clang 17.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
17
18namespace clang {
19class IdentifierInfo;
20class ASTRecordWriter;
21
23public:
24 /// The style used to specify an attribute.
25 enum Syntax {
26 /// __attribute__((...))
28
29 /// [[...]]
31
32 /// [[...]]
34
35 /// __declspec(...)
37
38 /// [uuid("...")] class Foo
40
41 /// __ptr16, alignas(...), etc.
43
44 /// #pragma ...
46
47 // Note TableGen depends on the order above. Do not add or change the order
48 // without adding related code to TableGen/ClangAttrEmitter.cpp.
49 /// Context-sensitive version of a keyword attribute.
51
52 /// <vardecl> : <semantic>
54 };
55 enum Kind {
56#define PARSED_ATTR(NAME) AT_##NAME,
57#include "clang/Sema/AttrParsedAttrList.inc"
58#undef PARSED_ATTR
62 };
63
64private:
65 const IdentifierInfo *AttrName = nullptr;
66 const IdentifierInfo *ScopeName = nullptr;
67 SourceRange AttrRange;
68 const SourceLocation ScopeLoc;
69 // Corresponds to the Kind enum.
70 unsigned AttrKind : 16;
71 /// Corresponds to the Syntax enum.
72 unsigned SyntaxUsed : 4;
73 unsigned SpellingIndex : 4;
74
75protected:
76 static constexpr unsigned SpellingNotCalculated = 0xf;
77
78public:
80 : AttrRange(AttrRange), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
81 SpellingIndex(SpellingNotCalculated) {}
82
84 : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
85 SpellingIndex(SpellingNotCalculated) {}
86
88 const IdentifierInfo *ScopeName, SourceRange AttrRange,
89 SourceLocation ScopeLoc, Syntax SyntaxUsed)
90 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
91 ScopeLoc(ScopeLoc),
92 AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
93 SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
94
96 const IdentifierInfo *ScopeName, SourceRange AttrRange,
97 SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed)
98 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
99 ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
100 SpellingIndex(SpellingNotCalculated) {}
101
103 const IdentifierInfo *ScopeName, SourceRange AttrRange,
104 SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed,
105 unsigned Spelling)
106 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
107 ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
108 SpellingIndex(Spelling) {}
109
111 Syntax SyntaxUsed)
112 : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange),
113 ScopeLoc(), AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
114 SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
115
116 AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed)
117 : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
118 AttrKind(K), SyntaxUsed(SyntaxUsed),
119 SpellingIndex(SpellingNotCalculated) {}
120
121 AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed,
122 unsigned Spelling)
123 : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
124 AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {}
125
128
129 Kind getParsedKind() const { return Kind(AttrKind); }
130 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
131 const IdentifierInfo *getAttrName() const { return AttrName; }
132 SourceLocation getLoc() const { return AttrRange.getBegin(); }
133 SourceRange getRange() const { return AttrRange; }
134 void setRange(SourceRange R) { AttrRange = R; }
135
136 bool hasScope() const { return ScopeName; }
137 const IdentifierInfo *getScopeName() const { return ScopeName; }
138 SourceLocation getScopeLoc() const { return ScopeLoc; }
139
140 /// Gets the normalized full name, which consists of both scope and name and
141 /// with surrounding underscores removed as appropriate (e.g.
142 /// __gnu__::__attr__ will be normalized to gnu::attr).
143 std::string getNormalizedFullName() const;
144
145 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
146 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
147
148 bool isGNUScope() const;
149 bool isClangScope() const;
150
151 bool isAlignasAttribute() const {
152 // FIXME: Use a better mechanism to determine this.
153 // We use this in `isCXX11Attribute` below, so it _should_ only return
154 // true for the `alignas` spelling, but it currently also returns true
155 // for the `_Alignas` spelling, which only exists in C11. Distinguishing
156 // between the two is important because they behave differently:
157 // - `alignas` may only appear in the attribute-specifier-seq before
158 // the decl-specifier-seq and is therefore associated with the
159 // declaration.
160 // - `_Alignas` may appear anywhere within the declaration-specifiers
161 // and is therefore associated with the `DeclSpec`.
162 // It's not clear how best to fix this:
163 // - We have the necessary information in the form of the `SpellingIndex`,
164 // but we would need to compare against AlignedAttr::Keyword_alignas,
165 // and we can't depend on clang/AST/Attr.h here.
166 // - We could test `getAttrName()->getName() == "alignas"`, but this is
167 // inefficient.
168 return getParsedKind() == AT_Aligned && isKeywordAttribute();
169 }
170
171 bool isCXX11Attribute() const {
172 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
173 }
174
175 bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; }
176
177 /// The attribute is spelled [[]] in either C or C++ mode, including standard
178 /// attributes spelled with a keyword, like alignas.
180 return isCXX11Attribute() || isC2xAttribute();
181 }
182
183 bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }
184
185 bool isKeywordAttribute() const {
186 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
187 }
188
190 return SyntaxUsed == AS_ContextSensitiveKeyword;
191 }
192
194 assert((isAttributeSpellingListCalculated() || AttrName) &&
195 "Spelling cannot be found");
197 ? SpellingIndex
198 : calculateAttributeSpellingListIndex();
199 }
200 void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
201
202 static Kind getParsedKind(const IdentifierInfo *Name,
203 const IdentifierInfo *Scope, Syntax SyntaxUsed);
204
205private:
206 /// Get an index into the attribute spelling list
207 /// defined in Attr.td. This index is used by an attribute
208 /// to pretty print itself.
209 unsigned calculateAttributeSpellingListIndex() const;
210
212 // Used exclusively by ASTDeclWriter to get the raw spelling list state.
213 unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
214
215protected:
217 return SpellingIndex != SpellingNotCalculated;
218 }
219};
220} // namespace clang
221
222#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
#define V(N, I)
Definition: ASTContext.h:3211
Defines the clang::SourceLocation class and associated facilities.
An object for streaming information to a record.
SourceLocation getScopeLoc() const
bool isAttributeSpellingListCalculated() const
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:117
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_Microsoft
[uuid("...")] class Foo
AttributeCommonInfo(const IdentifierInfo *AttrName, const IdentifierInfo *ScopeName, SourceRange AttrRange, SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed)
AttributeCommonInfo(SourceRange AttrRange)
unsigned getAttributeSpellingListIndex() const
const IdentifierInfo * getScopeName() const
bool isContextSensitiveKeywordAttribute() const
AttributeCommonInfo(const IdentifierInfo *AttrName, const IdentifierInfo *ScopeName, SourceRange AttrRange, SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed, unsigned Spelling)
AttributeCommonInfo(AttributeCommonInfo &&)=default
AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange, Syntax SyntaxUsed)
AttributeCommonInfo(const IdentifierInfo *AttrName, const IdentifierInfo *ScopeName, SourceRange AttrRange, SourceLocation ScopeLoc, Syntax SyntaxUsed)
AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed)
AttributeCommonInfo(SourceLocation AttrLoc)
SourceLocation getLoc() const
const IdentifierInfo * getAttrName() 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...
AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed, unsigned Spelling)
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