[llvm] 4018317 - [Clang] restrict use of attribute names reserved by the C++ standard (#106036)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 23 11:17:03 PST 2025
Author: Oleksandr T.
Date: 2025-01-23T21:16:59+02:00
New Revision: 4018317407006b2c632fbb75729de624a2426439
URL: https://github.com/llvm/llvm-project/commit/4018317407006b2c632fbb75729de624a2426439
DIFF: https://github.com/llvm/llvm-project/commit/4018317407006b2c632fbb75729de624a2426439.diff
LOG: [Clang] restrict use of attribute names reserved by the C++ standard (#106036)
Fixes #92196
https://eel.is/c++draft/macro.names#2
> A translation unit shall not #define or #undef names lexically
identical to keywords, to the identifiers listed in Table
[4](https://eel.is/c++draft/lex.name#tab:lex.name.special), or to the
[attribute-token](https://eel.is/c++draft/dcl.attr.grammar#nt:attribute-token)s
described in [[dcl.attr]](https://eel.is/c++draft/dcl.attr), except that
the names likely and unlikely may be defined as function-like macros
([[cpp.replace]](https://eel.is/c++draft/cpp.replace))[.](https://eel.is/c++draft/macro.names#2.sentence-1)
Added:
clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/AttributeCommonInfo.h
clang/include/clang/Basic/Attributes.h
clang/include/clang/Basic/CMakeLists.txt
clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticLexKinds.td
clang/include/clang/Lex/Preprocessor.h
clang/include/clang/Sema/CMakeLists.txt
clang/lib/Basic/Attributes.cpp
clang/lib/Lex/PPDirectives.cpp
clang/utils/TableGen/ClangAttrEmitter.cpp
clang/utils/TableGen/TableGen.cpp
clang/utils/TableGen/TableGenBackends.h
llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn
llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn
utils/bazel/llvm-project-overlay/clang/BUILD.bazel
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5d4b182f29afa0..bd74abeb5dd68a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -807,6 +807,8 @@ Improvements to Clang's diagnostics
- Clang now emits a ``-Wignored-qualifiers`` diagnostic when a base class includes cv-qualifiers (#GH55474).
+- 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..4af5a8fd1852cf 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -61,13 +61,18 @@ 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,
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/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/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 56c27bacdb20b8..4103d2753abc5f 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -36,6 +36,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
@@ -53,6 +58,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/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index b0ad76026fdb35..209792f851b6ae 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">;
@@ -935,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.
//
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 959376b0847216..4bcef23ccce169 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -407,6 +407,9 @@ 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">, DefaultIgnore,
+ 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/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index fa26cc584b724a..2035d4c0a5768b 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) \
@@ -151,6 +161,17 @@ AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
}
+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>(AttrName)
+#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 a23ad40884f249..a29b73f97ab7e3 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,22 @@ 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::AS_CXX11, /* Scope*/ nullptr, II,
+ PP.getTargetInfo(), Lang, /*CheckPlugins*/ false) > 0) {
+ AttributeCommonInfo::AttrArgsInfo AttrArgsInfo =
+ AttributeCommonInfo::getCXX11AttrArgsInfo(II);
+ if (AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Required)
+ return PP.isNextPPTokenLParen();
+
+ return !PP.isNextPPTokenLParen() ||
+ AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Optional;
+ }
+ return false;
+}
+
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
const LangOptions &Lang = PP.getLangOpts();
StringRef Text = II->getName();
@@ -182,6 +201,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 +211,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 +388,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-attrs-cxx11.cpp b/clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp
new file mode 100644
index 00000000000000..ab48f1b46df989
--- /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 -Wreserved-attribute-identifier -fsyntax-only -verify %s -DTEST1
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -Wreserved-attribute-identifier -fsyntax-only -verify %s -DTEST2
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -Wreserved-attribute-identifier -fsyntax-only -verify %s -DTEST3
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -Wreserved-attribute-identifier -fsyntax-only -verify %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/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 8b8eadbe7f7e54..569d7a6a3ac8b7 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -69,6 +69,7 @@ enum ActionType {
GenClangOpenCLBuiltins,
GenClangOpenCLBuiltinHeader,
GenClangOpenCLBuiltinTests,
+ GenCXX11AttributeInfo,
GenArmNeon,
GenArmFP16,
GenArmBF16,
@@ -228,6 +229,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"),
@@ -336,6 +339,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 0448c94de08e3d..03ed3dad93631b 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,
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 3b72177ee5d7c3..306ef0adda7088 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 e3f4fab2c3fdb9..cd452cb6898db5 100644
--- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
@@ -572,6 +572,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",
@@ -1135,10 +1139,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",
@@ -1174,7 +1174,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",
More information about the llvm-commits
mailing list