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#include "clang/Basic/SourceLocation.h"
17
18namespace clang {
19class IdentifierInfo;
20class ASTRecordWriter;
21
22class AttributeCommonInfo {
23public:
24 /// The style used to specify an attribute.
25 enum Syntax {
26 /// __attribute__((...))
27 AS_GNU,
28
29 /// [[...]]
30 AS_CXX11,
31
32 /// [[...]]
33 AS_C2x,
34
35 /// __declspec(...)
36 AS_Declspec,
37
38 /// [uuid("...")] class Foo
39 AS_Microsoft,
40
41 /// __ptr16, alignas(...), etc.
42 AS_Keyword,
43
44 /// #pragma ...
45 AS_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.
50 AS_ContextSensitiveKeyword,
51 };
52 enum Kind {
53#define PARSED_ATTR(NAME) AT_##NAME,
54#include "clang/Sema/AttrParsedAttrList.inc"
55#undef PARSED_ATTR
56 NoSemaHandlerAttribute,
57 IgnoredAttribute,
58 UnknownAttribute,
59 };
60
61private:
62 const IdentifierInfo *AttrName = nullptr;
63 const IdentifierInfo *ScopeName = nullptr;
64 SourceRange AttrRange;
65 const SourceLocation ScopeLoc;
66 // Corresponds to the Kind enum.
67 unsigned AttrKind : 16;
68 /// Corresponds to the Syntax enum.
69 unsigned SyntaxUsed : 3;
70 unsigned SpellingIndex : 4;
71
72protected:
73 static constexpr unsigned SpellingNotCalculated = 0xf;
74
75public:
76 AttributeCommonInfo(SourceRange AttrRange)
77 : AttrRange(AttrRange), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
78 SpellingIndex(SpellingNotCalculated) {}
79
80 AttributeCommonInfo(SourceLocation AttrLoc)
81 : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
82 SpellingIndex(SpellingNotCalculated) {}
83
84 AttributeCommonInfo(const IdentifierInfo *AttrName,
85 const IdentifierInfo *ScopeName, SourceRange AttrRange,
86 SourceLocation ScopeLoc, Syntax SyntaxUsed)
87 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
88 ScopeLoc(ScopeLoc),
89 AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
90 SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
91
92 AttributeCommonInfo(const IdentifierInfo *AttrName,
93 const IdentifierInfo *ScopeName, SourceRange AttrRange,
94 SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed)
95 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
96 ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
97 SpellingIndex(SpellingNotCalculated) {}
98
99 AttributeCommonInfo(const IdentifierInfo *AttrName,
100 const IdentifierInfo *ScopeName, SourceRange AttrRange,
101 SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed,
102 unsigned Spelling)
103 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
104 ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
105 SpellingIndex(Spelling) {}
106
107 AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
108 Syntax SyntaxUsed)
109 : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange),
110 ScopeLoc(), AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
111 SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
112
113 AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed)
114 : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
115 AttrKind(K), SyntaxUsed(SyntaxUsed),
116 SpellingIndex(SpellingNotCalculated) {}
117
118 AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed,
119 unsigned Spelling)
120 : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
121 AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {}
122
123 AttributeCommonInfo(AttributeCommonInfo &&) = default;
124 AttributeCommonInfo(const AttributeCommonInfo &) = default;
125
126 Kind getParsedKind() const { return Kind(AttrKind); }
127 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
128 const IdentifierInfo *getAttrName() const { return AttrName; }
129 SourceLocation getLoc() const { return AttrRange.getBegin(); }
130 SourceRange getRange() const { return AttrRange; }
131 void setRange(SourceRange R) { AttrRange = R; }
132
133 bool hasScope() const { return ScopeName; }
134 const IdentifierInfo *getScopeName() const { return ScopeName; }
135 SourceLocation getScopeLoc() const { return ScopeLoc; }
136
137 /// Gets the normalized full name, which consists of both scope and name and
138 /// with surrounding underscores removed as appropriate (e.g.
139 /// __gnu__::__attr__ will be normalized to gnu::attr).
140 std::string getNormalizedFullName() const;
141
142 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
143 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
144
145 bool isGNUScope() const;
146
147 bool isAlignasAttribute() const {
148 // FIXME: Use a better mechanism to determine this.
149 return getParsedKind() == AT_Aligned && isKeywordAttribute();
150 }
151
152 bool isCXX11Attribute() const {
153 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
154 }
155
156 bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; }
157
158 bool isKeywordAttribute() const {
159 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
160 }
161
162 bool isContextSensitiveKeywordAttribute() const {
163 return SyntaxUsed == AS_ContextSensitiveKeyword;
164 }
165
166 unsigned getAttributeSpellingListIndex() const {
167 assert((isAttributeSpellingListCalculated() || AttrName) &&
168 "Spelling cannot be found");
169 return isAttributeSpellingListCalculated()
170 ? SpellingIndex
171 : calculateAttributeSpellingListIndex();
172 }
173 void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
174
175 static Kind getParsedKind(const IdentifierInfo *Name,
176 const IdentifierInfo *Scope, Syntax SyntaxUsed);
177
178private:
179 /// Get an index into the attribute spelling list
180 /// defined in Attr.td. This index is used by an attribute
181 /// to pretty print itself.
182 unsigned calculateAttributeSpellingListIndex() const;
183
184 friend class clang::ASTRecordWriter;
185 // Used exclusively by ASTDeclWriter to get the raw spelling list state.
186 unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
187
188protected:
189 bool isAttributeSpellingListCalculated() const {
190 return SpellingIndex != SpellingNotCalculated;
191 }
192};
193} // namespace clang
194
195#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
196