https://github.com/zebullax updated https://github.com/llvm/llvm-project/pull/166287
>From e2f13c0d8c6e5c6bed1fe445d16eed609e5f03e2 Mon Sep 17 00:00:00 2001 From: acassagnes <[email protected]> Date: Sat, 1 Nov 2025 11:11:25 +0900 Subject: [PATCH 1/7] Add annotation to attribute tablegen Recognize annotation starting token in attr parsing Signed-off-by: acassagnes <[email protected]> --- clang/include/clang/Basic/Attr.td | 45 +++++++++++++++++++ .../clang/Basic/DiagnosticParseKinds.td | 5 +++ clang/lib/Parse/ParseDeclCXX.cpp | 11 +++++ clang/utils/TableGen/ClangAttrEmitter.cpp | 8 ++-- 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 749f531ec9ab1..06b9b1ff3e295 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -744,6 +744,9 @@ class Attr { // Note: Any additional data members will leak and should be constructed // externally on the ASTContext. code AdditionalMembers = [{}]; + // Any additional text that should be included verbatim after instantiating + // an attribute on a template. + code PostInstantiationStmts =[{}]; // Any documentation that should be associated with the attribute. Since an // attribute may be documented under multiple categories, more than one // Documentation entry may be listed. @@ -930,6 +933,48 @@ def AlwaysInline : DeclOrStmtAttr { let Documentation = [AlwaysInlineDocs]; } +def CXX26Annotation : InheritableParamAttr { + let Spellings = []; + let Args = [ExprArgument<"Arg">]; + let AdditionalMembers = [{ +private: + APValue Value; + SourceLocation EqLoc; + +public: + static CXX26AnnotationAttr *Create(ASTContext &Ctx, \ + const AttributeCommonInfo &CommonInfo) { + return CXX26AnnotationAttr::Create(Ctx, nullptr, CommonInfo); + } + static CXX26AnnotationAttr *CreateImplicit( \ + ASTContext &Ctx, \ + const AttributeCommonInfo &CommonInfo) { + return CXX26AnnotationAttr::CreateImplicit(Ctx, nullptr, CommonInfo); + } + + APValue getValue() const { return Value; } + void setValue(APValue V) { Value = V; } + + SourceLocation getEqLoc() const { return EqLoc; } + void setEqLoc(SourceLocation Loc) { EqLoc = Loc; } + }]; + + let PostInstantiationStmts = [{ + Expr::EvalResult V; + if (!Result->getArg()->isValueDependent() && + !Result->getArg()->EvaluateAsRValue(V, C, true)) + llvm_unreachable("failed to evaluate annotation expression"); + + Result->setValue(V.Val); + Result->setEqLoc(A->getEqLoc()); + }]; + + let HasCustomParsing = 1; + let TemplateDependent = 1; + let MeaningfulToClassTemplateDefinition = 1; + let Documentation = [InternalOnly]; +} + def Artificial : InheritableAttr { let Spellings = [GCC<"artificial">]; let Subjects = SubjectList<[InlineFunction]>; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index e5e071f43fa75..c7e59ad21b3bb 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1848,6 +1848,11 @@ def err_placeholder_expected_auto_or_decltype_auto : Error< "expected 'auto' or 'decltype(auto)' after concept name">; } +let CategoryName = "Reflection Issue" in { +def err_annotation_with_using : Error< + "annotations are not permitted following an attribute-using-prefix">; +} + def warn_max_tokens : Warning< "the number of preprocessor source tokens (%0) exceeds this token limit (%1)">, InGroup<MaxTokens>, DefaultIgnore; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index b96968d4592f5..4ca0568b37b12 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -17,6 +17,7 @@ #include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/DiagnosticParse.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TokenKinds.h" #include "clang/Lex/LiteralSupport.h" @@ -4700,6 +4701,16 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, SourceLocation ScopeLoc, AttrLoc; IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr; + // '=' token marks the beginning of an annotation + if (getLangOpts().CPlusPlus26 && Tok.is(tok::equal)) { + if (CommonScopeName) { + Diag(Tok.getLocation(), diag::err_annotation_with_using); + SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); + continue; + } + continue; + } + AttrName = TryParseCXX11AttributeIdentifier( AttrLoc, SemaCodeCompletion::AttributeCompletion::Attribute, CommonScopeName); diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 183952af590e1..7bc4719289441 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -4091,13 +4091,15 @@ EmitClangAttrTemplateInstantiateHelper(ArrayRef<const Record *> Attrs, for (auto const &ai : Args) ai->writeTemplateInstantiation(OS); - OS << " return new (C) " << R.getName() << "Attr(C, *A"; + OS << " auto* Result = new (C) " << R.getName() << "Attr(C, *A"; for (auto const &ai : Args) { OS << ", "; ai->writeTemplateInstantiationArgs(OS); } - OS << ");\n" - << " }\n"; + OS << ");\n"; + OS << R.getValueAsString("PostInstantiationStmts"); + OS << "return Result;\n"; + OS << " }\n"; } OS << " } // end switch\n" << " llvm_unreachable(\"Unknown attribute!\");\n" >From 76337f8ae60947346fe4fe2f2569f5affe8f0722 Mon Sep 17 00:00:00 2001 From: acassagnes <[email protected]> Date: Sun, 2 Nov 2025 10:52:44 +0900 Subject: [PATCH 2/7] Build logic around parsing of annotation inside list Signed-off-by: acassagnes <[email protected]> --- .../clang/Basic/DiagnosticParseKinds.td | 4 ++ clang/include/clang/Parse/Parser.h | 4 ++ clang/lib/Parse/ParseDeclCXX.cpp | 40 ++++++++++++++----- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index c7e59ad21b3bb..e87b605632d19 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -795,6 +795,10 @@ def err_cxx11_attribute_forbids_ellipsis : Error< def warn_cxx14_compat_using_attribute_ns : Warning< "default scope specifier for attributes is incompatible with C++ standards " "before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore; +def warn_cxx26_compat_annotation : Warning< + "annotation is a C++26 extension">, InGroup<CXXPre26Compat>, DefaultIgnore; +def err_mixed_attributes_and_annotations : Error< + "attribute specifier cannot contain both attributes and annotations">; def ext_using_attribute_ns : ExtWarn< "default scope specifier for attributes is a C++17 extension">, InGroup<CXX17>; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index dad8efd0f017f..dd1e774316ca0 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3046,6 +3046,10 @@ class Parser : public CodeCompletionHandler { SourceLocation ScopeLoc, CachedTokens &OpenMPTokens); + /// TODO doc + void ParseAnnotationSpecifier(ParsedAttributes &Attrs, + SourceLocation *EndLoc); + /// Parse the argument to C++23's [[assume()]] attribute. Returns true on /// error. bool diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 4ca0568b37b12..4a82a365bb0b8 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -4443,6 +4443,12 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, } } +void Parser::ParseAnnotationSpecifier(ParsedAttributes &Attrs, + SourceLocation *EndLoc) +{ + // TODO +} + bool Parser::ParseCXXAssumeAttributeArg( ParsedAttributes &Attrs, IdentifierInfo *AttrName, SourceLocation AttrNameLoc, IdentifierInfo *ScopeName, @@ -4682,16 +4688,21 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, Diag(Tok.getLocation(), diag::err_expected) << tok::colon; } - bool AttrParsed = false; + bool hasAttribute = false; + bool hasAnnotation = false; while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof)) { - if (AttrParsed) { - // If we parsed an attribute, a comma is required before parsing any - // additional attributes. + // If we parsed an attribute/annotation, a comma is required before parsing + // any additional ones. + if (hasAttribute || hasAnnotation) { if (ExpectAndConsume(tok::comma)) { SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch); continue; } - AttrParsed = false; + if (hasAttribute && hasAnnotation) { + Diag(Tok.getLocation(), diag::err_mixed_attributes_and_annotations); + SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); + continue; + } } // Eat all remaining superfluous commas before parsing the next attribute. @@ -4702,12 +4713,19 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr; // '=' token marks the beginning of an annotation - if (getLangOpts().CPlusPlus26 && Tok.is(tok::equal)) { + if (Tok.is(tok::equal)) { + if (!getLangOpts().CPlusPlus26) { + Diag(Tok.getLocation(), diag::warn_cxx26_compat_annotation); + SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); + continue; + } if (CommonScopeName) { Diag(Tok.getLocation(), diag::err_annotation_with_using); SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); continue; } + ParseAnnotationSpecifier(Attrs, EndLoc); + hasAnnotation = true; continue; } @@ -4744,11 +4762,11 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, } // Parse attribute arguments - if (Tok.is(tok::l_paren)) - AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc, - ScopeName, ScopeLoc, OpenMPTokens); + hasAttribute = Tok.is(tok::l_paren) + && ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc, + ScopeName, ScopeLoc, OpenMPTokens); - if (!AttrParsed) { + if (!hasAttribute) { Attrs.addNew(AttrName, SourceRange(ScopeLoc.isValid() && CommonScopeLoc.isInvalid() ? ScopeLoc @@ -4758,7 +4776,7 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, nullptr, 0, getLangOpts().CPlusPlus ? ParsedAttr::Form::CXX11() : ParsedAttr::Form::C23()); - AttrParsed = true; + hasAttribute = true; } if (TryConsumeToken(tok::ellipsis)) >From cc405d31f4a9c0eb3d931b7d92729c98b7170889 Mon Sep 17 00:00:00 2001 From: acassagnes <[email protected]> Date: Tue, 4 Nov 2025 09:19:07 +0900 Subject: [PATCH 3/7] Add sema handler for annotation Add parsing for annotation Signed-off-by: acassagnes <[email protected]> --- .../include/clang/Basic/AttributeCommonInfo.h | 8 ++- clang/lib/Parse/ParseDeclCXX.cpp | 28 +++++++++- clang/lib/Sema/SemaDeclAttr.cpp | 56 +++++++++++++++++++ 3 files changed, 88 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h index 77b5eb8a1a7cc..c404d840555fd 100644 --- a/clang/include/clang/Basic/AttributeCommonInfo.h +++ b/clang/include/clang/Basic/AttributeCommonInfo.h @@ -61,7 +61,10 @@ class AttributeCommonInfo { /// The attibute has no source code manifestation and is only created /// implicitly. - AS_Implicit + AS_Implicit, + + /// The attribute is a C++26 annotation. + AS_Annotation, }; enum Kind { @@ -133,6 +136,7 @@ class AttributeCommonInfo { static Form ContextSensitiveKeyword() { return AS_ContextSensitiveKeyword; } static Form HLSLAnnotation() { return AS_HLSLAnnotation; } static Form Implicit() { return AS_Implicit; } + static Form Annotation() { return AS_Annotation; } private: constexpr Form(Syntax SyntaxUsed) @@ -156,7 +160,7 @@ class AttributeCommonInfo { SpellingIndex(FormUsed.getSpellingIndex()), IsAlignas(FormUsed.isAlignas()), IsRegularKeywordAttribute(FormUsed.isRegularKeywordAttribute()) { - assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit && + assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Annotation && "Invalid syntax!"); } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 4a82a365bb0b8..df33948790fd3 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -4446,7 +4446,23 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, void Parser::ParseAnnotationSpecifier(ParsedAttributes &Attrs, SourceLocation *EndLoc) { - // TODO + assert(Tok.is(tok::equal) && "not an annotation"); + SourceLocation EqLoc = ConsumeToken(); + + ExprResult AnnotExpr = ParseConstantExpression(); + if (AnnotExpr.isInvalid() || AnnotExpr.get()->containsErrors()) + return; + + IdentifierTable &IT = Actions.PP.getIdentifierTable(); + IdentifierInfo &Placeholder = IT.get("__annotation_placeholder"); + + ArgsVector ArgExprs; + ArgExprs.push_back(AnnotExpr.get()); + Attrs.addNew(&Placeholder, EqLoc, {}, ArgExprs.data(), 1, + ParsedAttr::Form::Annotation()); + + if (EndLoc) + *EndLoc = AnnotExpr.get()->getEndLoc(); } bool Parser::ParseCXXAssumeAttributeArg( @@ -4712,7 +4728,10 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, SourceLocation ScopeLoc, AttrLoc; IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr; - // '=' token marks the beginning of an annotation + // A '=' token marks the beginning of an annotation + // - We must not be in C++ < 26 + // - We must not have seen 'using X::' + // - We must not mix with an attribute if (Tok.is(tok::equal)) { if (!getLangOpts().CPlusPlus26) { Diag(Tok.getLocation(), diag::warn_cxx26_compat_annotation); @@ -4724,6 +4743,11 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); continue; } + if (hasAttribute) { + Diag(Tok.getLocation(), diag::err_mixed_attributes_and_annotations); + SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); + continue; + } ParseAnnotationSpecifier(Attrs, EndLoc); hasAnnotation = true; continue; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index a9e7b44ac9d73..725a84fd85c3c 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6409,6 +6409,59 @@ static void handleRequiresCapabilityAttr(Sema &S, Decl *D, D->addAttr(RCA); } +static void handleCxx26AnnotationAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + Expr *CE = AL.getArgAsExpr(0); + if (CE->isLValue()) { + if (CE->getType()->isRecordType()) { + InitializedEntity Entity = + InitializedEntity::InitializeTemporary( + CE->getType().getUnqualifiedType()); + InitializationKind Kind = + InitializationKind::CreateCopy(CE->getExprLoc(), SourceLocation()); + InitializationSequence Seq(S, Entity, Kind, CE); + + ExprResult CopyResult = Seq.Perform(S, Entity, Kind, CE); + if (CopyResult.isInvalid()) + return; + + CE = CopyResult.get(); + } else { + ExprResult RVExprResult = S.DefaultLvalueConversion(AL.getArgAsExpr(0)); + assert(!RVExprResult.isInvalid() && RVExprResult.get()); + + CE = RVExprResult.get(); + } + } + + Expr::EvalResult Result; + + SmallVector<PartialDiagnosticAt, 4> Notes; + Result.Diag = &Notes; + + if (!CE->isValueDependent()) { + ConstantExprKind CEKind = (CE->getType()->isClassType() ? + ConstantExprKind::ClassTemplateArgument : + ConstantExprKind::NonClassTemplateArgument); + + if (!CE->EvaluateAsConstantExpr(Result, S.Context, CEKind)) { + S.Diag(CE->getBeginLoc(), diag::err_attribute_argument_type) + << "C++26 annotation" << 4 << CE->getSourceRange(); + for (auto P : Notes) + S.Diag(P.first, P.second); + + return; + } else if (!CE->getType()->isStructuralType()) { + S.Diag(CE->getBeginLoc(), diag::err_attribute_argument_type) + << "C++26 annotation" << 5 << CE->getSourceRange(); + return; + } + } + auto *Annot = CXX26AnnotationAttr::Create(S.Context, CE, AL); + Annot->setValue(Result.Val); + Annot->setEqLoc(AL.getLoc()); + D->addAttr(Annot); +} + static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (const auto *NSD = dyn_cast<NamespaceDecl>(D)) { if (NSD->isAnonymousNamespace()) { @@ -7179,6 +7232,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_Constructor: handleConstructorAttr(S, D, AL); break; + case ParsedAttr::AT_CXX26Annotation: + handleCxx26AnnotationAttr(S, D, AL); + break; case ParsedAttr::AT_Deprecated: handleDeprecatedAttr(S, D, AL); break; >From 0a8e12564aae79285802f6d6598038c1f74de41c Mon Sep 17 00:00:00 2001 From: acassagnes <[email protected]> Date: Tue, 4 Nov 2025 09:43:08 +0900 Subject: [PATCH 4/7] Fix the copy around of common info for attribute Signed-off-by: acassagnes <[email protected]> --- clang/lib/Sema/ParsedAttr.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp index 2b5ad33ad7b29..888a5d42a0ec6 100644 --- a/clang/lib/Sema/ParsedAttr.cpp +++ b/clang/lib/Sema/ParsedAttr.cpp @@ -107,6 +107,13 @@ const ParsedAttrInfo &ParsedAttrInfo::get(const AttributeCommonInfo &A) { if ((size_t)A.getParsedKind() < std::size(AttrInfoMap)) return *AttrInfoMap[A.getParsedKind()]; + // If this is an annotation then return an appropriate ParsedAttrInfo. + static const ParsedAttrInfo AnnotationAttrInfo( + AttributeCommonInfo::AT_CXX26Annotation, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, {}, + nullptr); + if (A.getSyntax() == AttributeCommonInfo::AS_Annotation) + return AnnotationAttrInfo; + // If this is an ignored attribute then return an appropriate ParsedAttrInfo. static const ParsedAttrInfo IgnoredParsedAttrInfo( AttributeCommonInfo::IgnoredAttribute); >From c579bd993143b0c281fd1e7b4e7e3cb028eb0f4a Mon Sep 17 00:00:00 2001 From: acassagnes <[email protected]> Date: Tue, 4 Nov 2025 11:21:59 +0900 Subject: [PATCH 5/7] Fill the doc for ParseAnnotationSpecifier Signed-off-by: acassagnes <[email protected]> --- clang/include/clang/Parse/Parser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index dd1e774316ca0..52b909ffcae91 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3046,7 +3046,7 @@ class Parser : public CodeCompletionHandler { SourceLocation ScopeLoc, CachedTokens &OpenMPTokens); - /// TODO doc + /// Parse an annotation as specified from C++26 void ParseAnnotationSpecifier(ParsedAttributes &Attrs, SourceLocation *EndLoc); >From 7673caba149e586a84f0c8e371680a38ccc7cce8 Mon Sep 17 00:00:00 2001 From: acassagnes <[email protected]> Date: Tue, 4 Nov 2025 11:45:06 +0900 Subject: [PATCH 6/7] Apply formatter Signed-off-by: acassagnes <[email protected]> --- clang/lib/Parse/ParseDeclCXX.cpp | 9 ++++----- clang/lib/Sema/SemaDeclAttr.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index df33948790fd3..04eea962a0208 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -4444,8 +4444,7 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, } void Parser::ParseAnnotationSpecifier(ParsedAttributes &Attrs, - SourceLocation *EndLoc) -{ + SourceLocation *EndLoc) { assert(Tok.is(tok::equal) && "not an annotation"); SourceLocation EqLoc = ConsumeToken(); @@ -4786,9 +4785,9 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, } // Parse attribute arguments - hasAttribute = Tok.is(tok::l_paren) - && ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc, - ScopeName, ScopeLoc, OpenMPTokens); + hasAttribute = Tok.is(tok::l_paren) && + ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc, + ScopeName, ScopeLoc, OpenMPTokens); if (!hasAttribute) { Attrs.addNew(AttrName, diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 725a84fd85c3c..f72328facddfc 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6413,9 +6413,8 @@ static void handleCxx26AnnotationAttr(Sema &S, Decl *D, const ParsedAttr &AL) { Expr *CE = AL.getArgAsExpr(0); if (CE->isLValue()) { if (CE->getType()->isRecordType()) { - InitializedEntity Entity = - InitializedEntity::InitializeTemporary( - CE->getType().getUnqualifiedType()); + InitializedEntity Entity = InitializedEntity::InitializeTemporary( + CE->getType().getUnqualifiedType()); InitializationKind Kind = InitializationKind::CreateCopy(CE->getExprLoc(), SourceLocation()); InitializationSequence Seq(S, Entity, Kind, CE); @@ -6439,9 +6438,10 @@ static void handleCxx26AnnotationAttr(Sema &S, Decl *D, const ParsedAttr &AL) { Result.Diag = &Notes; if (!CE->isValueDependent()) { - ConstantExprKind CEKind = (CE->getType()->isClassType() ? - ConstantExprKind::ClassTemplateArgument : - ConstantExprKind::NonClassTemplateArgument); + ConstantExprKind CEKind = + (CE->getType()->isClassType() + ? ConstantExprKind::ClassTemplateArgument + : ConstantExprKind::NonClassTemplateArgument); if (!CE->EvaluateAsConstantExpr(Result, S.Context, CEKind)) { S.Diag(CE->getBeginLoc(), diag::err_attribute_argument_type) >From c28d0666990ffdc06286fa2515714fcb81e6cca8 Mon Sep 17 00:00:00 2001 From: acassagnes <[email protected]> Date: Tue, 4 Nov 2025 14:39:00 +0900 Subject: [PATCH 7/7] Address review Signed-off-by: acassagnes <[email protected]> Undo dumb edit Signed-off-by: acassagnes <[email protected]> --- clang/lib/Parse/ParseDeclCXX.cpp | 18 +++++++++--------- clang/lib/Sema/SemaDeclAttr.cpp | 3 ++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 04eea962a0208..920b7b9429c4c 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -4703,17 +4703,17 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, Diag(Tok.getLocation(), diag::err_expected) << tok::colon; } - bool hasAttribute = false; - bool hasAnnotation = false; + bool HasAttribute = false; + bool HasAnnotation = false; while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof)) { // If we parsed an attribute/annotation, a comma is required before parsing // any additional ones. - if (hasAttribute || hasAnnotation) { + if (HasAttribute || HasAnnotation) { if (ExpectAndConsume(tok::comma)) { SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch); continue; } - if (hasAttribute && hasAnnotation) { + if (HasAttribute && HasAnnotation) { Diag(Tok.getLocation(), diag::err_mixed_attributes_and_annotations); SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); continue; @@ -4742,13 +4742,13 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); continue; } - if (hasAttribute) { + if (HasAttribute) { Diag(Tok.getLocation(), diag::err_mixed_attributes_and_annotations); SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); continue; } ParseAnnotationSpecifier(Attrs, EndLoc); - hasAnnotation = true; + HasAnnotation = true; continue; } @@ -4785,11 +4785,11 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, } // Parse attribute arguments - hasAttribute = Tok.is(tok::l_paren) && + HasAttribute = Tok.is(tok::l_paren) && ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc, ScopeName, ScopeLoc, OpenMPTokens); - if (!hasAttribute) { + if (!HasAttribute) { Attrs.addNew(AttrName, SourceRange(ScopeLoc.isValid() && CommonScopeLoc.isInvalid() ? ScopeLoc @@ -4799,7 +4799,7 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, nullptr, 0, getLangOpts().CPlusPlus ? ParsedAttr::Form::CXX11() : ParsedAttr::Form::C23()); - hasAttribute = true; + HasAttribute = true; } if (TryConsumeToken(tok::ellipsis)) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f72328facddfc..2e293b15b97d0 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6450,7 +6450,8 @@ static void handleCxx26AnnotationAttr(Sema &S, Decl *D, const ParsedAttr &AL) { S.Diag(P.first, P.second); return; - } else if (!CE->getType()->isStructuralType()) { + } + if (!CE->getType()->isStructuralType()) { S.Diag(CE->getBeginLoc(), diag::err_attribute_argument_type) << "C++26 annotation" << 5 << CE->getSourceRange(); return; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
