clang 20.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> : <annotation>
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 enum class Scope { NONE, CLANG, GNU, MSVC, OMP, HLSL, GSL, RISCV };
71
72private:
73 const IdentifierInfo *AttrName = nullptr;
74 const IdentifierInfo *ScopeName = nullptr;
75 SourceRange AttrRange;
76 const SourceLocation ScopeLoc;
77 // Corresponds to the Kind enum.
78 LLVM_PREFERRED_TYPE(Kind)
79 unsigned AttrKind : 16;
80 /// Corresponds to the Syntax enum.
81 LLVM_PREFERRED_TYPE(Syntax)
82 unsigned SyntaxUsed : 4;
83 LLVM_PREFERRED_TYPE(bool)
84 unsigned SpellingIndex : 4;
85 LLVM_PREFERRED_TYPE(bool)
86 unsigned IsAlignas : 1;
87 LLVM_PREFERRED_TYPE(bool)
88 unsigned IsRegularKeywordAttribute : 1;
89
90protected:
91 static constexpr unsigned SpellingNotCalculated = 0xf;
92
93public:
94 /// Combines information about the source-code form of an attribute,
95 /// including its syntax and spelling.
96 class Form {
97 public:
98 constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas,
99 bool IsRegularKeywordAttribute)
100 : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex),
101 IsAlignas(IsAlignas),
102 IsRegularKeywordAttribute(IsRegularKeywordAttribute) {}
103 constexpr Form(tok::TokenKind Tok)
104 : SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated),
105 IsAlignas(Tok == tok::kw_alignas),
106 IsRegularKeywordAttribute(tok::isRegularKeywordAttribute(Tok)) {}
107
108 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
109 unsigned getSpellingIndex() const { return SpellingIndex; }
110 bool isAlignas() const { return IsAlignas; }
111 bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
112
113 static Form GNU() { return AS_GNU; }
114 static Form CXX11() { return AS_CXX11; }
115 static Form C23() { return AS_C23; }
116 static Form Declspec() { return AS_Declspec; }
117 static Form Microsoft() { return AS_Microsoft; }
118 static Form Keyword(bool IsAlignas, bool IsRegularKeywordAttribute) {
119 return Form(AS_Keyword, SpellingNotCalculated, IsAlignas,
120 IsRegularKeywordAttribute);
121 }
122 static Form Pragma() { return AS_Pragma; }
125 static Form Implicit() { return AS_Implicit; }
126
127 private:
128 constexpr Form(Syntax SyntaxUsed)
129 : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated),
130 IsAlignas(0), IsRegularKeywordAttribute(0) {}
131
132 LLVM_PREFERRED_TYPE(Syntax)
133 unsigned SyntaxUsed : 4;
134 unsigned SpellingIndex : 4;
135 LLVM_PREFERRED_TYPE(bool)
136 unsigned IsAlignas : 1;
137 LLVM_PREFERRED_TYPE(bool)
138 unsigned IsRegularKeywordAttribute : 1;
139 };
140
142 const IdentifierInfo *ScopeName, SourceRange AttrRange,
143 SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
144 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
145 ScopeLoc(ScopeLoc), AttrKind(AttrKind),
146 SyntaxUsed(FormUsed.getSyntax()),
147 SpellingIndex(FormUsed.getSpellingIndex()),
148 IsAlignas(FormUsed.isAlignas()),
149 IsRegularKeywordAttribute(FormUsed.isRegularKeywordAttribute()) {
150 assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
151 "Invalid syntax!");
152 }
153
155 const IdentifierInfo *ScopeName, SourceRange AttrRange,
156 SourceLocation ScopeLoc, Form FormUsed)
158 AttrName, ScopeName, AttrRange, ScopeLoc,
159 getParsedKind(AttrName, ScopeName, FormUsed.getSyntax()),
160 FormUsed) {}
161
163 Form FormUsed)
164 : AttributeCommonInfo(AttrName, nullptr, AttrRange, SourceLocation(),
165 FormUsed) {}
166
167 AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
168 : AttributeCommonInfo(nullptr, nullptr, AttrRange, SourceLocation(), K,
169 FormUsed) {}
170
173
174 Kind getParsedKind() const { return Kind(AttrKind); }
175 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
176 Form getForm() const {
177 return Form(getSyntax(), SpellingIndex, IsAlignas,
178 IsRegularKeywordAttribute);
179 }
180 const IdentifierInfo *getAttrName() const { return AttrName; }
181 void setAttrName(const IdentifierInfo *AttrNameII) { AttrName = AttrNameII; }
182 SourceLocation getLoc() const { return AttrRange.getBegin(); }
183 SourceRange getRange() const { return AttrRange; }
184 void setRange(SourceRange R) { AttrRange = R; }
185
186 bool hasScope() const { return ScopeName; }
187 const IdentifierInfo *getScopeName() const { return ScopeName; }
188 SourceLocation getScopeLoc() const { return ScopeLoc; }
189
190 /// Gets the normalized full name, which consists of both scope and name and
191 /// with surrounding underscores removed as appropriate (e.g.
192 /// __gnu__::__attr__ will be normalized to gnu::attr).
193 std::string getNormalizedFullName() const;
194
195 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
196 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
197
198 bool isGNUScope() const;
199 bool isClangScope() const;
200
201 bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11 || IsAlignas; }
202
203 bool isC23Attribute() const { return SyntaxUsed == AS_C23; }
204
205 bool isAlignas() const {
206 // FIXME: In the current state, the IsAlignas member variable is only true
207 // with the C++ `alignas` keyword but not `_Alignas`. The following
208 // expression works around the otherwise lost information so it will return
209 // true for `alignas` or `_Alignas` while still returning false for things
210 // like `__attribute__((aligned))`.
211 return (getParsedKind() == AT_Aligned && isKeywordAttribute());
212 }
213
214 /// The attribute is spelled [[]] in either C or C++ mode, including standard
215 /// attributes spelled with a keyword, like alignas.
217 return isCXX11Attribute() || isC23Attribute();
218 }
219
220 bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }
221
222 bool isKeywordAttribute() const {
223 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
224 }
225
226 bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
227
229 return SyntaxUsed == AS_ContextSensitiveKeyword;
230 }
231
233 assert((isAttributeSpellingListCalculated() || AttrName) &&
234 "Spelling cannot be found");
236 ? SpellingIndex
237 : calculateAttributeSpellingListIndex();
238 }
239 void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
240
241 static Kind getParsedKind(const IdentifierInfo *Name,
242 const IdentifierInfo *Scope, Syntax SyntaxUsed);
243
244private:
245 /// Get an index into the attribute spelling list
246 /// defined in Attr.td. This index is used by an attribute
247 /// to pretty print itself.
248 unsigned calculateAttributeSpellingListIndex() const;
249
251 // Used exclusively by ASTDeclWriter to get the raw spelling list state.
252 unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
253
254protected:
256 return SpellingIndex != SpellingNotCalculated;
257 }
258};
259
261 switch (Kind) {
262 default:
263 return false;
264#define KEYWORD_ATTRIBUTE(NAME, HASARG, ...) \
265 case tok::kw_##NAME: \
266 return HASARG;
267#include "clang/Basic/RegularKeywordAttrInfo.inc"
268#undef KEYWORD_ATTRIBUTE
269 }
270}
271
272} // namespace clang
273
274#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
#define V(N, I)
Definition: ASTContext.h:3443
enum clang::sema::@1718::IndirectLocalPathEntry::EntryKind Kind
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:154
Syntax
The style used to specify an attribute.
@ AS_Keyword
__ptr16, alignas(...), etc.
@ AS_ContextSensitiveKeyword
Context-sensitive version of a keyword attribute.
@ AS_HLSLAnnotation
<vardecl> : <annotation>
@ 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)