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

Reply via email to