https://github.com/zeyi2 updated 
https://github.com/llvm/llvm-project/pull/205250

>From 1ca4f441b6209697f1c7d8c97c1d9a12d03f129c Mon Sep 17 00:00:00 2001
From: Zeyi Xu <[email protected]>
Date: Tue, 23 Jun 2026 11:54:15 +0800
Subject: [PATCH 1/2] [LifetimeSafety] Cache lifetimebound macro lookup. NFC.

---
 clang/lib/Sema/SemaLifetimeSafety.h | 91 ++++++++++++++++++++++++++---
 1 file changed, 83 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Sema/SemaLifetimeSafety.h 
b/clang/lib/Sema/SemaLifetimeSafety.h
index 4bde272fb40a1..c2f7a56e166c4 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -442,21 +442,94 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
   }
 
 private:
+  struct LifetimeBoundMacroCache {
+    bool IsBuilt = false;
+    llvm::SmallVector<const IdentifierInfo *> Candidates;
+  };
+
+  void buildLifetimeBoundMacroCache(LifetimeBoundMacroCache &Cache,
+                                    llvm::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);
+      if (!MD)
+        continue;
+      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.
+      SourceLocation Location = Def.getLocation();
+      if (BestLocation.isInvalid() ||
+          (Location.isValid() &&
+           SM.isBeforeInTranslationUnit(BestLocation, Location))) {
+        BestLocation = Location;
+        BestSpelling = II->getName();
+      }
+    }
+    return BestSpelling;
+  }
+
   std::string getLifetimeBoundFixItText(SourceLocation Loc, bool LeadingSpace,
                                         bool AllowGNUAttrMacro = true) {
     StringRef Spelling = S.getLangOpts().LifetimeSafetyLifetimeBoundMacro;
     if (Spelling.empty() && Loc.isValid()) {
       const Preprocessor &PP = S.getPreprocessor();
-      Spelling = PP.getLastMacroWithSpelling(
-          Loc, {tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
-                tok::coloncolon, PP.getIdentifierInfo("lifetimebound"),
-                tok::r_square, tok::r_square});
+      Spelling = getLastCachedMacroWithSpelling(
+          Loc,
+          {tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
+           tok::coloncolon, PP.getIdentifierInfo("lifetimebound"),
+           tok::r_square, tok::r_square},
+          ClangLifetimeBoundMacroCache);
 
       if (Spelling.empty() && AllowGNUAttrMacro)
-        Spelling = PP.getLastMacroWithSpelling(
-            Loc, {tok::kw___attribute, tok::l_paren, tok::l_paren,
-                  PP.getIdentifierInfo("lifetimebound"), tok::r_paren,
-                  tok::r_paren});
+        Spelling = getLastCachedMacroWithSpelling(
+            Loc,
+            {tok::kw___attribute, tok::l_paren, tok::l_paren,
+             PP.getIdentifierInfo("lifetimebound"), tok::r_paren, 
tok::r_paren},
+            GNULifetimeBoundMacroCache);
     }
     const std::string Text =
         Spelling.empty() ? "[[clang::lifetimebound]]" : Spelling.str();
@@ -589,6 +662,8 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
     }
   }
 
+  LifetimeBoundMacroCache ClangLifetimeBoundMacroCache;
+  LifetimeBoundMacroCache GNULifetimeBoundMacroCache;
   Sema &S;
 };
 

>From 798dc68f9eba602bb6d4c0c1d83abaf7fd451dce Mon Sep 17 00:00:00 2001
From: Zeyi Xu <[email protected]>
Date: Tue, 23 Jun 2026 11:57:14 +0800
Subject: [PATCH 2/2] small style nit fixes

---
 clang/lib/Sema/SemaLifetimeSafety.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaLifetimeSafety.h 
b/clang/lib/Sema/SemaLifetimeSafety.h
index c2f7a56e166c4..b3f5a3b477a4d 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -444,11 +444,11 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
 private:
   struct LifetimeBoundMacroCache {
     bool IsBuilt = false;
-    llvm::SmallVector<const IdentifierInfo *> Candidates;
+    SmallVector<const IdentifierInfo *> Candidates;
   };
 
   void buildLifetimeBoundMacroCache(LifetimeBoundMacroCache &Cache,
-                                    llvm::ArrayRef<TokenValue> Tokens) {
+                                    ArrayRef<TokenValue> Tokens) {
     if (Cache.IsBuilt)
       return;
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to