Author: Mohammed Ashraf
Date: 2026-06-22T12:49:48-07:00
New Revision: 223bdef73f761f22353744eeea46663ed0941926

URL: 
https://github.com/llvm/llvm-project/commit/223bdef73f761f22353744eeea46663ed0941926
DIFF: 
https://github.com/llvm/llvm-project/commit/223bdef73f761f22353744eeea46663ed0941926.diff

LOG: [BoundsSafety] unify ParseLexedAttribute (#186033)

Resolves #93263

Added: 
    

Modified: 
    clang/include/clang/Parse/Parser.h
    clang/lib/Parse/ParseCXXInlineMethods.cpp
    clang/lib/Parse/ParseDecl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 5e7af97feeb6c..f0e06473bf615 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1377,15 +1377,17 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse all attributes in LAs, and attach them to Decl D.
   void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
-                               bool EnterScope, bool OnDefinition);
+                               bool EnterScope, bool OnDefinition,
+                               ParsedAttributes *OutAttrs = nullptr);
 
   /// Finish parsing an attribute for which parsing was delayed.
   /// This will be called at the end of parsing a class declaration
   /// for each LateParsedAttribute. We consume the saved tokens and
   /// create an attribute with the arguments filled in. We add this
   /// to the Attribute list for the decl.
-  void ParseLexedAttribute(LateParsedAttribute &LA, bool EnterScope,
-                           bool OnDefinition);
+  void ParseLexedAttribute(LateParsedAttribute &LPA, bool EnterScope,
+                           bool OnDefinition,
+                           ParsedAttributes *OutAttrs = nullptr);
 
   /// ParseLexedMethodDeclarations - We finished parsing the member
   /// specification of a top (non-nested) C++ class. Now go over the
@@ -1518,17 +1520,6 @@ class Parser : public CodeCompletionHandler {
                                 const char *&PrevSpec, unsigned &DiagID,
                                 bool &isInvalid);
 
-  void ParseLexedCAttributeList(LateParsedAttrList &LA,
-                                ParsedAttributes *OutAttrs = nullptr);
-
-  /// Finish parsing an attribute for which parsing was delayed.
-  /// This will be called at the end of parsing a class declaration
-  /// for each LateParsedAttribute. We consume the saved tokens and
-  /// create an attribute with the arguments filled in. We add this
-  /// to the Attribute list for the decl.
-  void ParseLexedCAttribute(LateParsedAttribute &LA,
-                            ParsedAttributes *OutAttrs = nullptr);
-
   void ParseLexedTypeAttribute(LateParsedTypeAttribute &LA,
                                ParsedAttributes &OutAttrs);
 

diff  --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp 
b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 6189c854e5fbf..d13f73641218b 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -725,83 +725,86 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) {
 }
 
 void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
-                                     bool EnterScope, bool OnDefinition) {
+                                     bool EnterScope, bool OnDefinition,
+                                     ParsedAttributes *OutAttrs) {
   assert(LAs.parseSoon() &&
          "Attribute list should be marked for immediate parsing.");
   for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
     if (D)
       LAs[i]->addDecl(D);
-    ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
+    ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition, OutAttrs);
     delete LAs[i];
   }
   LAs.clear();
 }
 
-void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
-                                 bool EnterScope, bool OnDefinition) {
+void Parser::ParseLexedAttribute(LateParsedAttribute &LPA, bool EnterScope,
+                                 bool OnDefinition,
+                                 ParsedAttributes *OutAttrs) {
   // Create a fake EOF so that attribute parsing won't go off the end of the
   // attribute.
   Token AttrEnd;
   AttrEnd.startToken();
   AttrEnd.setKind(tok::eof);
   AttrEnd.setLocation(Tok.getLocation());
-  AttrEnd.setEofData(LA.Toks.data());
-  LA.Toks.push_back(AttrEnd);
+  AttrEnd.setEofData(LPA.Toks.data());
+  LPA.Toks.push_back(AttrEnd);
 
   // Append the current token at the end of the new token stream so that it
   // doesn't get lost.
-  LA.Toks.push_back(Tok);
-  PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true);
+  LPA.Toks.push_back(Tok);
+  PP.EnterTokenStream(LPA.Toks, true, /*IsReinject=*/true);
   // Consume the previously pushed token.
   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
 
   ParsedAttributes Attrs(AttrFactory);
 
-  if (LA.Decls.size() > 0) {
-    Decl *D = LA.Decls[0];
-    NamedDecl *ND  = dyn_cast<NamedDecl>(D);
+  if (LPA.Decls.size() > 0) {
+    Decl *D = LPA.Decls[0];
+    bool HasFuncScope = EnterScope && LPA.Decls.size() == 1 &&
+                        D->isFunctionOrFunctionTemplate();
+    bool IsCPlusPlus = getLangOpts().CPlusPlus;
+
+    NamedDecl *ND = dyn_cast<NamedDecl>(D);
     RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
 
     // Allow 'this' within late-parsed attributes.
     Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(),
-                                     ND && ND->isCXXInstanceMember());
-
-    if (LA.Decls.size() == 1) {
-      // If the Decl is templatized, add template parameters to scope.
-      ReenterTemplateScopeRAII InDeclScope(*this, D, EnterScope);
-
-      // If the Decl is on a function, add function parameters to the scope.
-      bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();
-      if (HasFunScope) {
-        InDeclScope.Scopes.Enter(Scope::FnScope | Scope::DeclScope |
-                                 Scope::CompoundStmtScope);
-        Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
-      }
+                                     IsCPlusPlus && ND &&
+                                         ND->isCXXInstanceMember());
 
-      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,
-                            nullptr, SourceLocation(), ParsedAttr::Form::GNU(),
-                            nullptr);
+    // If the Decl is templatized, add template parameters to the scope.
+    ReenterTemplateScopeRAII InDeclScope(*this, D, IsCPlusPlus && EnterScope);
 
-      if (HasFunScope)
-        Actions.ActOnExitFunctionContext();
-    } else {
-      // If there are multiple decls, then the decl cannot be within the
-      // function scope.
-      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,
-                            nullptr, SourceLocation(), ParsedAttr::Form::GNU(),
-                            nullptr);
+    // If the Decl is on a function, add function parameters to the scope.
+    if (HasFuncScope) {
+      InDeclScope.Scopes.Enter(Scope::FnScope | Scope::DeclScope |
+                               Scope::CompoundStmtScope);
+      Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
     }
+
+    ParseGNUAttributeArgs(&LPA.AttrName, LPA.AttrNameLoc, Attrs,
+                          /*EndLoc=*/nullptr, /*ScopeName=*/nullptr,
+                          SourceLocation(), ParsedAttr::Form::GNU(),
+                          /*D=*/nullptr);
+
+    if (HasFuncScope)
+      Actions.ActOnExitFunctionContext();
+  } else if (OutAttrs) {
+    ParseGNUAttributeArgs(&LPA.AttrName, LPA.AttrNameLoc, Attrs,
+                          /*EndLoc=*/nullptr, /*ScopeName=*/nullptr,
+                          SourceLocation(), ParsedAttr::Form::GNU(),
+                          /*D=*/nullptr);
   } else {
-    Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
+    Diag(Tok, diag::warn_attribute_no_decl) << LPA.AttrName.getName();
   }
 
   if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&
       Attrs.begin()->isKnownToGCC())
-    Diag(Tok, diag::warn_attribute_on_function_definition)
-      << &LA.AttrName;
+    Diag(Tok, diag::warn_attribute_on_function_definition) << &LPA.AttrName;
 
-  for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i)
-    Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
+  for (auto *D : LPA.Decls)
+    Actions.ActOnFinishDelayedAttribute(getCurScope(), D, Attrs);
 
   // Due to a parsing error, we either went over the cached tokens or
   // there are still cached tokens left, so we skip the leftover tokens.
@@ -810,6 +813,9 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
 
   if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
     ConsumeAnyToken();
+
+  if (OutAttrs)
+    OutAttrs->takeAllAppendingFrom(Attrs);
 }
 
 void Parser::ParseLexedPragmas(ParsingClass &Class) {

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 405dddf7991b4..3f41e7c5c6f0d 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4847,19 +4847,6 @@ void Parser::ParseStructDeclaration(
   }
 }
 
-// TODO: All callers of this function should be moved to
-// `Parser::ParseLexedAttributeList`.
-void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
-                                      ParsedAttributes *OutAttrs) {
-  assert(LAs.parseSoon() &&
-         "Attribute list should be marked for immediate parsing.");
-  for (auto *LA : LAs) {
-    ParseLexedCAttribute(*LA, OutAttrs);
-    delete LA;
-  }
-  LAs.clear();
-}
-
 ParsedAttributes Parser::ParseLexedCAttributeTokens(LateParsedAttribute &LA) {
   // Create a fake EOF so that attribute parsing won't go off the end of the
   // attribute.
@@ -4900,17 +4887,6 @@ ParsedAttributes 
Parser::ParseLexedCAttributeTokens(LateParsedAttribute &LA) {
   return Attrs;
 }
 
-void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
-                                  ParsedAttributes *OutAttrs) {
-  ParsedAttributes Attrs = ParseLexedCAttributeTokens(LA);
-
-  for (Decl *D : LA.Decls)
-    Actions.ActOnFinishDelayedAttribute(getCurScope(), D, Attrs);
-
-  if (OutAttrs)
-    OutAttrs->takeAllAppendingFrom(Attrs);
-}
-
 void Parser::ParseLexedTypeAttribute(LateParsedTypeAttribute &LA,
                                      ParsedAttributes &OutAttrs) {
   ParsedAttributes Attrs = ParseLexedCAttributeTokens(LA);
@@ -5066,7 +5042,8 @@ void Parser::ParseStructUnionBody(SourceLocation 
RecordLoc,
                       T.getOpenLocation(), T.getCloseLocation(), attrs);
 
   // Late parse field attributes if necessary.
-  ParseLexedCAttributeList(LateFieldAttrs);
+  ParseLexedAttributeList(LateFieldAttrs, /*D=*/nullptr, /*EnterScope=*/false,
+                          /*OnDefinition=*/false);
   StructScope.Exit();
   Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange());
 }


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

Reply via email to