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
