================
@@ -424,6 +424,74 @@ class LifetimeSafetySemaHelperImpl : public
LifetimeSafetySemaHelper {
}
private:
+ struct LifetimeBoundMacroCache {
+ bool IsBuilt = false;
+ SmallVector<const IdentifierInfo *> Candidates;
+ };
+
+ void buildLifetimeBoundMacroCache(LifetimeBoundMacroCache &Cache,
+ ArrayRef<TokenValue> Tokens) {
+ if (Cache.IsBuilt)
+ return;
+
+ const Preprocessor &PP = S.getPreprocessor();
+ // Collect macro names that were ever defined as a lifetimebound attribute.
+ for (const auto &M : PP.macros()) {
+ const IdentifierInfo *II = M.first;
+ const MacroDirective *MD = PP.getLocalMacroDirectiveHistory(II);
+ if (!MD)
+ continue;
+
+ // Include earlier matching definitions to handle redefinitions.
+ for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
+ Def = Def.getPreviousDefinition()) {
+ const MacroInfo *MI = Def.getMacroInfo();
+ if (MI->isObjectLike() && Tokens.size() == MI->getNumTokens() &&
+ std::equal(Tokens.begin(), Tokens.end(), MI->tokens_begin())) {
+ Cache.Candidates.push_back(II);
+ break;
+ }
+ }
+ }
+ Cache.IsBuilt = true;
+ }
+
+ StringRef getLastCachedMacroWithSpelling(SourceLocation Loc,
+ llvm::ArrayRef<TokenValue> Tokens,
+ LifetimeBoundMacroCache &Cache) {
+ if (Loc.isInvalid())
+ return {};
+
+ buildLifetimeBoundMacroCache(Cache, Tokens);
+
+ const Preprocessor &PP = S.getPreprocessor();
+ const SourceManager &SM = S.getSourceManager();
+ SourceLocation BestLocation;
+ StringRef BestSpelling;
+ for (const IdentifierInfo *II : Cache.Candidates) {
+ const MacroDirective *MD = PP.getLocalMacroDirectiveHistory(II);
+ const MacroDirective::DefInfo Def = MD->findDirectiveAtLoc(Loc, SM);
+ if (!Def || !Def.getMacroInfo())
+ continue;
+
+ // Ensure the macro definition active at Loc still has this spelling.
+ const MacroInfo *MI = Def.getMacroInfo();
+ if (!MI->isObjectLike() || Tokens.size() != MI->getNumTokens() ||
+ !std::equal(Tokens.begin(), Tokens.end(), MI->tokens_begin()))
+ continue;
+
+ // Choose the matching macro defined latest before Loc.
----------------
zeyi2 wrote:
`findDirectiveAtLoc(Loc, SM)` should guarantee this. Its implementation only
returns a definition whose location is invalid, otherwise it keeps walking the
definition chain. The implementation here basically mirrors what
`Preprocessor::getLastMacroWithSpelling` does today. Please see:
https://github.com/llvm/llvm-project/blob/1e3018523042d1b610b6676cf8d056315f6e3bd7/clang/lib/Lex/Preprocessor.cpp#L393-L417
> Should we have an assertion about this?
Added now, thanks for reviewing.
https://github.com/llvm/llvm-project/pull/205250
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits