Skip to content

Commit fb66fca

Browse files
committed
ast-exporter: In VisitExpr, handle when Begin and End start off in different macros
1 parent bd3a1a7 commit fb66fca

1 file changed

Lines changed: 56 additions & 18 deletions

File tree

c2rust-ast-exporter/src/AstExporter.cpp

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,9 +1411,7 @@ class TranslateASTVisitor final
14111411
auto Begin = Range.getBegin();
14121412
auto End = Range.getEnd();
14131413

1414-
// Check that we are only expanding a single macro call.
1415-
if (!Begin.isMacroID() || !End.isMacroID() ||
1416-
Mgr.getImmediateMacroCallerLoc(Begin) != Mgr.getImmediateMacroCallerLoc(End)) {
1414+
if (!Begin.isMacroID() || !End.isMacroID()) {
14171415
return true;
14181416
}
14191417

@@ -1436,21 +1434,9 @@ class TranslateASTVisitor final
14361434
return true;
14371435
}
14381436

1439-
auto ReplacementBegin = mac->getReplacementToken(0).getLocation();
1440-
auto ReplacementEnd = mac->getDefinitionEndLoc();
1441-
// Verify that this expansion covers the entire macro replacement
1442-
// definition, i.e. E is not a subexpression of the macro
1443-
// replacement.
1444-
if (Mgr.getSpellingLoc(Range.getBegin()) != ReplacementBegin ||
1445-
Mgr.getSpellingLoc(Range.getEnd()) != ReplacementEnd) {
1446-
return true;
1447-
}
1448-
14491437
if (VisitMacro(name, ExpansionRange.getBegin(), mac, E)) {
14501438
curMacroExpansionStack.push_back(mac);
14511439
}
1452-
1453-
Range = ExpansionRange.getAsRange();
14541440
}
14551441

14561442
return true;
@@ -1460,20 +1446,72 @@ class TranslateASTVisitor final
14601446
auto &Mgr = Context->getSourceManager();
14611447
auto Begin = Range.getBegin();
14621448
auto End = Range.getEnd();
1463-
1464-
// Holds the stack of ranges of macro expansions.
1465-
// The last element is the top-level macro call.
14661449
std::vector<CharSourceRange> ExpansionStack;
14671450

14681451
do {
1452+
if (!isAtStartOfImmediateMacroExpansion(Begin)) {
1453+
break;
1454+
}
1455+
14691456
auto ExpansionRange = Mgr.getImmediateExpansionRange(Begin);
14701457
ExpansionStack.push_back(ExpansionRange);
14711458
Begin = ExpansionRange.getBegin();
14721459
} while (Begin.isMacroID());
14731460

1461+
// Find the point at which `Begin` and `End` converge on the same expansion range.
1462+
// This is where the expression in `Range` first corresponds to a single macro call.
1463+
auto ConvergencePoint = ExpansionStack.end();
1464+
1465+
do {
1466+
if (!isAtEndOfImmediateMacroExpansion(End)) {
1467+
break;
1468+
}
1469+
1470+
auto ExpansionRange = Mgr.getImmediateExpansionRange(End);
1471+
ConvergencePoint = std::find_if(
1472+
ExpansionStack.begin(),
1473+
ExpansionStack.end(),
1474+
[ExpansionRange](auto &R) {
1475+
return R.getAsRange() == ExpansionRange.getAsRange() &&
1476+
R.isTokenRange() == ExpansionRange.isTokenRange();
1477+
}
1478+
);
1479+
End = ExpansionRange.getEnd();
1480+
} while (End.isMacroID() && ConvergencePoint == ExpansionStack.end());
1481+
1482+
// Remove all elements before the convergence point.
1483+
ExpansionStack.erase(ExpansionStack.begin(), ConvergencePoint);
1484+
1485+
// Ensure the remaining ranges still correspond to the input `Range`.
1486+
auto EraseAfter = std::find_if(
1487+
ExpansionStack.begin(),
1488+
ExpansionStack.end(),
1489+
[this, &Mgr](auto &R) {
1490+
auto End = R.getEnd();
1491+
return End.isMacroID() && !isAtEndOfImmediateMacroExpansion(End);
1492+
}
1493+
);
1494+
auto EraseFrom = EraseAfter + 1;
1495+
1496+
if (EraseFrom < ExpansionStack.end()) {
1497+
ExpansionStack.erase(EraseFrom, ExpansionStack.end());
1498+
}
1499+
14741500
return ExpansionStack;
14751501
}
14761502

1503+
bool isAtStartOfImmediateMacroExpansion(SourceLocation loc) const {
1504+
auto &Mgr = Context->getSourceManager();
1505+
return Mgr.isAtStartOfImmediateMacroExpansion(loc);
1506+
}
1507+
1508+
bool isAtEndOfImmediateMacroExpansion(SourceLocation loc) const {
1509+
auto &Mgr = Context->getSourceManager();
1510+
auto spellingLoc = Mgr.getSpellingLoc(loc);
1511+
auto len = Lexer::MeasureTokenLength(spellingLoc, Mgr, Context->getLangOpts());
1512+
return Mgr.isAtEndOfImmediateMacroExpansion(loc.getLocWithOffset(len));
1513+
}
1514+
14771515
bool VisitVAArgExpr(VAArgExpr *E) {
14781516
std::vector<void *> childIds{E->getSubExpr()};
14791517
encode_entry(E, TagVAArgExpr, childIds);

0 commit comments

Comments
 (0)