1 | //======- AttributeCommonInfo.h - Base info about Attributes-----*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the AttributeCommonInfo type, which is the base for a |
10 | // ParsedAttr and is used by Attr as a way to share info between the two. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H |
15 | #define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H |
16 | #include "clang/Basic/SourceLocation.h" |
17 | |
18 | namespace clang { |
19 | class IdentifierInfo; |
20 | class ASTRecordWriter; |
21 | |
22 | class AttributeCommonInfo { |
23 | public: |
24 | /// The style used to specify an attribute. |
25 | enum Syntax { |
26 | /// __attribute__((...)) |
27 | AS_GNU, |
28 | |
29 | /// [[...]] |
30 | AS_CXX11, |
31 | |
32 | /// [[...]] |
33 | AS_C2x, |
34 | |
35 | /// __declspec(...) |
36 | AS_Declspec, |
37 | |
38 | /// [uuid("...")] class Foo |
39 | AS_Microsoft, |
40 | |
41 | /// __ptr16, alignas(...), etc. |
42 | AS_Keyword, |
43 | |
44 | /// #pragma ... |
45 | AS_Pragma, |
46 | |
47 | // Note TableGen depends on the order above. Do not add or change the order |
48 | // without adding related code to TableGen/ClangAttrEmitter.cpp. |
49 | /// Context-sensitive version of a keyword attribute. |
50 | AS_ContextSensitiveKeyword, |
51 | }; |
52 | enum Kind { |
53 | #define PARSED_ATTR(NAME) AT_##NAME, |
54 | #include "clang/Sema/AttrParsedAttrList.inc" |
55 | #undef PARSED_ATTR |
56 | NoSemaHandlerAttribute, |
57 | IgnoredAttribute, |
58 | UnknownAttribute, |
59 | }; |
60 | |
61 | private: |
62 | const IdentifierInfo *AttrName = nullptr; |
63 | const IdentifierInfo *ScopeName = nullptr; |
64 | SourceRange AttrRange; |
65 | const SourceLocation ScopeLoc; |
66 | // Corresponds to the Kind enum. |
67 | unsigned AttrKind : 16; |
68 | /// Corresponds to the Syntax enum. |
69 | unsigned SyntaxUsed : 3; |
70 | unsigned SpellingIndex : 4; |
71 | |
72 | protected: |
73 | static constexpr unsigned SpellingNotCalculated = 0xf; |
74 | |
75 | public: |
76 | AttributeCommonInfo(SourceRange AttrRange) |
77 | : AttrRange(AttrRange), ScopeLoc(), AttrKind(0), SyntaxUsed(0), |
78 | SpellingIndex(SpellingNotCalculated) {} |
79 | |
80 | AttributeCommonInfo(SourceLocation AttrLoc) |
81 | : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0), |
82 | SpellingIndex(SpellingNotCalculated) {} |
83 | |
84 | AttributeCommonInfo(const IdentifierInfo *AttrName, |
85 | const IdentifierInfo *ScopeName, SourceRange AttrRange, |
86 | SourceLocation ScopeLoc, Syntax SyntaxUsed) |
87 | : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange), |
88 | ScopeLoc(ScopeLoc), |
89 | AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)), |
90 | SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {} |
91 | |
92 | AttributeCommonInfo(const IdentifierInfo *AttrName, |
93 | const IdentifierInfo *ScopeName, SourceRange AttrRange, |
94 | SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed) |
95 | : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange), |
96 | ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed), |
97 | SpellingIndex(SpellingNotCalculated) {} |
98 | |
99 | AttributeCommonInfo(const IdentifierInfo *AttrName, |
100 | const IdentifierInfo *ScopeName, SourceRange AttrRange, |
101 | SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed, |
102 | unsigned Spelling) |
103 | : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange), |
104 | ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed), |
105 | SpellingIndex(Spelling) {} |
106 | |
107 | AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange, |
108 | Syntax SyntaxUsed) |
109 | : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange), |
110 | ScopeLoc(), AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)), |
111 | SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {} |
112 | |
113 | AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed) |
114 | : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(), |
115 | AttrKind(K), SyntaxUsed(SyntaxUsed), |
116 | SpellingIndex(SpellingNotCalculated) {} |
117 | |
118 | AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed, |
119 | unsigned Spelling) |
120 | : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(), |
121 | AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {} |
122 | |
123 | AttributeCommonInfo(AttributeCommonInfo &&) = default; |
124 | AttributeCommonInfo(const AttributeCommonInfo &) = default; |
125 | |
126 | Kind getParsedKind() const { return Kind(AttrKind); } |
127 | Syntax getSyntax() const { return Syntax(SyntaxUsed); } |
128 | const IdentifierInfo *getAttrName() const { return AttrName; } |
129 | SourceLocation getLoc() const { return AttrRange.getBegin(); } |
130 | SourceRange getRange() const { return AttrRange; } |
131 | void setRange(SourceRange R) { AttrRange = R; } |
132 | |
133 | bool hasScope() const { return ScopeName; } |
134 | const IdentifierInfo *getScopeName() const { return ScopeName; } |
135 | SourceLocation getScopeLoc() const { return ScopeLoc; } |
136 | |
137 | /// Gets the normalized full name, which consists of both scope and name and |
138 | /// with surrounding underscores removed as appropriate (e.g. |
139 | /// __gnu__::__attr__ will be normalized to gnu::attr). |
140 | std::string getNormalizedFullName() const; |
141 | |
142 | bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } |
143 | bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; } |
144 | |
145 | bool isGNUScope() const; |
146 | |
147 | bool isAlignasAttribute() const { |
148 | // FIXME: Use a better mechanism to determine this. |
149 | return getParsedKind() == AT_Aligned && isKeywordAttribute(); |
150 | } |
151 | |
152 | bool isCXX11Attribute() const { |
153 | return SyntaxUsed == AS_CXX11 || isAlignasAttribute(); |
154 | } |
155 | |
156 | bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; } |
157 | |
158 | bool isKeywordAttribute() const { |
159 | return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword; |
160 | } |
161 | |
162 | bool isContextSensitiveKeywordAttribute() const { |
163 | return SyntaxUsed == AS_ContextSensitiveKeyword; |
164 | } |
165 | |
166 | unsigned getAttributeSpellingListIndex() const { |
167 | assert((isAttributeSpellingListCalculated() || AttrName) && |
168 | "Spelling cannot be found" ); |
169 | return isAttributeSpellingListCalculated() |
170 | ? SpellingIndex |
171 | : calculateAttributeSpellingListIndex(); |
172 | } |
173 | void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; } |
174 | |
175 | static Kind getParsedKind(const IdentifierInfo *Name, |
176 | const IdentifierInfo *Scope, Syntax SyntaxUsed); |
177 | |
178 | private: |
179 | /// Get an index into the attribute spelling list |
180 | /// defined in Attr.td. This index is used by an attribute |
181 | /// to pretty print itself. |
182 | unsigned calculateAttributeSpellingListIndex() const; |
183 | |
184 | friend class clang::ASTRecordWriter; |
185 | // Used exclusively by ASTDeclWriter to get the raw spelling list state. |
186 | unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; } |
187 | |
188 | protected: |
189 | bool isAttributeSpellingListCalculated() const { |
190 | return SpellingIndex != SpellingNotCalculated; |
191 | } |
192 | }; |
193 | } // namespace clang |
194 | |
195 | #endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H |
196 | |