clang 19.0.0git
AttributeCommonInfo.h
Go to the documentation of this file.
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
19
20namespace clang {
21
22class ASTRecordWriter;
23class IdentifierInfo;
24
26public:
27 /// The style used to specify an attribute.
28 enum Syntax {
29 /// __attribute__((...))
30 AS_GNU = 1,
31
32 /// [[...]]
34
35 /// [[...]]
37
38 /// __declspec(...)
40
41 /// [uuid("...")] class Foo
43
44 /// __ptr16, alignas(...), etc.
46
47 /// #pragma ...
49
50 // Note TableGen depends on the order above. Do not add or change the order
51 // without adding related code to TableGen/ClangAttrEmitter.cpp.
52 /// Context-sensitive version of a keyword attribute.
54
55 /// <vardecl> : <semantic>
57
58 /// The attibute has no source code manifestation and is only created
59 /// implicitly.
61 };
62 enum Kind {
63#define PARSED_ATTR(NAME) AT_##NAME,
64#include "clang/Sema/AttrParsedAttrList.inc"
65#undef PARSED_ATTR
69 };
70
71private:
72 const IdentifierInfo *AttrName = nullptr;
73 const IdentifierInfo *ScopeName = nullptr;
74 SourceRange AttrRange;
75 const SourceLocation ScopeLoc;
76 // Corresponds to the Kind enum.
77 LLVM_PREFERRED_TYPE(Kind)
78 unsigned AttrKind : 16;
79 /// Corresponds to the Syntax enum.
80 LLVM_PREFERRED_TYPE(Syntax)
81 unsigned SyntaxUsed : 4;
82 LLVM_PREFERRED_TYPE(bool)
83 unsigned SpellingIndex : 4;
84 LLVM_PREFERRED_TYPE(bool)
85 unsigned IsAlignas : 1;
86 LLVM_PREFERRED_TYPE(bool)
87 unsigned IsRegularKeywordAttribute : 1;
88
89protected:
90 static constexpr unsigned SpellingNotCalculated = 0xf;
91
92public:
93 /// Combines information about the source-code form of an attribute,
94 /// including its syntax and spelling.
95 class Form {
96 public:
97 constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas,
98 bool IsRegularKeywordAttribute)
99 : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex),
100 IsAlignas(IsAlignas),
101 IsRegularKeywordAttribute(IsRegularKeywordAttribute) {}
102 constexpr Form(tok::TokenKind Tok)
103 : SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated),
104 IsAlignas(Tok == tok::kw_alignas),
105 IsRegularKeywordAttribute(tok::isRegularKeywordAttribute(Tok)) {}
106
107 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
108 unsigned getSpellingIndex() const { return SpellingIndex; }
109 bool isAlignas() const { return IsAlignas; }
110 bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
111
112 static Form GNU() { return AS_GNU; }
113 static Form CXX11() { return AS_CXX11; }
114 static Form C23() { return AS_C23; }
115 static Form Declspec() { return AS_Declspec; }
116 static Form Microsoft() { return AS_Microsoft; }
117 static Form Keyword(bool IsAlignas, bool IsRegularKeywordAttribute) {
118 return Form(AS_Keyword, SpellingNotCalculated, IsAlignas,
119 IsRegularKeywordAttribute);
120 }
121 static Form Pragma() { return AS_Pragma; }
123 static Form HLSLSemantic() { return AS_HLSLSemantic; }
124 static Form Implicit() { return AS_Implicit; }
125
126 private:
127 constexpr Form(Syntax SyntaxUsed)
128 : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated),
129 IsAlignas(0), IsRegularKeywordAttribute(0) {}
130
131 LLVM_PREFERRED_TYPE(Syntax)
132 unsigned SyntaxUsed : 4;
133 unsigned SpellingIndex : 4;
134 LLVM_PREFERRED_TYPE(bool)
135 unsigned IsAlignas : 1;
136 LLVM_PREFERRED_TYPE(bool)
137 unsigned IsRegularKeywordAttribute : 1;
138 };
139
141 const IdentifierInfo *ScopeName, SourceRange AttrRange,
142 SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
143 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
144 ScopeLoc(ScopeLoc), AttrKind(AttrKind),
145 SyntaxUsed(FormUsed.getSyntax()),
146 SpellingIndex(FormUsed.getSpellingIndex()),
147 IsAlignas(FormUsed.isAlignas()),
148 IsRegularKeywordAttribute(FormUsed.isRegularKeywordAttribute()) {
149 assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
150 "Invalid syntax!");
151 }
152
154 const IdentifierInfo *ScopeName, SourceRange AttrRange,
155 SourceLocation ScopeLoc, Form FormUsed)
157 AttrName, ScopeName, AttrRange, ScopeLoc,
158 getParsedKind(AttrName, ScopeName, FormUsed.getSyntax()),
159 FormUsed) {}
160
162 Form FormUsed)
163 : AttributeCommonInfo(AttrName, nullptr, AttrRange, SourceLocation(),
164 FormUsed) {}
165
166 AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
167 : AttributeCommonInfo(nullptr, nullptr, AttrRange, SourceLocation(), K,
168 FormUsed) {}
169
172
173 Kind getParsedKind() const { return Kind(AttrKind); }
174 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
175 Form getForm() const {
176 return Form(getSyntax(), SpellingIndex, IsAlignas,
177 IsRegularKeywordAttribute);
178 }
179 const IdentifierInfo *getAttrName() const { return AttrName; }
180 void setAttrName(const IdentifierInfo *AttrNameII) { AttrName = AttrNameII; }
181 SourceLocation getLoc() const { return AttrRange.getBegin(); }
182 SourceRange getRange() const { return AttrRange; }
183 void setRange(SourceRange R) { AttrRange = R; }
184
185 bool hasScope() const { return ScopeName; }
186 const IdentifierInfo *getScopeName() const { return ScopeName; }
187 SourceLocation getScopeLoc() const { return ScopeLoc; }
188
189 /// Gets the normalized full name, which consists of both scope and name and
190 /// with surrounding underscores removed as appropriate (e.g.
191 /// __gnu__::__attr__ will be normalized to gnu::attr).
192 std::string getNormalizedFullName() const;
193
194 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
195 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
196
197 bool isGNUScope() const;
198 bool isClangScope() const;
199
200 bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11 || IsAlignas; }
201
202 bool isC23Attribute() const { return SyntaxUsed == AS_C23; }
203
204 bool isAlignas() const {
205 // FIXME: In the current state, the IsAlignas member variable is only true
206 // with the C++ `alignas` keyword but not `_Alignas`. The following
207 // expression works around the otherwise lost information so it will return
208 // true for `alignas` or `_Alignas` while still returning false for things
209 // like `__attribute__((aligned))`.
210 return (getParsedKind() == AT_Aligned && isKeywordAttribute());
211 }
212
213 /// The attribute is spelled [[]] in either C or C++ mode, including standard
214 /// attributes spelled with a keyword, like alignas.
216 return isCXX11Attribute() || isC23Attribute();
217 }
218
219 bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }
220
221 bool isKeywordAttribute() const {
222 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
223 }
224
225 bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
226
228 return SyntaxUsed == AS_ContextSensitiveKeyword;
229 }
230
232 assert((isAttributeSpellingListCalculated() || AttrName) &&
233 "Spelling cannot be found");
235 ? SpellingIndex
236 : calculateAttributeSpellingListIndex();
237 }
238 void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
239
240 static Kind getParsedKind(const IdentifierInfo *Name,
241 const IdentifierInfo *Scope, Syntax SyntaxUsed);
242
243private:
244 /// Get an index into the attribute spelling list
245 /// defined in Attr.td. This index is used by an attribute
246 /// to pretty print itself.
247 unsigned calculateAttributeSpellingListIndex() const;
248
250 // Used exclusively by ASTDeclWriter to get the raw spelling list state.
251 unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
252
253protected:
255 return SpellingIndex != SpellingNotCalculated;
256 }
257};
258
260 switch (Kind) {
261 default:
262 return false;
263#define KEYWORD_ATTRIBUTE(NAME, HASARG, ...) \
264 case tok::kw_##NAME: \
265 return HASARG;
266#include "clang/Basic/RegularKeywordAttrInfo.inc"
267#undef KEYWORD_ATTRIBUTE
268 }
269}
270
271} // namespace clang
272
273#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
#define V(N, I)
Definition: ASTContext.h:3266
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TokenKind enum and support functions.
An object for streaming information to a record.
Combines information about the source-code form of an attribute, including its syntax and spelling.
static Form Keyword(bool IsAlignas, bool IsRegularKeywordAttribute)
constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas, bool IsRegularKeywordAttribute)
constexpr Form(tok::TokenKind Tok)
SourceLocation getScopeLoc() const
bool isAttributeSpellingListCalculated() const
AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange, Form FormUsed)
void setAttributeSpellingListIndex(unsigned V)
std::string getNormalizedFullName() const
Gets the normalized full name, which consists of both scope and name and with surrounding underscores...
Definition: Attributes.cpp:151
Syntax
The style used to specify an attribute.
@ AS_Keyword
__ptr16, alignas(...), etc.
@ AS_ContextSensitiveKeyword
Context-sensitive version of a keyword attribute.
@ AS_HLSLSemantic
<vardecl> : <semantic>
@ AS_Implicit
The attibute has no source code manifestation and is only created implicitly.
@ AS_Microsoft
[uuid("...")] class Foo
AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
AttributeCommonInfo(const IdentifierInfo *AttrName, const IdentifierInfo *ScopeName, SourceRange AttrRange, SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
void setAttrName(const IdentifierInfo *AttrNameII)
unsigned getAttributeSpellingListIndex() const
const IdentifierInfo * getScopeName() const
bool isContextSensitiveKeywordAttribute() const
AttributeCommonInfo(AttributeCommonInfo &&)=default
SourceLocation getLoc() const
const IdentifierInfo * getAttrName() const
AttributeCommonInfo(const IdentifierInfo *AttrName, const IdentifierInfo *ScopeName, SourceRange AttrRange, SourceLocation ScopeLoc, Form FormUsed)
AttributeCommonInfo(const AttributeCommonInfo &)=default
static constexpr unsigned SpellingNotCalculated
bool isStandardAttributeSyntax() const
The attribute is spelled [[]] in either C or C++ mode, including standard attributes spelled with a k...
One of these records is kept for each identifier that is lexed.
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition: TokenKinds.h:25
The JSON file list parser is used to communicate input to InstallAPI.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)