[clang] [BoundsSafety] Unify ParseLexedAttributeTokens (PR #206689)
Mohammed Ashraf via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 19 09:32:00 PDT 2026
https://github.com/Holo-xy updated https://github.com/llvm/llvm-project/pull/206689
>From 136d2f7592ac505881d9f540efd8610a9c7c75ec Mon Sep 17 00:00:00 2001
From: Mohammed Ashraf <mohammedashraf4599 at gmail.com>
Date: Tue, 30 Jun 2026 04:41:29 +0000
Subject: [PATCH 1/2] unify parse lexed attribute tokens
---
clang/include/clang/Parse/Parser.h | 4 +--
clang/lib/Parse/ParseCXXInlineMethods.cpp | 39 ++++-------------------
clang/lib/Parse/ParseDecl.cpp | 26 ++++++++-------
3 files changed, 22 insertions(+), 47 deletions(-)
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index f0e06473bf615..d07f4467a17a3 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1524,9 +1524,9 @@ class Parser : public CodeCompletionHandler {
ParsedAttributes &OutAttrs);
/// Parse cached tokens for a late-parsed attribute and return the parsed
- /// attributes. Shared implementation used by both ParseLexedCAttribute and
+ /// attributes. Shared implementation used by both ParseLexedAttribute and
/// ParseLexedTypeAttribute.
- ParsedAttributes ParseLexedCAttributeTokens(LateParsedAttribute &LA);
+ ParsedAttributes ParseLexedAttributeTokens(LateParsedAttribute &LPA);
/// Helper function to move LateParsedTypeAttribute pointers from one list
/// to another. Filters type attributes from \p From and appends them to \p
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index d13f73641218b..5011f5a76cb53 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -741,22 +741,6 @@ void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
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(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.
- LPA.Toks.push_back(Tok);
- PP.EnterTokenStream(LPA.Toks, true, /*IsReinject=*/true);
- // Consume the previously pushed token.
- ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
-
ParsedAttributes Attrs(AttrFactory);
if (LPA.Decls.size() > 0) {
@@ -783,20 +767,17 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LPA, bool EnterScope,
Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
}
- ParseGNUAttributeArgs(&LPA.AttrName, LPA.AttrNameLoc, Attrs,
- /*EndLoc=*/nullptr, /*ScopeName=*/nullptr,
- SourceLocation(), ParsedAttr::Form::GNU(),
- /*D=*/nullptr);
+ ParsedAttributes Parsed = ParseLexedAttributeTokens(LPA);
+ Attrs.takeAllAppendingFrom(Parsed);
if (HasFuncScope)
Actions.ActOnExitFunctionContext();
} else if (OutAttrs) {
- ParseGNUAttributeArgs(&LPA.AttrName, LPA.AttrNameLoc, Attrs,
- /*EndLoc=*/nullptr, /*ScopeName=*/nullptr,
- SourceLocation(), ParsedAttr::Form::GNU(),
- /*D=*/nullptr);
+ ParsedAttributes Parsed = ParseLexedAttributeTokens(LPA);
+ Attrs.takeAllAppendingFrom(Parsed);
} else {
- Diag(Tok, diag::warn_attribute_no_decl) << LPA.AttrName.getName();
+ Diag(LPA.AttrNameLoc, diag::warn_attribute_no_decl)
+ << LPA.AttrName.getName();
}
if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&
@@ -806,14 +787,6 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LPA, bool EnterScope,
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.
- while (Tok.isNot(tok::eof))
- ConsumeAnyToken();
-
- if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
- ConsumeAnyToken();
-
if (OutAttrs)
OutAttrs->takeAllAppendingFrom(Attrs);
}
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 3f41e7c5c6f0d..015c1125c0e48 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4847,33 +4847,32 @@ void Parser::ParseStructDeclaration(
}
}
-ParsedAttributes Parser::ParseLexedCAttributeTokens(LateParsedAttribute &LA) {
+ParsedAttributes Parser::ParseLexedAttributeTokens(LateParsedAttribute &LPA) {
// 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, /*DisableMacroExpansion=*/true,
+ LPA.Toks.push_back(Tok);
+ PP.EnterTokenStream(LPA.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);
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);
+ ParseGNUAttributeArgs(&LPA.AttrName, LPA.AttrNameLoc, Attrs,
+ /*EndLoc=*/nullptr, /*ScopeName=*/nullptr,
+ SourceLocation(), ParsedAttr::Form::GNU(),
+ /*D=*/nullptr);
// 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.
@@ -4889,7 +4888,10 @@ ParsedAttributes Parser::ParseLexedCAttributeTokens(LateParsedAttribute &LA) {
void Parser::ParseLexedTypeAttribute(LateParsedTypeAttribute &LA,
ParsedAttributes &OutAttrs) {
- ParsedAttributes Attrs = ParseLexedCAttributeTokens(LA);
+ assert(LA.Decls.size() <= 1 &&
+ "late field attribute expects to have at most one declaration.");
+
+ ParsedAttributes Attrs = ParseLexedAttributeTokens(LA);
OutAttrs.takeAllAppendingFrom(Attrs);
}
>From 890a72bccaf0d705aa358192accefdae5cc060d6 Mon Sep 17 00:00:00 2001
From: Mohammed Ashraf <mohammedashraf4599 at gmail.com>
Date: Sat, 18 Jul 2026 23:45:51 +0000
Subject: [PATCH 2/2] remove OutAttrs path
---
clang/lib/Parse/ParseCXXInlineMethods.cpp | 3 ---
1 file changed, 3 deletions(-)
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 5011f5a76cb53..d3d63e5a5c029 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -772,9 +772,6 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LPA, bool EnterScope,
if (HasFuncScope)
Actions.ActOnExitFunctionContext();
- } else if (OutAttrs) {
- ParsedAttributes Parsed = ParseLexedAttributeTokens(LPA);
- Attrs.takeAllAppendingFrom(Parsed);
} else {
Diag(LPA.AttrNameLoc, diag::warn_attribute_no_decl)
<< LPA.AttrName.getName();
More information about the cfe-commits
mailing list