Skip to content

Commit 7754bc9

Browse files
committed
feat: Add PP_INTERNAL_VARIABLE to track header dependencies
Signed-off-by: Roberto Raggi <[email protected]>
1 parent 8e4dce0 commit 7754bc9

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

packages/cxx-frontend/src/TokenKind.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export enum TokenKind {
3232
UTF32_STRING_LITERAL,
3333
UTF8_STRING_LITERAL,
3434
WIDE_STRING_LITERAL,
35+
PP_INTERNAL_VARIABLE,
3536
AMP_AMP,
3637
AMP_EQUAL,
3738
AMP,

packages/cxx-gen-ast/src/tokens.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const BASE_TOKENS: string[] = [
3232
"UTF32_STRING_LITERAL",
3333
"UTF8_STRING_LITERAL",
3434
"WIDE_STRING_LITERAL",
35+
"PP_INTERNAL_VARIABLE",
3536
];
3637

3738
export const OPERATORS: Array<[kind: string, spelling: string]> = [

src/parser/cxx/preprocessor.cc

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

23452367
auto 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;

src/parser/cxx/token_fwd.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ class Token;
4242
V(UTF16_STRING_LITERAL, "<utf16_string_literal>") \
4343
V(UTF32_STRING_LITERAL, "<utf32_string_literal>") \
4444
V(UTF8_STRING_LITERAL, "<utf8_string_literal>") \
45-
V(WIDE_STRING_LITERAL, "<wide_string_literal>")
45+
V(WIDE_STRING_LITERAL, "<wide_string_literal>") \
46+
V(PP_INTERNAL_VARIABLE, "<PP_INTERNAL_VARIABLE>")
4647

4748
#define FOR_EACH_OPERATOR(V) \
4849
V(AMP_AMP, "&&") \

0 commit comments

Comments
 (0)