Skip to content

Commit d89c879

Browse files
committed
handle function like attr names
1 parent 593cc60 commit d89c879

File tree

10 files changed

+168
-73
lines changed

10 files changed

+168
-73
lines changed

clang/include/clang/Basic/AttributeCommonInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ class AttributeCommonInfo {
6868
UnknownAttribute,
6969
};
7070
enum class Scope { NONE, CLANG, GNU, MSVC, OMP, HLSL, GSL, RISCV };
71+
enum class AttrArgsInfo {
72+
None,
73+
Optional,
74+
Required,
75+
};
7176

7277
private:
7378
const IdentifierInfo *AttrName = nullptr;
@@ -241,6 +246,8 @@ class AttributeCommonInfo {
241246
static Kind getParsedKind(const IdentifierInfo *Name,
242247
const IdentifierInfo *Scope, Syntax SyntaxUsed);
243248

249+
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name);
250+
244251
private:
245252
/// Get an index into the attribute spelling list
246253
/// defined in Attr.td. This index is used by an attribute

clang/include/clang/Basic/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ clang_tablegen(AttrHasAttributeImpl.inc -gen-clang-attr-has-attribute-impl
5353
TARGET ClangAttrHasAttributeImpl
5454
)
5555

56+
clang_tablegen(CXX11AttributeInfo.inc -gen-cxx11-attribute-info
57+
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
58+
SOURCE Attr.td
59+
TARGET CXX11AttributeInfo
60+
)
61+
5662
clang_tablegen(Builtins.inc -gen-clang-builtins
5763
SOURCE Builtins.td
5864
TARGET ClangBuiltins)

clang/lib/Basic/Attributes.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,16 @@ AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
151151
return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
152152
}
153153

154+
AttributeCommonInfo::AttrArgsInfo
155+
AttributeCommonInfo::getCXX11AttrArgsInfo(const IdentifierInfo *Name) {
156+
#define CXX11_ATTR_ARGS_INFO
157+
return llvm::StringSwitch<AttributeCommonInfo::AttrArgsInfo>(
158+
normalizeName(Name, /*Scope*/ nullptr, Syntax::AS_CXX11))
159+
#include "clang/Basic/CXX11AttributeInfo.inc"
160+
.Default(AttributeCommonInfo::AttrArgsInfo::None);
161+
#undef CXX11_ATTR_ARGS_INFO
162+
}
163+
154164
std::string AttributeCommonInfo::getNormalizedFullName() const {
155165
return static_cast<std::string>(
156166
normalizeName(getAttrName(), getScopeName(), getSyntax()));

clang/lib/Lex/PPDirectives.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,13 @@ static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II) {
181181
if (Lang.CPlusPlus &&
182182
hasAttribute(AttributeCommonInfo::Syntax::AS_CXX11, /*Scope*/ nullptr, II,
183183
PP.getTargetInfo(), Lang) > 0) {
184-
AttributeCommonInfo::Kind AttrKind = AttributeCommonInfo::getParsedKind(
185-
II, /*Scope*/ nullptr, AttributeCommonInfo::Syntax::AS_CXX11);
186-
return !((AttrKind == AttributeCommonInfo::Kind::AT_Likely ||
187-
AttrKind == AttributeCommonInfo::Kind::AT_Unlikely) &&
188-
PP.isNextPPTokenLParen());
184+
AttributeCommonInfo::AttrArgsInfo AttrArgsInfo =
185+
AttributeCommonInfo::getCXX11AttrArgsInfo(II);
186+
if (AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Required)
187+
return PP.isNextPPTokenLParen();
188+
189+
return !PP.isNextPPTokenLParen() ||
190+
AttrArgsInfo == AttributeCommonInfo::AttrArgsInfo::Optional;
189191
}
190192
return false;
191193
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify -pedantic %s -DTEST1
2+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify -pedantic %s -DTEST2
3+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify -pedantic %s -DTEST3
4+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -fsyntax-only -verify -pedantic %s -DTEST4
5+
6+
#ifdef TEST1
7+
8+
#define assume
9+
#undef assume
10+
11+
#define noreturn // expected-warning {{noreturn is a reserved attribute identifier}}
12+
#undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}}
13+
14+
#define carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}}
15+
#undef carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}}
16+
17+
#define deprecated // expected-warning {{deprecated is a reserved attribute identifier}}
18+
#undef deprecated // expected-warning {{deprecated is a reserved attribute identifier}}
19+
20+
#define fallthrough // expected-warning {{fallthrough is a reserved attribute identifier}}
21+
#undef fallthrough // expected-warning {{fallthrough is a reserved attribute identifier}}
22+
23+
#define likely // expected-warning {{likely is a reserved attribute identifier}}
24+
#undef likely // expected-warning {{likely is a reserved attribute identifier}}
25+
26+
#define no_unique_address // expected-warning {{no_unique_address is a reserved attribute identifier}}
27+
#undef no_unique_address // expected-warning {{no_unique_address is a reserved attribute identifier}}
28+
29+
#define unlikely // expected-warning {{unlikely is a reserved attribute identifier}}
30+
#undef unlikely // expected-warning {{unlikely is a reserved attribute identifier}}
31+
32+
#define maybe_unused // expected-warning {{maybe_unused is a reserved attribute identifier}}
33+
#undef maybe_unused // expected-warning {{maybe_unused is a reserved attribute identifier}}
34+
35+
#define nodiscard // expected-warning {{nodiscard is a reserved attribute identifier}}
36+
#undef nodiscard // expected-warning {{nodiscard is a reserved attribute identifier}}
37+
38+
#elif TEST2
39+
40+
#define assume "test"
41+
#undef assume
42+
43+
#define noreturn "test" // expected-warning {{noreturn is a reserved attribute identifier}}
44+
#undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}}
45+
46+
#define carries_dependency "test" // expected-warning {{carries_dependency is a reserved attribute identifier}}
47+
#undef carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}}
48+
49+
#define deprecated "test" // expected-warning {{deprecated is a reserved attribute identifier}}
50+
#undef deprecated // expected-warning {{deprecated is a reserved attribute identifier}}
51+
52+
#define fallthrough "test" // expected-warning {{fallthrough is a reserved attribute identifier}}
53+
#undef fallthrough // expected-warning {{fallthrough is a reserved attribute identifier}}
54+
55+
#define likely "test" // expected-warning {{likely is a reserved attribute identifier}}
56+
#undef likely // expected-warning {{likely is a reserved attribute identifier}}
57+
58+
#define no_unique_address "test" // expected-warning {{no_unique_address is a reserved attribute identifier}}
59+
#undef no_unique_address // expected-warning {{no_unique_address is a reserved attribute identifier}}
60+
61+
#define unlikely "test" // expected-warning {{unlikely is a reserved attribute identifier}}
62+
#undef unlikely // expected-warning {{unlikely is a reserved attribute identifier}}
63+
64+
#define maybe_unused "test" // expected-warning {{maybe_unused is a reserved attribute identifier}}
65+
#undef maybe_unused // expected-warning {{maybe_unused is a reserved attribute identifier}}
66+
67+
#define nodiscard "test" // expected-warning {{nodiscard is a reserved attribute identifier}}
68+
#undef nodiscard // expected-warning {{nodiscard is a reserved attribute identifier}}
69+
70+
#elif TEST3
71+
72+
#define assume() "test" // expected-warning {{assume is a reserved attribute identifier}}
73+
#define deprecated() "test" // expected-warning {{deprecated is a reserved attribute identifier}}
74+
#define nodiscard() "test" // expected-warning {{nodiscard is a reserved attribute identifier}}
75+
#define noreturn() "test"
76+
#define carries_dependency() "test"
77+
#define fallthrough() "test"
78+
#define likely() "test"
79+
#define no_unique_address() "test"
80+
#define unlikely() "test"
81+
#define maybe_unused() "test"
82+
83+
#elif TEST4
84+
85+
#define assume() // expected-warning {{assume is a reserved attribute identifier}}
86+
#define deprecated() // expected-warning {{deprecated is a reserved attribute identifier}}
87+
#define nodiscard() // expected-warning {{nodiscard is a reserved attribute identifier}}
88+
#define noreturn()
89+
#define carries_dependency()
90+
#define fallthrough()
91+
#define likely()
92+
#define no_unique_address()
93+
#define unlikely()
94+
#define maybe_unused()
95+
96+
#else
97+
98+
#error Unknown test
99+
100+
#endif

clang/test/Preprocessor/macro-reserved-attrs1.cpp

Lines changed: 0 additions & 34 deletions
This file was deleted.

clang/test/Preprocessor/macro-reserved-attrs2.cpp

Lines changed: 0 additions & 34 deletions
This file was deleted.

clang/utils/TableGen/ClangAttrEmitter.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3743,6 +3743,36 @@ void EmitClangRegularKeywordAttributeInfo(const RecordKeeper &Records,
37433743
OS << "#undef KEYWORD_ATTRIBUTE\n";
37443744
}
37453745

3746+
void EmitCXX11AttributeInfo(const RecordKeeper &Records, raw_ostream &OS) {
3747+
OS << "#if defined(CXX11_ATTR_ARGS_INFO)\n";
3748+
for (auto *R : Records.getAllDerivedDefinitions("Attr")) {
3749+
for (const FlattenedSpelling &SI : GetFlattenedSpellings(*R)) {
3750+
if (SI.variety() == "CXX11" && SI.nameSpace().empty()) {
3751+
unsigned RequiredArgs = 0;
3752+
unsigned OptionalArgs = 0;
3753+
for (const auto *Arg : R->getValueAsListOfDefs("Args")) {
3754+
if (Arg->getValueAsBit("Fake"))
3755+
continue;
3756+
3757+
if (Arg->getValueAsBit("Optional"))
3758+
OptionalArgs++;
3759+
else
3760+
RequiredArgs++;
3761+
}
3762+
OS << ".Case(\"" << SI.getSpellingRecord().getValueAsString("Name")
3763+
<< "\","
3764+
<< "AttributeCommonInfo::AttrArgsInfo::"
3765+
<< (RequiredArgs ? "Required"
3766+
: OptionalArgs ? "Optional"
3767+
: "None")
3768+
<< ")"
3769+
<< "\n";
3770+
}
3771+
}
3772+
}
3773+
OS << "#endif // CXX11_ATTR_ARGS_INFO\n";
3774+
}
3775+
37463776
// Emits the list of spellings for attributes.
37473777
void EmitClangAttrHasAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {
37483778
emitSourceFileHeader("Code to implement the __has_attribute logic", OS,

clang/utils/TableGen/TableGen.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ enum ActionType {
6868
GenClangOpenCLBuiltins,
6969
GenClangOpenCLBuiltinHeader,
7070
GenClangOpenCLBuiltinTests,
71+
GenCXX11AttributeInfo,
7172
GenArmNeon,
7273
GenArmFP16,
7374
GenArmBF16,
@@ -225,6 +226,8 @@ cl::opt<ActionType> Action(
225226
"Generate OpenCL builtin header"),
226227
clEnumValN(GenClangOpenCLBuiltinTests, "gen-clang-opencl-builtin-tests",
227228
"Generate OpenCL builtin declaration tests"),
229+
clEnumValN(GenCXX11AttributeInfo, "gen-cxx11-attribute-info",
230+
"Generate CXX11 attributes info"),
228231
clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for clang"),
229232
clEnumValN(GenArmFP16, "gen-arm-fp16", "Generate arm_fp16.h for clang"),
230233
clEnumValN(GenArmBF16, "gen-arm-bf16", "Generate arm_bf16.h for clang"),
@@ -333,6 +336,9 @@ bool ClangTableGenMain(raw_ostream &OS, const RecordKeeper &Records) {
333336
case GenClangAttrSubjectMatchRulesParserStringSwitches:
334337
EmitClangAttrSubjectMatchRulesParserStringSwitches(Records, OS);
335338
break;
339+
case GenCXX11AttributeInfo:
340+
EmitCXX11AttributeInfo(Records, OS);
341+
break;
336342
case GenClangAttrImpl:
337343
EmitClangAttrImpl(Records, OS);
338344
break;

clang/utils/TableGen/TableGenBackends.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ void EmitClangAttrParserStringSwitches(const llvm::RecordKeeper &Records,
4949
llvm::raw_ostream &OS);
5050
void EmitClangAttrSubjectMatchRulesParserStringSwitches(
5151
const llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
52+
void EmitCXX11AttributeInfo(const llvm::RecordKeeper &Records,
53+
llvm::raw_ostream &OS);
5254
void EmitClangAttrClass(const llvm::RecordKeeper &Records,
5355
llvm::raw_ostream &OS);
5456
void EmitClangAttrImpl(const llvm::RecordKeeper &Records,

0 commit comments

Comments
 (0)