[clang] [LifetimeSafety] Cache lifetimebound macro lookup. NFC. (PR #205250)
Zeyi Xu via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 24 06:58:07 PDT 2026
================
@@ -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;
----------------
zeyi2 wrote:
The outer loop only iterates macro names, not individual definitions. So it would not visit the previous definitions of the same macro again.
The inner loop is needed because the cache is location-independent. A macro name should be collected as a candidate if any definition in its history had the lifetimebound spelling.
The break is only to avoid adding the same macro name multiple times once we know it is a candidate.
https://github.com/llvm/llvm-project/pull/205250
More information about the cfe-commits
mailing list