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 };
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) {}
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)
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)
Defines the Diagnostic-related interfaces.
Token Tok
The Token.
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
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...
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
std::optional< StringRef > tryGetCorrectedAttrName(StringRef ScopeName, StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts) const
AttributeCommonInfo(const IdentifierInfo *AttrName, AttributeScopeInfo Scope, SourceRange AttrRange, Form FormUsed)
bool isContextSensitiveKeywordAttribute() const
AttributeCommonInfo(AttributeCommonInfo &&)=default
static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)
AttributeCommonInfo(SourceRange AttrRange, AttributeScopeInfo AttrScope, Kind K, Form FormUsed)
SourceRange getNormalizedRange() const
std::optional< StringRef > tryGetCorrectedScopeName(StringRef ScopeName) const
SourceLocation getLoc() const
const IdentifierInfo * getAttrName() const
StringRef getNormalizedScopeName() const
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...
@ ak_attr_info
AttributeCommonInfo *.
Definition Diagnostic.h:295
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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.
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
void AddTaggedVal(uint64_t V, DiagnosticsEngine::ArgumentKind Kind) const
Exposes information about the current target.
Definition TargetInfo.h:226
Definition SPIR.cpp:47
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)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.