/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Attributes.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "clang/Basic/Attributes.h" |
2 | | #include "clang/Basic/AttrSubjectMatchRules.h" |
3 | | #include "clang/Basic/AttributeCommonInfo.h" |
4 | | #include "clang/Basic/IdentifierTable.h" |
5 | | #include "llvm/ADT/StringSwitch.h" |
6 | | using namespace clang; |
7 | | |
8 | | int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope, |
9 | | const IdentifierInfo *Attr, const TargetInfo &Target, |
10 | 64.0k | const LangOptions &LangOpts) { |
11 | 64.0k | StringRef Name = Attr->getName(); |
12 | | // Normalize the attribute name, __foo__ becomes foo. |
13 | 64.0k | if (Name.size() >= 4 && Name.startswith("__")64.0k && Name.endswith("__")6.45k ) |
14 | 6.45k | Name = Name.substr(2, Name.size() - 4); |
15 | | |
16 | | // Normalize the scope name, but only for gnu and clang attributes. |
17 | 64.0k | StringRef ScopeName = Scope ? Scope->getName()2.86k : ""61.1k ; |
18 | 64.0k | if (ScopeName == "__gnu__") |
19 | 5 | ScopeName = "gnu"; |
20 | 64.0k | else if (ScopeName == "_Clang") |
21 | 13 | ScopeName = "clang"; |
22 | | |
23 | | // As a special case, look for the omp::sequence and omp::directive |
24 | | // attributes. We support those, but not through the typical attribute |
25 | | // machinery that goes through TableGen. We support this in all OpenMP modes |
26 | | // so long as double square brackets are enabled. |
27 | 64.0k | if (LangOpts.OpenMP && LangOpts.DoubleSquareBracketAttributes676 && |
28 | 64.0k | ScopeName == "omp"676 ) |
29 | 658 | return (Name == "directive" || Name == "sequence"121 ) ? 1652 : 06 ; |
30 | | |
31 | 64.0k | #include "clang/Basic/AttrHasAttributeImpl.inc" |
32 | | |
33 | 938 | return 0; |
34 | 63.3k | } |
35 | | |
36 | 140 | const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) { |
37 | 140 | switch (Rule) { |
38 | 0 | #define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract) \ |
39 | 140 | case attr::NAME: \ |
40 | 140 | return SPELLING; |
41 | 140 | #include "clang/Basic/AttrSubMatchRulesList.inc"0 |
42 | 140 | } |
43 | 0 | llvm_unreachable("Invalid subject match rule"); |
44 | 0 | } |
45 | | |
46 | | static StringRef |
47 | | normalizeAttrScopeName(const IdentifierInfo *Scope, |
48 | 128M | AttributeCommonInfo::Syntax SyntaxUsed) { |
49 | 128M | if (!Scope) |
50 | 128M | return ""; |
51 | | |
52 | | // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name |
53 | | // to be "clang". |
54 | 3.39k | StringRef ScopeName = Scope->getName(); |
55 | 3.39k | if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 || |
56 | 3.39k | SyntaxUsed == AttributeCommonInfo::AS_C2x176 ) { |
57 | 3.39k | if (ScopeName == "__gnu__") |
58 | 13 | ScopeName = "gnu"; |
59 | 3.38k | else if (ScopeName == "_Clang") |
60 | 22 | ScopeName = "clang"; |
61 | 3.39k | } |
62 | 3.39k | return ScopeName; |
63 | 128M | } |
64 | | |
65 | | static StringRef normalizeAttrName(const IdentifierInfo *Name, |
66 | | StringRef NormalizedScopeName, |
67 | 128M | AttributeCommonInfo::Syntax SyntaxUsed) { |
68 | | // Normalize the attribute name, __foo__ becomes foo. This is only allowable |
69 | | // for GNU attributes, and attributes using the double square bracket syntax. |
70 | 128M | bool ShouldNormalize = |
71 | 128M | SyntaxUsed == AttributeCommonInfo::AS_GNU || |
72 | 128M | (3.84M (3.84M SyntaxUsed == AttributeCommonInfo::AS_CXX113.84M || |
73 | 3.84M | SyntaxUsed == AttributeCommonInfo::AS_C2x3.83M ) && |
74 | 3.84M | (16.9k NormalizedScopeName.empty()16.9k || NormalizedScopeName == "gnu"3.39k || |
75 | 16.9k | NormalizedScopeName == "clang"2.98k )); |
76 | 128M | StringRef AttrName = Name->getName(); |
77 | 128M | if (ShouldNormalize && AttrName.size() >= 4124M && AttrName.startswith("__")124M && |
78 | 128M | AttrName.endswith("__")110M ) |
79 | 55.4M | AttrName = AttrName.slice(2, AttrName.size() - 2); |
80 | | |
81 | 128M | return AttrName; |
82 | 128M | } |
83 | | |
84 | 14.8k | bool AttributeCommonInfo::isGNUScope() const { |
85 | 14.8k | return ScopeName && (762 ScopeName->isStr("gnu")762 || ScopeName->isStr("__gnu__")566 ); |
86 | 14.8k | } |
87 | | |
88 | | #include "clang/Sema/AttrParsedAttrKinds.inc" |
89 | | |
90 | | static SmallString<64> normalizeName(const IdentifierInfo *Name, |
91 | | const IdentifierInfo *Scope, |
92 | 128M | AttributeCommonInfo::Syntax SyntaxUsed) { |
93 | 128M | StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed); |
94 | 128M | StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed); |
95 | | |
96 | 128M | SmallString<64> FullName = ScopeName; |
97 | 128M | if (!ScopeName.empty()) { |
98 | 2.64k | assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 || |
99 | 2.64k | SyntaxUsed == AttributeCommonInfo::AS_C2x); |
100 | 0 | FullName += "::"; |
101 | 2.64k | } |
102 | 0 | FullName += AttrName; |
103 | | |
104 | 128M | return FullName; |
105 | 128M | } |
106 | | |
107 | | AttributeCommonInfo::Kind |
108 | | AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name, |
109 | | const IdentifierInfo *ScopeName, |
110 | 128M | Syntax SyntaxUsed) { |
111 | 128M | return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed); |
112 | 128M | } |
113 | | |
114 | 192 | std::string AttributeCommonInfo::getNormalizedFullName() const { |
115 | 192 | return static_cast<std::string>( |
116 | 192 | normalizeName(getAttrName(), getScopeName(), getSyntax())); |
117 | 192 | } |
118 | | |
119 | 398k | unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const { |
120 | | // Both variables will be used in tablegen generated |
121 | | // attribute spell list index matching code. |
122 | 398k | auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax()); |
123 | 398k | StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax); |
124 | 398k | StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax); |
125 | | |
126 | 398k | #include "clang/Sema/AttrSpellingListIndex.inc"0 |
127 | 398k | } |