clang 22.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
21
22namespace clang {
23
24class ASTRecordWriter;
25class IdentifierInfo;
26class LangOptions;
27class TargetInfo;
28
30public:
31 /// The style used to specify an attribute.
32 enum Syntax {
33 /// __attribute__((...))
34 AS_GNU = 1,
35
36 /// [[...]]
38
39 /// [[...]]
41
42 /// __declspec(...)
44
45 /// [uuid("...")] class Foo
47
48 /// __ptr16, alignas(...), etc.
50
51 /// #pragma ...
53
54 // Note TableGen depends on the order above. Do not add or change the order
55 // without adding related code to TableGen/ClangAttrEmitter.cpp.
56 /// Context-sensitive version of a keyword attribute.
58
59 /// <vardecl> : <annotation>
61
62 /// The attibute has no source code manifestation and is only created
63 /// implicitly.
65 };
66
67 enum Kind {
68#define PARSED_ATTR(NAME) AT_##NAME,
69#include "clang/Basic/AttrParsedAttrList.inc"
70#undef PARSED_ATTR
74 };
75 enum class Scope { NONE, CLANG, GNU, MSVC, OMP, HLSL, VK, GSL, RISCV };
76 enum class AttrArgsInfo {
77 None,
80 };
81
82private:
83 const IdentifierInfo *AttrName = nullptr;
84 AttributeScopeInfo AttrScope;
85 SourceRange AttrRange;
86
87 // Corresponds to the Kind enum.
88 LLVM_PREFERRED_TYPE(Kind)
89 unsigned AttrKind : 16;
90 /// Corresponds to the Syntax enum.
91 LLVM_PREFERRED_TYPE(Syntax)
92 unsigned SyntaxUsed : 4;
93 LLVM_PREFERRED_TYPE(bool)
94 unsigned SpellingIndex : 4;
95 LLVM_PREFERRED_TYPE(bool)
96 unsigned IsAlignas : 1;
97 LLVM_PREFERRED_TYPE(bool)
98 unsigned IsRegularKeywordAttribute : 1;
99
100protected:
101 static constexpr unsigned SpellingNotCalculated = 0xf;
102
103public:
104 /// Combines information about the source-code form of an attribute,
105 /// including its syntax and spelling.
106 class Form {
107 public:
108 constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas,
109 bool IsRegularKeywordAttribute)
110 : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex),
111 IsAlignas(IsAlignas),
112 IsRegularKeywordAttribute(IsRegularKeywordAttribute) {}
113 constexpr Form(tok::TokenKind Tok)
114 : SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated),
115 IsAlignas(Tok == tok::kw_alignas),
116 IsRegularKeywordAttribute(tok::isRegularKeywordAttribute(Tok)) {}
117
118 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
119 unsigned getSpellingIndex() const { return SpellingIndex; }
120 bool isAlignas() const { return IsAlignas; }
121 bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
122
123 static Form GNU() { return AS_GNU; }
124 static Form CXX11() { return AS_CXX11; }
125 static Form C23() { return AS_C23; }
126 static Form Declspec() { return AS_Declspec; }
127 static Form Microsoft() { return AS_Microsoft; }
128 static Form Keyword(bool IsAlignas, bool IsRegularKeywordAttribute) {
129 return Form(AS_Keyword, SpellingNotCalculated, IsAlignas,
130 IsRegularKeywordAttribute);
131 }
132 static Form Pragma() { return AS_Pragma; }
135 static Form Implicit() { return AS_Implicit; }
136
137 private:
138 constexpr Form(Syntax SyntaxUsed)
139 : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated),
140 IsAlignas(0), IsRegularKeywordAttribute(0) {}
141
142 LLVM_PREFERRED_TYPE(Syntax)
143 unsigned SyntaxUsed : 4;
144 unsigned SpellingIndex : 4;
145 LLVM_PREFERRED_TYPE(bool)
146 unsigned IsAlignas : 1;
147 LLVM_PREFERRED_TYPE(bool)
148 unsigned IsRegularKeywordAttribute : 1;
149 };
150
152 AttributeScopeInfo AttrScope, SourceRange AttrRange,
153 Kind AttrKind, Form FormUsed)
154 : AttrName(AttrName), AttrScope(AttrScope), AttrRange(AttrRange),
155 AttrKind(AttrKind), SyntaxUsed(FormUsed.getSyntax()),
156 SpellingIndex(FormUsed.getSpellingIndex()),
157 IsAlignas(FormUsed.isAlignas()),
158 IsRegularKeywordAttribute(FormUsed.isRegularKeywordAttribute()) {
159 assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
160 "Invalid syntax!");
161 }
162
164 SourceRange AttrRange, Form FormUsed)
166 AttrName, Scope, AttrRange,
167 getParsedKind(AttrName, Scope.getName(), FormUsed.getSyntax()),
168 FormUsed) {}
169
171 Form FormUsed)
172 : AttributeCommonInfo(AttrName, AttributeScopeInfo(), AttrRange,
173 FormUsed) {}
174
175 AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
176 : AttributeCommonInfo(nullptr, AttributeScopeInfo(), AttrRange, K,
177 FormUsed) {}
178
180 Kind K, Form FormUsed)
181 : AttributeCommonInfo(nullptr, AttrScope, AttrRange, K, FormUsed) {}
182
185
186 Kind getParsedKind() const { return Kind(AttrKind); }
187 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
188 Form getForm() const {
189 return Form(getSyntax(), SpellingIndex, IsAlignas,
190 IsRegularKeywordAttribute);
191 }
192 const IdentifierInfo *getAttrName() const { return AttrName; }
193 void setAttrName(const IdentifierInfo *AttrNameII) { AttrName = AttrNameII; }
194 SourceLocation getLoc() const { return AttrRange.getBegin(); }
195 SourceRange getRange() const { return AttrRange; }
196 void setRange(SourceRange R) { AttrRange = R; }
197
198 bool hasScope() const { return AttrScope.isValid(); }
199 bool isExplicitScope() const { return AttrScope.isExplicit(); }
200
201 const IdentifierInfo *getScopeName() const { return AttrScope.getName(); }
202 SourceLocation getScopeLoc() const { return AttrScope.getNameLoc(); }
203
204 /// Gets the normalized full name, which consists of both scope and name and
205 /// with surrounding underscores removed as appropriate (e.g.
206 /// __gnu__::__attr__ will be normalized to gnu::attr).
207 std::string getNormalizedFullName() const;
208 std::string getNormalizedFullName(StringRef ScopeName,
209 StringRef AttrName) const;
210 StringRef getNormalizedScopeName() const;
211 StringRef getNormalizedAttrName(StringRef ScopeName) const;
212
213 std::optional<StringRef> tryGetCorrectedScopeName(StringRef ScopeName) const;
214 std::optional<StringRef>
215 tryGetCorrectedAttrName(StringRef ScopeName, StringRef AttrName,
216 const TargetInfo &Target,
217 const LangOptions &LangOpts) const;
218
220
221 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
222 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
223
224 bool isGNUScope() const;
225 bool isClangScope() const;
226
227 bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11 || IsAlignas; }
228
229 bool isC23Attribute() const { return SyntaxUsed == AS_C23; }
230
231 bool isAlignas() const {
232 // FIXME: In the current state, the IsAlignas member variable is only true
233 // with the C++ `alignas` keyword but not `_Alignas`. The following
234 // expression works around the otherwise lost information so it will return
235 // true for `alignas` or `_Alignas` while still returning false for things
236 // like `__attribute__((aligned))`.
237 return (getParsedKind() == AT_Aligned && isKeywordAttribute());
238 }
239
240 /// The attribute is spelled [[]] in either C or C++ mode, including standard
241 /// attributes spelled with a keyword, like alignas.
243 return isCXX11Attribute() || isC23Attribute();
244 }
245
246 bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }
247
248 bool isKeywordAttribute() const {
249 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
250 }
251
252 bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
253
255 return SyntaxUsed == AS_ContextSensitiveKeyword;
256 }
257
259 assert((isAttributeSpellingListCalculated() || AttrName) &&
260 "Spelling cannot be found");
262 ? SpellingIndex
263 : calculateAttributeSpellingListIndex();
264 }
265 void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
266
267 static Kind getParsedKind(const IdentifierInfo *Name,
268 const IdentifierInfo *Scope, Syntax SyntaxUsed);
269
271
272private:
273 /// Get an index into the attribute spelling list
274 /// defined in Attr.td. This index is used by an attribute
275 /// to pretty print itself.
276 unsigned calculateAttributeSpellingListIndex() const;
277
279 // Used exclusively by ASTDeclWriter to get the raw spelling list state.
280 unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
281
282protected:
284 return SpellingIndex != SpellingNotCalculated;
285 }
286};
287
289 switch (Kind) {
290 default:
291 return false;
292#define KEYWORD_ATTRIBUTE(NAME, HASARG, ...) \
293 case tok::kw_##NAME: \
294 return HASARG;
295#include "clang/Basic/RegularKeywordAttrInfo.inc"
296#undef KEYWORD_ATTRIBUTE
297 }
298}
299
301 const AttributeCommonInfo *CI) {
302 DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI),
304 return DB;
305}
306
308 const AttributeCommonInfo &CI) {
309 return DB << &CI;
310}
311
312} // namespace clang
313
314#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
#define V(N, I)
Definition: ASTContext.h:3597
Defines the Diagnostic-related interfaces.
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
llvm::MachO::Target Target
Definition: MachO.h:51
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:206
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, AttributeScopeInfo AttrScope, SourceRange AttrRange, Kind AttrKind, Form FormUsed)
void setAttrName(const IdentifierInfo *AttrNameII)
unsigned getAttributeSpellingListIndex() const
const IdentifierInfo * getScopeName() const
StringRef getNormalizedAttrName(StringRef ScopeName) const
Definition: Attributes.cpp:148
std::optional< StringRef > tryGetCorrectedAttrName(StringRef ScopeName, StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts) const
Definition: Attributes.cpp:274
AttributeCommonInfo(const IdentifierInfo *AttrName, AttributeScopeInfo Scope, SourceRange AttrRange, Form FormUsed)
bool isContextSensitiveKeywordAttribute() const
AttributeCommonInfo(AttributeCommonInfo &&)=default
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
Definition: Attributes.cpp:196
AttributeCommonInfo(SourceRange AttrRange, AttributeScopeInfo AttrScope, Kind K, Form FormUsed)
SourceRange getNormalizedRange() const
Definition: Attributes.cpp:218
std::optional< StringRef > tryGetCorrectedScopeName(StringRef ScopeName) const
Definition: Attributes.cpp:261
SourceLocation getLoc() const
const IdentifierInfo * getAttrName() const
StringRef getNormalizedScopeName() const
Definition: Attributes.cpp:143
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...
SourceLocation getNameLoc() const
const IdentifierInfo * getName() const
@ ak_attr_info
AttributeCommonInfo *.
Definition: Diagnostic.h:295
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:434
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
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
Definition: Diagnostic.h:1115
void AddTaggedVal(uint64_t V, DiagnosticsEngine::ArgumentKind Kind) const
Definition: Diagnostic.h:1156
Exposes information about the current target.
Definition: TargetInfo.h:226
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)
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.