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