[clang] 223bdef - [BoundsSafety] unify ParseLexedAttribute (#186033)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 22 12:49:52 PDT 2026
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());
}
More information about the cfe-commits
mailing list