https://github.com/Holo-xy updated https://github.com/llvm/llvm-project/pull/186033
>From 87956fca2ca33bab84ec4b171fad5f175ff34cb6 Mon Sep 17 00:00:00 2001 From: Mohammed Ashraf <[email protected]> Date: Thu, 12 Mar 2026 03:27:11 +0000 Subject: [PATCH 1/3] [BoundsSafety] merge ParseLexedAttribute and ParseLexedCAttribute functions --- clang/include/clang/Parse/Parser.h | 17 ++---- clang/lib/Parse/ParseCXXInlineMethods.cpp | 69 +++++++++++++++-------- clang/lib/Parse/ParseDecl.cpp | 64 +-------------------- 3 files changed, 51 insertions(+), 99 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 5ae02e2b4e8ad..2efc901ff49ad 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1337,7 +1337,8 @@ 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 @@ -1345,7 +1346,8 @@ class Parser : public CodeCompletionHandler { /// 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); + bool OnDefinition, + ParsedAttributes *OutAttrs = nullptr); /// ParseLexedMethodDeclarations - We finished parsing the member /// specification of a top (non-nested) C++ class. Now go over the @@ -1478,17 +1480,6 @@ class Parser : public CodeCompletionHandler { const char *&PrevSpec, unsigned &DiagID, bool &isInvalid); - void ParseLexedCAttributeList(LateParsedAttrList &LA, bool EnterScope, - 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, bool EnterScope, - ParsedAttributes *OutAttrs = nullptr); - void ParseLexedPragmas(ParsingClass &Class); void ParseLexedPragma(LateParsedPragma &LP); diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index bc18881e89110..aefcfce55508c 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -717,20 +717,22 @@ 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 &LA, 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; @@ -751,24 +753,45 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, if (LA.Decls.size() > 0) { Decl *D = LA.Decls[0]; - 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 (getLangOpts().CPlusPlus) { + NamedDecl *ND = dyn_cast<NamedDecl>(D); + RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); - if (LA.Decls.size() == 1) { - // If the Decl is templatized, add template parameters to scope. - ReenterTemplateScopeRAII InDeclScope(*this, D, EnterScope); + // Allow 'this' within late-parsed attributes. + Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(), + ND && ND->isCXXInstanceMember()); - // If the Decl is on a function, add function parameters to the scope. + 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); + } + + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, + nullptr, SourceLocation(), + ParsedAttr::Form::GNU(), nullptr); + + 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); + } + } else { bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); - if (HasFunScope) { - InDeclScope.Scopes.Enter(Scope::FnScope | Scope::DeclScope | - Scope::CompoundStmtScope); + ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope, HasFunScope); + if (HasFunScope) Actions.ActOnReenterFunctionContext(Actions.CurScope, D); - } ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, nullptr, SourceLocation(), ParsedAttr::Form::GNU(), @@ -776,13 +799,10 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, 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); } + } else if (OutAttrs) { + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, nullptr, + SourceLocation(), ParsedAttr::Form::GNU(), nullptr); } else { Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); } @@ -802,6 +822,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 72935f427b7f8..46c261aa04e3d 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4802,68 +4802,6 @@ void Parser::ParseStructDeclaration( } } -// TODO: All callers of this function should be moved to -// `Parser::ParseLexedAttributeList`. -void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs, bool EnterScope, - ParsedAttributes *OutAttrs) { - assert(LAs.parseSoon() && - "Attribute list should be marked for immediate parsing."); - for (auto *LA : LAs) { - ParseLexedCAttribute(*LA, EnterScope, OutAttrs); - delete LA; - } - LAs.clear(); -} - -void Parser::ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope, - 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); - - // 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, /*DisableMacroExpansion=*/true, - /*IsReinject=*/true); - // Drop the current token and bring the first cached one. It's the same token - // as when we entered this function. - ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); - - // TODO: Use `EnterScope` - (void)EnterScope; - - ParsedAttributes Attrs(AttrFactory); - - assert(LA.Decls.size() <= 1 && - "late field attribute expects to have at most one declaration."); - - // Dispatch based on the attribute and parse it - ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, nullptr, - SourceLocation(), ParsedAttr::Form::GNU(), nullptr); - - for (auto *D : LA.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. - while (Tok.isNot(tok::eof)) - ConsumeAnyToken(); - - // Consume the fake EOF token if it's there - if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()) - ConsumeAnyToken(); - - if (OutAttrs) { - OutAttrs->takeAllAppendingFrom(Attrs); - } -} - void Parser::ParseStructUnionBody(SourceLocation RecordLoc, DeclSpec::TST TagType, RecordDecl *TagDecl) { PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc, @@ -4990,7 +4928,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, MaybeParseGNUAttributes(attrs, &LateFieldAttrs); // Late parse field attributes if necessary. - ParseLexedCAttributeList(LateFieldAttrs, /*EnterScope=*/false); + ParseLexedAttributeList(LateFieldAttrs, nullptr, false, false); SmallVector<Decl *, 32> FieldDecls(TagDecl->fields()); >From 3a25befad4f99f4771f4426cc4b07b539863c921 Mon Sep 17 00:00:00 2001 From: Mohammed Ashraf <[email protected]> Date: Fri, 13 Mar 2026 04:50:44 +0000 Subject: [PATCH 2/3] simplify ParseLexedAttribute changes --- clang/lib/Parse/ParseCXXInlineMethods.cpp | 38 +++++++++-------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index aefcfce55508c..e297e284d2130 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -753,7 +753,8 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, bool EnterScope, if (LA.Decls.size() > 0) { Decl *D = LA.Decls[0]; - + bool HasFuncScope = + EnterScope && LA.Decls.size() == 1 && D->isFunctionOrFunctionTemplate(); if (getLangOpts().CPlusPlus) { NamedDecl *ND = dyn_cast<NamedDecl>(D); RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); @@ -762,42 +763,33 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, bool EnterScope, 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 templatized, add template parameters to the 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); - } + // 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(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, nullptr, SourceLocation(), ParsedAttr::Form::GNU(), nullptr); - if (HasFunScope) + if (HasFuncScope) 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); - } + } else { - bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); - ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope, HasFunScope); - if (HasFunScope) + ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope, HasFuncScope); + if (HasFuncScope) Actions.ActOnReenterFunctionContext(Actions.CurScope, D); ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, nullptr, SourceLocation(), ParsedAttr::Form::GNU(), nullptr); - if (HasFunScope) + if (HasFuncScope) Actions.ActOnExitFunctionContext(); } } else if (OutAttrs) { >From f13f18ad200dbdbe71e202d53f228092ea0e4861 Mon Sep 17 00:00:00 2001 From: Mohammed Ashraf <[email protected]> Date: Fri, 20 Mar 2026 03:40:10 +0000 Subject: [PATCH 3/3] fix format --- clang/lib/Parse/ParseCXXInlineMethods.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index e297e284d2130..898c4100f51a9 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -773,12 +773,12 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, bool EnterScope, Actions.ActOnReenterFunctionContext(Actions.CurScope, D); } - ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, - nullptr, SourceLocation(), - ParsedAttr::Form::GNU(), nullptr); + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, + nullptr, SourceLocation(), ParsedAttr::Form::GNU(), + nullptr); - if (HasFuncScope) - Actions.ActOnExitFunctionContext(); + if (HasFuncScope) + Actions.ActOnExitFunctionContext(); } else { ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope, HasFuncScope); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
