@@ -731,6 +731,15 @@ struct Preprocessor::Private {
731731  std::function<std::string(std::string)> readFile_;
732732  std::function<void (const  std::string &, int )> willIncludeHeader_;
733733  std::vector<Buffer> buffers_;
734+   struct  Dep  {
735+     std::string_view local;
736+     Include include;
737+     bool  isIncludeNext = false ;
738+     int  value = 0 ;
739+   };
740+   std::vector<Dep> dependencies_;
741+   int  localCount_ = 0 ;
742+ 
734743  int  counter_ = 0 ;
735744  int  includeDepth_ = 0 ;
736745  bool  omitLineMarkers_ = false ;
@@ -1379,6 +1388,15 @@ void Preprocessor::Private::initialize() {
13791388    return  cons (tk, ts);
13801389  };
13811390
1391+   auto  replaceWithLocal = [this ](const  Tok *token, std::string_view local,
1392+                                  TokList *ts) {
1393+     auto  tk = gen (TokenKind::T_PP_INTERNAL_VARIABLE, local);
1394+     tk->sourceFile  = token->sourceFile ;
1395+     tk->space  = token->space ;
1396+     tk->bol  = token->bol ;
1397+     return  cons (tk, ts);
1398+   };
1399+ 
13821400  adddBuiltinFunctionMacro (
13831401      " __has_feature"  ,
13841402      [this , replaceWithBoolLiteral](
@@ -1435,7 +1453,7 @@ void Preprocessor::Private::initialize() {
14351453        return  replaceWithBoolLiteral (macroId, enabled, ts);
14361454      });
14371455
1438-   auto  hasInclude = [this , replaceWithBoolLiteral](
1456+   auto  hasInclude = [this , replaceWithLocal,  replaceWithBoolLiteral](
14391457                        const  MacroExpansionContext &context) -> TokList * {
14401458    auto  ts = context.ts ;
14411459
@@ -1478,9 +1496,11 @@ void Preprocessor::Private::initialize() {
14781496      include = SystemInclude (std::move (fn));
14791497    }
14801498
1481-     const  auto  value = resolve (include, isIncludeNext);
1499+     std::string_view local = string (std::format (" @{}"  , localCount_++));
1500+ 
1501+     dependencies_.push_back ({local, include, isIncludeNext});
14821502
1483-     return  replaceWithBoolLiteral (macroName, value. has_value () , rest);
1503+     return  replaceWithLocal (macroName, local , rest);
14841504  };
14851505
14861506  adddBuiltinFunctionMacro (" __has_include"  , hasInclude);
@@ -1710,6 +1730,8 @@ auto Preprocessor::Private::parseDirective(SourceFile *source, TokList *start)
17101730
17111731  if  (!lookat (directive, TokenKind::T_IDENTIFIER)) return  std::nullopt ;
17121732
1733+   dependencies_.clear ();
1734+ 
17131735  const  auto  directiveKind = classifyDirective (directive->tok ->text .data (),
17141736                                               directive->tok ->text .length ());
17151737
@@ -2344,8 +2366,14 @@ auto Preprocessor::Private::copyLine(TokList *ts, bool inMacroBody)
23442366
23452367auto  Preprocessor::Private::constantExpression (TokList *ts) -> long {
23462368  auto  line = copyLine (ts);
2369+   dependencies_.clear ();
23472370  auto  it = expandTokens (TokIterator{line}, TokIterator{},
23482371                         /* inConditionalExpression*/   true );
2372+   //  evaluate the deps
2373+   for  (auto  &d : dependencies_) {
2374+     auto  resolved = resolve (d.include , d.isIncludeNext );
2375+     d.value  = resolved.has_value ();
2376+   }
23492377  auto  e = it.toTokList ();
23502378  return  conditionalExpression (e);
23512379}
@@ -2527,6 +2555,13 @@ auto Preprocessor::Private::primaryExpression(TokList *&ts) -> long {
25272555    auto  result = conditionalExpression (ts);
25282556    expect (ts, TokenKind::T_RPAREN);
25292557    return  result;
2558+   } else  if  (tk->is (TokenKind::T_PP_INTERNAL_VARIABLE)) {
2559+     for  (const  auto  &dep : dependencies_) {
2560+       if  (dep.local  == tk->text ) {
2561+         ts = ts->next ;
2562+         return  dep.value ;
2563+       }
2564+     }
25302565  }
25312566
25322567  ts = ts->next ;
0 commit comments