https://github.com/a-tarasyuk updated 
https://github.com/llvm/llvm-project/pull/106036

>From ef0f3551dbb3ce61c57a5ad044d86b504c7742e0 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Tue, 10 Sep 2024 02:35:43 +0300
Subject: [PATCH 1/7] [Clang] restrict use of attribute names reserved by the
 C++ standard

---
 clang/docs/ReleaseNotes.rst                   |  2 ++
 .../include/clang/Basic/AttributeCommonInfo.h |  2 +-
 clang/include/clang/Basic/CMakeLists.txt      |  5 +++
 clang/include/clang/Basic/DiagnosticGroups.td |  1 +
 .../include/clang/Basic/DiagnosticLexKinds.td |  2 ++
 clang/include/clang/Lex/Preprocessor.h        | 10 +++---
 clang/include/clang/Sema/CMakeLists.txt       |  5 ---
 clang/lib/Lex/PPDirectives.cpp                | 26 +++++++++++++-
 .../Preprocessor/macro-reserved-attrs1.cpp    | 34 +++++++++++++++++++
 .../Preprocessor/macro-reserved-attrs2.cpp    | 34 +++++++++++++++++++
 .../gn/secondary/clang/lib/Basic/BUILD.gn     |  5 +--
 .../gn/secondary/clang/lib/Sema/BUILD.gn      |  2 +-
 .../llvm-project-overlay/clang/BUILD.bazel    |  9 +++--
 13 files changed, 115 insertions(+), 22 deletions(-)
 create mode 100644 clang/test/Preprocessor/macro-reserved-attrs1.cpp
 create mode 100644 clang/test/Preprocessor/macro-reserved-attrs2.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 61aa955ca9b9d4..09a0e46014476a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -788,6 +788,8 @@ Improvements to Clang's diagnostics
       require(scope); // Warning!  Requires mu1.
     }
 
+- Clang now diagnoses the use of attribute names reserved by the C++ standard 
(#GH92196).
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h 
b/clang/include/clang/Basic/AttributeCommonInfo.h
index 11c64547721739..4fee781fb9c5a1 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -61,7 +61,7 @@ class AttributeCommonInfo {
   };
   enum Kind {
 #define PARSED_ATTR(NAME) AT_##NAME,
-#include "clang/Sema/AttrParsedAttrList.inc"
+#include "clang/Basic/AttrParsedAttrList.inc"
 #undef PARSED_ATTR
     NoSemaHandlerAttribute,
     IgnoredAttribute,
diff --git a/clang/include/clang/Basic/CMakeLists.txt 
b/clang/include/clang/Basic/CMakeLists.txt
index 897a610b7f9089..f4843189348b8d 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -31,6 +31,11 @@ clang_tablegen(AttrList.inc -gen-clang-attr-list
   SOURCE Attr.td
   TARGET ClangAttrList)
 
+clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE Attr.td
+  TARGET ClangAttrParsedAttrList)
+
 clang_tablegen(AttrSubMatchRulesList.inc 
-gen-clang-attr-subject-match-rule-list
   -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
   SOURCE Attr.td
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index b0ad76026fdb35..14d85696cc0089 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -760,6 +760,7 @@ def AmbiguousMacro : DiagGroup<"ambiguous-macro">;
 def KeywordAsMacro : DiagGroup<"keyword-macro">;
 def ReservedIdAsMacro : DiagGroup<"reserved-macro-identifier">;
 def ReservedIdAsMacroAlias : DiagGroup<"reserved-id-macro", 
[ReservedIdAsMacro]>;
+def ReservedAttributeIdentifier : DiagGroup<"reserved-attribute-identifier">;
 def RestrictExpansionMacro : DiagGroup<"restrict-expansion">;
 def FinalMacro : DiagGroup<"final-macro">;
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 959376b0847216..9b28e28f59506d 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -407,6 +407,8 @@ def warn_pp_macro_hides_keyword : Extension<
 def warn_pp_macro_is_reserved_id : Warning<
   "macro name is a reserved identifier">, DefaultIgnore,
   InGroup<ReservedIdAsMacro>;
+def warn_pp_macro_is_reserved_attribute_id : Warning<
+  "%0 is a reserved attribute identifier">, 
InGroup<ReservedAttributeIdentifier>;
 def warn_pp_objc_macro_redef_ignored : Warning<
   "ignoring redefinition of Objective-C qualifier macro">,
   InGroup<DiagGroup<"objc-macro-redefinition">>;
diff --git a/clang/include/clang/Lex/Preprocessor.h 
b/clang/include/clang/Lex/Preprocessor.h
index 3d223c345ea156..8ddc5b56eedbd4 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -2271,6 +2271,11 @@ class Preprocessor {
     }
   }
 
+  /// Determine whether the next preprocessor token to be
+  /// lexed is a '('.  If so, consume the token and return true, if not, this
+  /// method should have no observable side-effect on the lexed tokens.
+  bool isNextPPTokenLParen();
+
 private:
   /// Identifiers used for SEH handling in Borland. These are only
   /// allowed in particular circumstances
@@ -2648,11 +2653,6 @@ class Preprocessor {
 
   void removeCachedMacroExpandedTokensOfLastLexer();
 
-  /// Determine whether the next preprocessor token to be
-  /// lexed is a '('.  If so, consume the token and return true, if not, this
-  /// method should have no observable side-effect on the lexed tokens.
-  bool isNextPPTokenLParen();
-
   /// After reading "MACRO(", this method is invoked to read all of the formal
   /// arguments specified for the macro invocation.  Returns null on error.
   MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI,
diff --git a/clang/include/clang/Sema/CMakeLists.txt 
b/clang/include/clang/Sema/CMakeLists.txt
index 0b0e31ece3195d..9077e22c2307cd 100644
--- a/clang/include/clang/Sema/CMakeLists.txt
+++ b/clang/include/clang/Sema/CMakeLists.txt
@@ -3,11 +3,6 @@ clang_tablegen(AttrTemplateInstantiate.inc 
-gen-clang-attr-template-instantiate
   SOURCE ../Basic/Attr.td
   TARGET ClangAttrTemplateInstantiate)
 
-clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list
-  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
-  SOURCE ../Basic/Attr.td
-  TARGET ClangAttrParsedAttrList)
-
 clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds
   -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
   SOURCE ../Basic/Attr.td
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index a23ad40884f249..4889bd47c199e4 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -11,6 +11,8 @@
 ///
 
//===----------------------------------------------------------------------===//
 
+#include "clang/Basic/AttributeCommonInfo.h"
+#include "clang/Basic/Attributes.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/DirectoryEntry.h"
 #include "clang/Basic/FileManager.h"
@@ -97,7 +99,8 @@ SourceRange Preprocessor::DiscardUntilEndOfDirective(Token 
&Tmp) {
 enum MacroDiag {
   MD_NoWarn,        //> Not a reserved identifier
   MD_KeywordDef,    //> Macro hides keyword, enabled by default
-  MD_ReservedMacro  //> #define of #undef reserved id, disabled by default
+  MD_ReservedMacro, //> #define of #undef reserved id, disabled by default
+  MD_ReservedAttributeIdentifier
 };
 
 /// Enumerates possible %select values for the pp_err_elif_after_else and
@@ -173,6 +176,20 @@ static bool isLanguageDefinedBuiltin(const SourceManager 
&SourceMgr,
   return false;
 }
 
+static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II) {
+  const LangOptions &Lang = PP.getLangOpts();
+  if (Lang.CPlusPlus &&
+      hasAttribute(AttributeCommonInfo::Syntax::AS_CXX11, /*Scope*/ nullptr, 
II,
+                   PP.getTargetInfo(), Lang) > 0) {
+    AttributeCommonInfo::Kind AttrKind = AttributeCommonInfo::getParsedKind(
+        II, /*Scope*/ nullptr, AttributeCommonInfo::Syntax::AS_CXX11);
+    return !((AttrKind == AttributeCommonInfo::Kind::AT_Likely ||
+              AttrKind == AttributeCommonInfo::Kind::AT_Unlikely) &&
+             PP.isNextPPTokenLParen());
+  }
+  return false;
+}
+
 static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
   const LangOptions &Lang = PP.getLangOpts();
   StringRef Text = II->getName();
@@ -182,6 +199,8 @@ static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, 
IdentifierInfo *II) {
     return MD_KeywordDef;
   if (Lang.CPlusPlus11 && (Text == "override" || Text == "final"))
     return MD_KeywordDef;
+  if (isReservedCXXAttributeName(PP, II))
+    return MD_ReservedAttributeIdentifier;
   return MD_NoWarn;
 }
 
@@ -190,6 +209,8 @@ static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, 
IdentifierInfo *II) {
   // Do not warn on keyword undef.  It is generally harmless and widely used.
   if (isReservedInAllContexts(II->isReserved(Lang)))
     return MD_ReservedMacro;
+  if (isReservedCXXAttributeName(PP, II))
+    return MD_ReservedAttributeIdentifier;
   return MD_NoWarn;
 }
 
@@ -365,6 +386,9 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, 
MacroUse isDefineUndef,
     }
     if (D == MD_ReservedMacro)
       Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
+    if (D == MD_ReservedAttributeIdentifier)
+      Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)
+          << II->getName();
   }
 
   // Okay, we got a good identifier.
diff --git a/clang/test/Preprocessor/macro-reserved-attrs1.cpp 
b/clang/test/Preprocessor/macro-reserved-attrs1.cpp
new file mode 100644
index 00000000000000..6a7554e1b83a67
--- /dev/null
+++ b/clang/test/Preprocessor/macro-reserved-attrs1.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s
+
+#define noreturn 1 // expected-warning {{noreturn is a reserved attribute 
identifier}}
+#undef noreturn    // expected-warning {{noreturn is a reserved attribute 
identifier}}
+
+#define assume 1 // expected-warning {{assume is a reserved attribute 
identifier}}
+#undef assume    // expected-warning {{assume is a reserved attribute 
identifier}}
+
+#define carries_dependency 1 // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
+#undef carries_dependency    // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
+
+#define deprecated 1 // expected-warning {{deprecated is a reserved attribute 
identifier}}
+#undef deprecated    // expected-warning {{deprecated is a reserved attribute 
identifier}}
+
+#define fallthrough 1 // expected-warning {{fallthrough is a reserved 
attribute identifier}}
+#undef fallthrough    // expected-warning {{fallthrough is a reserved 
attribute identifier}}
+
+#define likely 1 // expected-warning {{likely is a reserved attribute 
identifier}}
+#undef likely    // expected-warning {{likely is a reserved attribute 
identifier}}
+
+#define no_unique_address 1 // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
+#undef no_unique_address    // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
+
+#define unlikely 1 // expected-warning {{unlikely is a reserved attribute 
identifier}}
+#undef unlikely    // expected-warning {{unlikely is a reserved attribute 
identifier}}
+
+#define maybe_unused 1 // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
+#undef maybe_unused    // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
+
+#define nodiscard 1 // expected-warning {{nodiscard is a reserved attribute 
identifier}}
+#undef nodiscard    // expected-warning {{nodiscard is a reserved attribute 
identifier}}
+
+#define likely() 1   // ok
+#define unlikely() 1 // ok
diff --git a/clang/test/Preprocessor/macro-reserved-attrs2.cpp 
b/clang/test/Preprocessor/macro-reserved-attrs2.cpp
new file mode 100644
index 00000000000000..eddbe0cebb74ab
--- /dev/null
+++ b/clang/test/Preprocessor/macro-reserved-attrs2.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s
+
+#define noreturn // expected-warning {{noreturn is a reserved attribute 
identifier}}
+#undef noreturn  // expected-warning {{noreturn is a reserved attribute 
identifier}}
+
+#define assume // expected-warning {{assume is a reserved attribute 
identifier}}
+#undef assume  // expected-warning {{assume is a reserved attribute 
identifier}}
+
+#define carries_dependency // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
+#undef carries_dependency  // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
+
+#define deprecated // expected-warning {{deprecated is a reserved attribute 
identifier}}
+#undef deprecated  // expected-warning {{deprecated is a reserved attribute 
identifier}}
+
+#define fallthrough // expected-warning {{fallthrough is a reserved attribute 
identifier}}
+#undef fallthrough  // expected-warning {{fallthrough is a reserved attribute 
identifier}}
+
+#define likely // expected-warning {{likely is a reserved attribute 
identifier}}
+#undef likely  // expected-warning {{likely is a reserved attribute 
identifier}}
+
+#define no_unique_address // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
+#undef no_unique_address  // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
+
+#define unlikely // expected-warning {{unlikely is a reserved attribute 
identifier}}
+#undef unlikely  // expected-warning {{unlikely is a reserved attribute 
identifier}}
+
+#define maybe_unused // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
+#undef maybe_unused  // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
+
+#define nodiscard // expected-warning {{nodiscard is a reserved attribute 
identifier}}
+#undef nodiscard  // expected-warning {{nodiscard is a reserved attribute 
identifier}}
+
+#define likely()   // ok
+#define unlikely() // ok
diff --git a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn 
b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn
index d759ff4429a922..99c86facde83c6 100644
--- a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn
+++ b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn
@@ -22,6 +22,7 @@ static_library("Basic") {
   public_deps = [
     # public_dep because public header Version.h includes generated 
Version.inc.
     "//clang/include/clang/Basic:AttrList",
+    "//clang/include/clang/Basic:AttrParsedAttrList",
     "//clang/include/clang/Basic:AttrSubMatchRulesList",
     "//clang/include/clang/Basic:Builtins",
     "//clang/include/clang/Basic:BuiltinsBPF",
@@ -42,10 +43,6 @@ static_library("Basic") {
     "//clang/include/clang/Basic:riscv_vector_builtins",
     "//clang/include/clang/Basic:version",
 
-    # public_dep because public header AttributeCommonInfo.h includes generated
-    # AttrParsedAttrList.inc.
-    "//clang/include/clang/Sema:AttrParsedAttrList",
-
     # public_dep because public header OpenMPKinds.h includes generated
     # OMP.h.inc.
     "//llvm/include/llvm/Frontend/OpenMP:public_tablegen",
diff --git a/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn 
b/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn
index fd2ac587146646..b5861cf1db4565 100644
--- a/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn
+++ b/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn
@@ -9,6 +9,7 @@ static_library("Sema") {
   configs += [ "//llvm/utils/gn/build:clang_code" ]
   deps = [
     ":OpenCLBuiltins",
+    "//clang/include/clang/Basic:AttrParsedAttrList",
     "//clang/include/clang/Basic:arm_cde_builtin_aliases",
     "//clang/include/clang/Basic:arm_cde_builtin_sema",
     "//clang/include/clang/Basic:arm_mve_builtin_aliases",
@@ -22,7 +23,6 @@ static_library("Sema") {
     "//clang/include/clang/Basic:riscv_vector_builtin_sema",
     "//clang/include/clang/Sema:AttrParsedAttrImpl",
     "//clang/include/clang/Sema:AttrParsedAttrKinds",
-    "//clang/include/clang/Sema:AttrParsedAttrList",
     "//clang/include/clang/Sema:AttrSpellingListIndex",
     "//clang/include/clang/Sema:AttrTemplateInstantiate",
     "//clang/lib/APINotes",
diff --git a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel 
b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
index 9d33e94e4432b2..a150eac28b5e1f 100644
--- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
@@ -566,6 +566,10 @@ gentbl(
             "-gen-clang-attr-list",
             "include/clang/Basic/AttrList.inc",
         ),
+        (
+            "-gen-clang-attr-parsed-attr-list",
+            "include/clang/Basic/AttrParsedAttrList.inc",
+        ),
         (
             "-gen-clang-attr-subject-match-rule-list",
             "include/clang/Basic/AttrSubMatchRulesList.inc",
@@ -1139,10 +1143,6 @@ gentbl(
             "-gen-clang-attr-parsed-attr-kinds",
             "include/clang/Sema/AttrParsedAttrKinds.inc",
         ),
-        (
-            "-gen-clang-attr-parsed-attr-list",
-            "include/clang/Sema/AttrParsedAttrList.inc",
-        ),
         (
             "-gen-clang-attr-spelling-index",
             "include/clang/Sema/AttrSpellingListIndex.inc",
@@ -1178,7 +1178,6 @@ cc_library(
     textual_hdrs = [
         "include/clang/Sema/AttrParsedAttrImpl.inc",
         "include/clang/Sema/AttrParsedAttrKinds.inc",
-        "include/clang/Sema/AttrParsedAttrList.inc",
         "include/clang/Sema/AttrSpellingListIndex.inc",
         "include/clang/Sema/AttrTemplateInstantiate.inc",
         "lib/Sema/OpenCLBuiltins.inc",

>From 593cc60948fd833c3fc32f24e831e63a9d0a811f Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Wed, 15 Jan 2025 02:26:02 +0200
Subject: [PATCH 2/7] update tests

---
 clang/test/Preprocessor/macro-reserved-attrs1.cpp | 2 +-
 clang/test/Preprocessor/macro-reserved-attrs2.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/Preprocessor/macro-reserved-attrs1.cpp 
b/clang/test/Preprocessor/macro-reserved-attrs1.cpp
index 6a7554e1b83a67..c91922f25d5bca 100644
--- a/clang/test/Preprocessor/macro-reserved-attrs1.cpp
+++ b/clang/test/Preprocessor/macro-reserved-attrs1.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify 
-pedantic %s
 
 #define noreturn 1 // expected-warning {{noreturn is a reserved attribute 
identifier}}
 #undef noreturn    // expected-warning {{noreturn is a reserved attribute 
identifier}}
diff --git a/clang/test/Preprocessor/macro-reserved-attrs2.cpp 
b/clang/test/Preprocessor/macro-reserved-attrs2.cpp
index eddbe0cebb74ab..450146b6a13d66 100644
--- a/clang/test/Preprocessor/macro-reserved-attrs2.cpp
+++ b/clang/test/Preprocessor/macro-reserved-attrs2.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify 
-pedantic %s
 
 #define noreturn // expected-warning {{noreturn is a reserved attribute 
identifier}}
 #undef noreturn  // expected-warning {{noreturn is a reserved attribute 
identifier}}

>From d89c879c124340089ffdb649e7d12d55ced51e05 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Thu, 16 Jan 2025 19:16:51 +0200
Subject: [PATCH 3/7] handle function like attr names

---
 .../include/clang/Basic/AttributeCommonInfo.h |   7 ++
 clang/include/clang/Basic/CMakeLists.txt      |   6 ++
 clang/lib/Basic/Attributes.cpp                |  10 ++
 clang/lib/Lex/PPDirectives.cpp                |  12 ++-
 .../macro-reserved-attrs-cxx11.cpp            | 100 ++++++++++++++++++
 .../Preprocessor/macro-reserved-attrs1.cpp    |  34 ------
 .../Preprocessor/macro-reserved-attrs2.cpp    |  34 ------
 clang/utils/TableGen/ClangAttrEmitter.cpp     |  30 ++++++
 clang/utils/TableGen/TableGen.cpp             |   6 ++
 clang/utils/TableGen/TableGenBackends.h       |   2 +
 10 files changed, 168 insertions(+), 73 deletions(-)
 create mode 100644 clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp
 delete mode 100644 clang/test/Preprocessor/macro-reserved-attrs1.cpp
 delete mode 100644 clang/test/Preprocessor/macro-reserved-attrs2.cpp

diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h 
b/clang/include/clang/Basic/AttributeCommonInfo.h
index 4fee781fb9c5a1..4af5a8fd1852cf 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -68,6 +68,11 @@ class AttributeCommonInfo {
     UnknownAttribute,
   };
   enum class Scope { NONE, CLANG, GNU, MSVC, OMP, HLSL, GSL, RISCV };
+  enum class AttrArgsInfo {
+    None,
+    Optional,
+    Required,
+  };
 
 private:
   const IdentifierInfo *AttrName = nullptr;
@@ -241,6 +246,8 @@ class AttributeCommonInfo {
   static Kind getParsedKind(const IdentifierInfo *Name,
                             const IdentifierInfo *Scope, Syntax SyntaxUsed);
 
+  static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name);
+
 private:
   /// Get an index into the attribute spelling list
   /// defined in Attr.td. This index is used by an attribute
diff --git a/clang/include/clang/Basic/CMakeLists.txt 
b/clang/include/clang/Basic/CMakeLists.txt
index f4843189348b8d..a9dac57192259c 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -53,6 +53,12 @@ clang_tablegen(AttrHasAttributeImpl.inc 
-gen-clang-attr-has-attribute-impl
   TARGET ClangAttrHasAttributeImpl
   )
 
+clang_tablegen(CXX11AttributeInfo.inc -gen-cxx11-attribute-info
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE Attr.td
+  TARGET CXX11AttributeInfo
+  )
+
 clang_tablegen(Builtins.inc -gen-clang-builtins
   SOURCE Builtins.td
   TARGET ClangBuiltins)
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index fa26cc584b724a..6b5499ccf18d23 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -151,6 +151,16 @@ AttributeCommonInfo::getParsedKind(const IdentifierInfo 
*Name,
   return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
 }
 
+AttributeCommonInfo::AttrArgsInfo
+AttributeCommonInfo::getCXX11AttrArgsInfo(const IdentifierInfo *Name) {
+#define CXX11_ATTR_ARGS_INFO
+  return llvm::StringSwitch<AttributeCommonInfo::AttrArgsInfo>(
+             normalizeName(Name, /*Scope*/ nullptr, Syntax::AS_CXX11))
+#include "clang/Basic/CXX11AttributeInfo.inc"
+      .Default(AttributeCommonInfo::AttrArgsInfo::None);
+#undef CXX11_ATTR_ARGS_INFO
+}
+
 std::string AttributeCommonInfo::getNormalizedFullName() const {
   return static_cast<std::string>(
       normalizeName(getAttrName(), getScopeName(), getSyntax()));
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 4889bd47c199e4..446df863170b4a 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -181,11 +181,13 @@ static bool isReservedCXXAttributeName(Preprocessor &PP, 
IdentifierInfo *II) {
   if (Lang.CPlusPlus &&
       hasAttribute(AttributeCommonInfo::Syntax::AS_CXX11, /*Scope*/ nullptr, 
II,
                    PP.getTargetInfo(), Lang) > 0) {
-    AttributeCommonInfo::Kind AttrKind = AttributeCommonInfo::getParsedKind(
-        II, /*Scope*/ nullptr, AttributeCommonInfo::Syntax::AS_CXX11);
-    return !((AttrKind == AttributeCommonInfo::Kind::AT_Likely ||
-              AttrKind == AttributeCommonInfo::Kind::AT_Unlikely) &&
-             PP.isNextPPTokenLParen());
+    AttributeCommonInfo::AttrArgsInfo AttrArgsInfo =
+        AttributeCommonInfo::getCXX11AttrArgsInfo(II);
+    if (AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Required)
+      return PP.isNextPPTokenLParen();
+
+    return !PP.isNextPPTokenLParen() ||
+           AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Optional;
   }
   return false;
 }
diff --git a/clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp 
b/clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp
new file mode 100644
index 00000000000000..10659cb6bcdbc5
--- /dev/null
+++ b/clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify 
-pedantic %s -DTEST1
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify 
-pedantic %s -DTEST2
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify 
-pedantic %s -DTEST3
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify 
-pedantic %s -DTEST4
+
+#ifdef TEST1
+
+#define assume
+#undef assume
+
+#define noreturn // expected-warning {{noreturn is a reserved attribute 
identifier}}
+#undef noreturn  // expected-warning {{noreturn is a reserved attribute 
identifier}}
+
+#define carries_dependency // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
+#undef carries_dependency  // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
+
+#define deprecated // expected-warning {{deprecated is a reserved attribute 
identifier}}
+#undef deprecated  // expected-warning {{deprecated is a reserved attribute 
identifier}}
+
+#define fallthrough // expected-warning {{fallthrough is a reserved attribute 
identifier}}
+#undef fallthrough  // expected-warning {{fallthrough is a reserved attribute 
identifier}}
+
+#define likely // expected-warning {{likely is a reserved attribute 
identifier}}
+#undef likely  // expected-warning {{likely is a reserved attribute 
identifier}}
+
+#define no_unique_address // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
+#undef no_unique_address  // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
+
+#define unlikely // expected-warning {{unlikely is a reserved attribute 
identifier}}
+#undef unlikely  // expected-warning {{unlikely is a reserved attribute 
identifier}}
+
+#define maybe_unused // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
+#undef maybe_unused  // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
+
+#define nodiscard // expected-warning {{nodiscard is a reserved attribute 
identifier}}
+#undef nodiscard  // expected-warning {{nodiscard is a reserved attribute 
identifier}}
+
+#elif TEST2
+
+#define assume "test"
+#undef assume
+
+#define noreturn "test" // expected-warning {{noreturn is a reserved attribute 
identifier}}
+#undef noreturn         // expected-warning {{noreturn is a reserved attribute 
identifier}}
+
+#define carries_dependency "test" // expected-warning {{carries_dependency is 
a reserved attribute identifier}}
+#undef carries_dependency         // expected-warning {{carries_dependency is 
a reserved attribute identifier}}
+
+#define deprecated "test" // expected-warning {{deprecated is a reserved 
attribute identifier}}
+#undef deprecated         // expected-warning {{deprecated is a reserved 
attribute identifier}}
+
+#define fallthrough "test" // expected-warning {{fallthrough is a reserved 
attribute identifier}}
+#undef fallthrough         // expected-warning {{fallthrough is a reserved 
attribute identifier}}
+
+#define likely "test" // expected-warning {{likely is a reserved attribute 
identifier}}
+#undef likely         // expected-warning {{likely is a reserved attribute 
identifier}}
+
+#define no_unique_address "test" // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
+#undef no_unique_address         // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
+
+#define unlikely "test" // expected-warning {{unlikely is a reserved attribute 
identifier}}
+#undef unlikely         // expected-warning {{unlikely is a reserved attribute 
identifier}}
+
+#define maybe_unused "test" // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
+#undef maybe_unused         // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
+
+#define nodiscard "test" // expected-warning {{nodiscard is a reserved 
attribute identifier}}
+#undef nodiscard         // expected-warning {{nodiscard is a reserved 
attribute identifier}}
+
+#elif TEST3
+
+#define assume() "test"     // expected-warning {{assume is a reserved 
attribute identifier}}
+#define deprecated() "test" // expected-warning {{deprecated is a reserved 
attribute identifier}}
+#define nodiscard() "test"  // expected-warning {{nodiscard is a reserved 
attribute identifier}}
+#define noreturn() "test"
+#define carries_dependency() "test"
+#define fallthrough() "test"
+#define likely() "test"
+#define no_unique_address() "test"
+#define unlikely() "test"
+#define maybe_unused() "test"
+
+#elif TEST4
+
+#define assume()     // expected-warning {{assume is a reserved attribute 
identifier}}
+#define deprecated() // expected-warning {{deprecated is a reserved attribute 
identifier}}
+#define nodiscard()  // expected-warning {{nodiscard is a reserved attribute 
identifier}}
+#define noreturn()
+#define carries_dependency()
+#define fallthrough()
+#define likely()
+#define no_unique_address()
+#define unlikely()
+#define maybe_unused()
+
+#else
+
+#error Unknown test
+
+#endif
diff --git a/clang/test/Preprocessor/macro-reserved-attrs1.cpp 
b/clang/test/Preprocessor/macro-reserved-attrs1.cpp
deleted file mode 100644
index c91922f25d5bca..00000000000000
--- a/clang/test/Preprocessor/macro-reserved-attrs1.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify 
-pedantic %s
-
-#define noreturn 1 // expected-warning {{noreturn is a reserved attribute 
identifier}}
-#undef noreturn    // expected-warning {{noreturn is a reserved attribute 
identifier}}
-
-#define assume 1 // expected-warning {{assume is a reserved attribute 
identifier}}
-#undef assume    // expected-warning {{assume is a reserved attribute 
identifier}}
-
-#define carries_dependency 1 // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
-#undef carries_dependency    // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
-
-#define deprecated 1 // expected-warning {{deprecated is a reserved attribute 
identifier}}
-#undef deprecated    // expected-warning {{deprecated is a reserved attribute 
identifier}}
-
-#define fallthrough 1 // expected-warning {{fallthrough is a reserved 
attribute identifier}}
-#undef fallthrough    // expected-warning {{fallthrough is a reserved 
attribute identifier}}
-
-#define likely 1 // expected-warning {{likely is a reserved attribute 
identifier}}
-#undef likely    // expected-warning {{likely is a reserved attribute 
identifier}}
-
-#define no_unique_address 1 // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
-#undef no_unique_address    // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
-
-#define unlikely 1 // expected-warning {{unlikely is a reserved attribute 
identifier}}
-#undef unlikely    // expected-warning {{unlikely is a reserved attribute 
identifier}}
-
-#define maybe_unused 1 // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
-#undef maybe_unused    // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
-
-#define nodiscard 1 // expected-warning {{nodiscard is a reserved attribute 
identifier}}
-#undef nodiscard    // expected-warning {{nodiscard is a reserved attribute 
identifier}}
-
-#define likely() 1   // ok
-#define unlikely() 1 // ok
diff --git a/clang/test/Preprocessor/macro-reserved-attrs2.cpp 
b/clang/test/Preprocessor/macro-reserved-attrs2.cpp
deleted file mode 100644
index 450146b6a13d66..00000000000000
--- a/clang/test/Preprocessor/macro-reserved-attrs2.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify 
-pedantic %s
-
-#define noreturn // expected-warning {{noreturn is a reserved attribute 
identifier}}
-#undef noreturn  // expected-warning {{noreturn is a reserved attribute 
identifier}}
-
-#define assume // expected-warning {{assume is a reserved attribute 
identifier}}
-#undef assume  // expected-warning {{assume is a reserved attribute 
identifier}}
-
-#define carries_dependency // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
-#undef carries_dependency  // expected-warning {{carries_dependency is a 
reserved attribute identifier}}
-
-#define deprecated // expected-warning {{deprecated is a reserved attribute 
identifier}}
-#undef deprecated  // expected-warning {{deprecated is a reserved attribute 
identifier}}
-
-#define fallthrough // expected-warning {{fallthrough is a reserved attribute 
identifier}}
-#undef fallthrough  // expected-warning {{fallthrough is a reserved attribute 
identifier}}
-
-#define likely // expected-warning {{likely is a reserved attribute 
identifier}}
-#undef likely  // expected-warning {{likely is a reserved attribute 
identifier}}
-
-#define no_unique_address // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
-#undef no_unique_address  // expected-warning {{no_unique_address is a 
reserved attribute identifier}}
-
-#define unlikely // expected-warning {{unlikely is a reserved attribute 
identifier}}
-#undef unlikely  // expected-warning {{unlikely is a reserved attribute 
identifier}}
-
-#define maybe_unused // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
-#undef maybe_unused  // expected-warning {{maybe_unused is a reserved 
attribute identifier}}
-
-#define nodiscard // expected-warning {{nodiscard is a reserved attribute 
identifier}}
-#undef nodiscard  // expected-warning {{nodiscard is a reserved attribute 
identifier}}
-
-#define likely()   // ok
-#define unlikely() // ok
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp 
b/clang/utils/TableGen/ClangAttrEmitter.cpp
index cc6a8eaebd44ec..de12c7062666a4 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3743,6 +3743,36 @@ void EmitClangRegularKeywordAttributeInfo(const 
RecordKeeper &Records,
   OS << "#undef KEYWORD_ATTRIBUTE\n";
 }
 
+void EmitCXX11AttributeInfo(const RecordKeeper &Records, raw_ostream &OS) {
+  OS << "#if defined(CXX11_ATTR_ARGS_INFO)\n";
+  for (auto *R : Records.getAllDerivedDefinitions("Attr")) {
+    for (const FlattenedSpelling &SI : GetFlattenedSpellings(*R)) {
+      if (SI.variety() == "CXX11" && SI.nameSpace().empty()) {
+        unsigned RequiredArgs = 0;
+        unsigned OptionalArgs = 0;
+        for (const auto *Arg : R->getValueAsListOfDefs("Args")) {
+          if (Arg->getValueAsBit("Fake"))
+            continue;
+
+          if (Arg->getValueAsBit("Optional"))
+            OptionalArgs++;
+          else
+            RequiredArgs++;
+        }
+        OS << ".Case(\"" << SI.getSpellingRecord().getValueAsString("Name")
+           << "\","
+           << "AttributeCommonInfo::AttrArgsInfo::"
+           << (RequiredArgs   ? "Required"
+               : OptionalArgs ? "Optional"
+                              : "None")
+           << ")"
+           << "\n";
+      }
+    }
+  }
+  OS << "#endif // CXX11_ATTR_ARGS_INFO\n";
+}
+
 // Emits the list of spellings for attributes.
 void EmitClangAttrHasAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Code to implement the __has_attribute logic", OS,
diff --git a/clang/utils/TableGen/TableGen.cpp 
b/clang/utils/TableGen/TableGen.cpp
index 6e2bd0c9f819b8..ec7ce4a191f1f3 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -68,6 +68,7 @@ enum ActionType {
   GenClangOpenCLBuiltins,
   GenClangOpenCLBuiltinHeader,
   GenClangOpenCLBuiltinTests,
+  GenCXX11AttributeInfo,
   GenArmNeon,
   GenArmFP16,
   GenArmBF16,
@@ -225,6 +226,8 @@ cl::opt<ActionType> Action(
                    "Generate OpenCL builtin header"),
         clEnumValN(GenClangOpenCLBuiltinTests, 
"gen-clang-opencl-builtin-tests",
                    "Generate OpenCL builtin declaration tests"),
+        clEnumValN(GenCXX11AttributeInfo, "gen-cxx11-attribute-info",
+                   "Generate CXX11 attributes info"),
         clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for 
clang"),
         clEnumValN(GenArmFP16, "gen-arm-fp16", "Generate arm_fp16.h for 
clang"),
         clEnumValN(GenArmBF16, "gen-arm-bf16", "Generate arm_bf16.h for 
clang"),
@@ -333,6 +336,9 @@ bool ClangTableGenMain(raw_ostream &OS, const RecordKeeper 
&Records) {
   case GenClangAttrSubjectMatchRulesParserStringSwitches:
     EmitClangAttrSubjectMatchRulesParserStringSwitches(Records, OS);
     break;
+  case GenCXX11AttributeInfo:
+    EmitCXX11AttributeInfo(Records, OS);
+    break;
   case GenClangAttrImpl:
     EmitClangAttrImpl(Records, OS);
     break;
diff --git a/clang/utils/TableGen/TableGenBackends.h 
b/clang/utils/TableGen/TableGenBackends.h
index f7527ac535a870..94e42b29d594e7 100644
--- a/clang/utils/TableGen/TableGenBackends.h
+++ b/clang/utils/TableGen/TableGenBackends.h
@@ -49,6 +49,8 @@ void EmitClangAttrParserStringSwitches(const 
llvm::RecordKeeper &Records,
                                        llvm::raw_ostream &OS);
 void EmitClangAttrSubjectMatchRulesParserStringSwitches(
     const llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitCXX11AttributeInfo(const llvm::RecordKeeper &Records,
+                            llvm::raw_ostream &OS);
 void EmitClangAttrClass(const llvm::RecordKeeper &Records,
                         llvm::raw_ostream &OS);
 void EmitClangAttrImpl(const llvm::RecordKeeper &Records,

>From 2b468af4e1217c2243b420671bc1f62ac5cad649 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Fri, 17 Jan 2025 00:10:28 +0200
Subject: [PATCH 4/7] improve attribute checking with a simplified helper

---
 clang/include/clang/Basic/AttributeCommonInfo.h |  4 ++++
 clang/lib/Basic/Attributes.cpp                  | 14 ++++++++++++--
 clang/lib/Lex/PPDirectives.cpp                  |  3 +--
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h 
b/clang/include/clang/Basic/AttributeCommonInfo.h
index 4af5a8fd1852cf..b84990833b5c0f 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
 
 #include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TokenKinds.h"
 
 namespace clang {
@@ -248,6 +249,9 @@ class AttributeCommonInfo {
 
   static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name);
 
+  static bool hasCXX11Attr(const IdentifierInfo *Name, const TargetInfo 
&Target,
+                           const LangOptions &LangOpts);
+
 private:
   /// Get an index into the attribute spelling list
   /// defined in Attr.td. This index is used by an attribute
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index 6b5499ccf18d23..6e10da3255bead 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -153,14 +153,24 @@ AttributeCommonInfo::getParsedKind(const IdentifierInfo 
*Name,
 
 AttributeCommonInfo::AttrArgsInfo
 AttributeCommonInfo::getCXX11AttrArgsInfo(const IdentifierInfo *Name) {
+  StringRef AttrName =
+      normalizeAttrName(Name, /*NormalizedScopeName*/ "", Syntax::AS_CXX11);
 #define CXX11_ATTR_ARGS_INFO
-  return llvm::StringSwitch<AttributeCommonInfo::AttrArgsInfo>(
-             normalizeName(Name, /*Scope*/ nullptr, Syntax::AS_CXX11))
+  return llvm::StringSwitch<AttributeCommonInfo::AttrArgsInfo>(AttrName)
 #include "clang/Basic/CXX11AttributeInfo.inc"
       .Default(AttributeCommonInfo::AttrArgsInfo::None);
 #undef CXX11_ATTR_ARGS_INFO
 }
 
+bool AttributeCommonInfo::hasCXX11Attr(const IdentifierInfo *Name,
+                                       const TargetInfo &Target,
+                                       const LangOptions &LangOpts) {
+  StringRef AttrName =
+      normalizeAttrName(Name, /*NormalizedScopeName*/ "", Syntax::AS_CXX11);
+  return hasAttributeImpl(Syntax::AS_CXX11, AttrName, /*ScopeName*/ "", Target,
+                          LangOpts) > 0;
+}
+
 std::string AttributeCommonInfo::getNormalizedFullName() const {
   return static_cast<std::string>(
       normalizeName(getAttrName(), getScopeName(), getSyntax()));
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 446df863170b4a..60766577393ccb 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -179,8 +179,7 @@ static bool isLanguageDefinedBuiltin(const SourceManager 
&SourceMgr,
 static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II) {
   const LangOptions &Lang = PP.getLangOpts();
   if (Lang.CPlusPlus &&
-      hasAttribute(AttributeCommonInfo::Syntax::AS_CXX11, /*Scope*/ nullptr, 
II,
-                   PP.getTargetInfo(), Lang) > 0) {
+      AttributeCommonInfo::hasCXX11Attr(II, PP.getTargetInfo(), Lang)) {
     AttributeCommonInfo::AttrArgsInfo AttrArgsInfo =
         AttributeCommonInfo::getCXX11AttrArgsInfo(II);
     if (AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Required)

>From e73f6b5a596402dede35e07243ffef9d631275e2 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Fri, 17 Jan 2025 16:29:32 +0200
Subject: [PATCH 5/7] add reserved attribute identifier to reserved identifier
 group

---
 clang/include/clang/Basic/DiagnosticGroups.td | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 14d85696cc0089..209792f851b6ae 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -936,7 +936,8 @@ def SignedEnumBitfield : DiagGroup<"signed-enum-bitfield">;
 
 def ReservedModuleIdentifier : DiagGroup<"reserved-module-identifier">;
 def ReservedIdentifier : DiagGroup<"reserved-identifier",
-    [ReservedIdAsMacro, ReservedModuleIdentifier, UserDefinedLiterals]>;
+    [ReservedIdAsMacro, ReservedModuleIdentifier,
+     UserDefinedLiterals, ReservedAttributeIdentifier]>;
 
 // Unreachable code warning groups.
 //

>From bfd7f9a49b0bccc30396072233fa7e50bbc4a693 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Fri, 17 Jan 2025 19:42:04 +0200
Subject: [PATCH 6/7] add hasAttribute overload

---
 .../include/clang/Basic/AttributeCommonInfo.h |  4 ---
 clang/include/clang/Basic/Attributes.h        |  5 ++++
 clang/lib/Basic/Attributes.cpp                | 29 ++++++++++---------
 clang/lib/Lex/PPDirectives.cpp                |  3 +-
 4 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h 
b/clang/include/clang/Basic/AttributeCommonInfo.h
index b84990833b5c0f..4af5a8fd1852cf 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -15,7 +15,6 @@
 #define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
 
 #include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TokenKinds.h"
 
 namespace clang {
@@ -249,9 +248,6 @@ class AttributeCommonInfo {
 
   static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name);
 
-  static bool hasCXX11Attr(const IdentifierInfo *Name, const TargetInfo 
&Target,
-                           const LangOptions &LangOpts);
-
 private:
   /// Get an index into the attribute spelling list
   /// defined in Attr.td. This index is used by an attribute
diff --git a/clang/include/clang/Basic/Attributes.h 
b/clang/include/clang/Basic/Attributes.h
index 61666a6f4d9ac4..99bb668fe32d00 100644
--- a/clang/include/clang/Basic/Attributes.h
+++ b/clang/include/clang/Basic/Attributes.h
@@ -23,6 +23,11 @@ int hasAttribute(AttributeCommonInfo::Syntax Syntax,
                  const IdentifierInfo *Scope, const IdentifierInfo *Attr,
                  const TargetInfo &Target, const LangOptions &LangOpts);
 
+int hasAttribute(AttributeCommonInfo::Syntax Syntax,
+                 const IdentifierInfo *Scope, const IdentifierInfo *Attr,
+                 const TargetInfo &Target, const LangOptions &LangOpts,
+                 bool CheckPlugins);
+
 } // end namespace clang
 
 #endif // LLVM_CLANG_BASIC_ATTRIBUTES_H
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index 6e10da3255bead..d34ef2ebeb34d1 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -33,7 +33,8 @@ static int hasAttributeImpl(AttributeCommonInfo::Syntax 
Syntax, StringRef Name,
 
 int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
                         const IdentifierInfo *Scope, const IdentifierInfo 
*Attr,
-                        const TargetInfo &Target, const LangOptions &LangOpts) 
{
+                        const TargetInfo &Target, const LangOptions &LangOpts,
+                        bool CheckPlugins) {
   StringRef Name = Attr->getName();
   // Normalize the attribute name, __foo__ becomes foo.
   if (Name.size() >= 4 && Name.starts_with("__") && Name.ends_with("__"))
@@ -61,14 +62,23 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
   if (res)
     return res;
 
-  // Check if any plugin provides this attribute.
-  for (auto &Ptr : getAttributePluginInstances())
-    if (Ptr->hasSpelling(Syntax, Name))
-      return 1;
+  if (CheckPlugins) {
+    // Check if any plugin provides this attribute.
+    for (auto &Ptr : getAttributePluginInstances())
+      if (Ptr->hasSpelling(Syntax, Name))
+        return 1;
+  }
 
   return 0;
 }
 
+int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
+                        const IdentifierInfo *Scope, const IdentifierInfo 
*Attr,
+                        const TargetInfo &Target, const LangOptions &LangOpts) 
{
+  return hasAttribute(Syntax, Scope, Attr, Target, LangOpts,
+                      /*CheckPlugins*/ true);
+}
+
 const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
   switch (Rule) {
 #define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract)                            
\
@@ -162,15 +172,6 @@ AttributeCommonInfo::getCXX11AttrArgsInfo(const 
IdentifierInfo *Name) {
 #undef CXX11_ATTR_ARGS_INFO
 }
 
-bool AttributeCommonInfo::hasCXX11Attr(const IdentifierInfo *Name,
-                                       const TargetInfo &Target,
-                                       const LangOptions &LangOpts) {
-  StringRef AttrName =
-      normalizeAttrName(Name, /*NormalizedScopeName*/ "", Syntax::AS_CXX11);
-  return hasAttributeImpl(Syntax::AS_CXX11, AttrName, /*ScopeName*/ "", Target,
-                          LangOpts) > 0;
-}
-
 std::string AttributeCommonInfo::getNormalizedFullName() const {
   return static_cast<std::string>(
       normalizeName(getAttrName(), getScopeName(), getSyntax()));
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 60766577393ccb..a29b73f97ab7e3 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -179,7 +179,8 @@ static bool isLanguageDefinedBuiltin(const SourceManager 
&SourceMgr,
 static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II) {
   const LangOptions &Lang = PP.getLangOpts();
   if (Lang.CPlusPlus &&
-      AttributeCommonInfo::hasCXX11Attr(II, PP.getTargetInfo(), Lang)) {
+      hasAttribute(AttributeCommonInfo::AS_CXX11, /* Scope*/ nullptr, II,
+                   PP.getTargetInfo(), Lang, /*CheckPlugins*/ false) > 0) {
     AttributeCommonInfo::AttrArgsInfo AttrArgsInfo =
         AttributeCommonInfo::getCXX11AttrArgsInfo(II);
     if (AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Required)

>From 2bbadddd431e2d9342bf51e6e552948f2dcb977a Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.taras...@outlook.com>
Date: Fri, 17 Jan 2025 20:41:05 +0200
Subject: [PATCH 7/7] update arg comment

---
 clang/lib/Basic/Attributes.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index d34ef2ebeb34d1..2035d4c0a5768b 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -76,7 +76,7 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
                         const IdentifierInfo *Scope, const IdentifierInfo 
*Attr,
                         const TargetInfo &Target, const LangOptions &LangOpts) 
{
   return hasAttribute(Syntax, Scope, Attr, Target, LangOpts,
-                      /*CheckPlugins*/ true);
+                      /*CheckPlugins=*/true);
 }
 
 const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to