xref: /freebsd-src/contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1a7dea167SDimitry Andric //======- AttributeCommonInfo.h - Base info about Attributes-----*- C++ -*-===//
2a7dea167SDimitry Andric //
3a7dea167SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a7dea167SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5a7dea167SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a7dea167SDimitry Andric //
7a7dea167SDimitry Andric //===----------------------------------------------------------------------===//
8a7dea167SDimitry Andric //
9a7dea167SDimitry Andric // This file defines the AttributeCommonInfo type, which is the base for a
10a7dea167SDimitry Andric // ParsedAttr and is used by Attr as a way to share info between the two.
11a7dea167SDimitry Andric //
12a7dea167SDimitry Andric //===----------------------------------------------------------------------===//
13a7dea167SDimitry Andric 
14a7dea167SDimitry Andric #ifndef LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
15a7dea167SDimitry Andric #define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
16a7dea167SDimitry Andric #include "clang/Basic/SourceLocation.h"
17a7dea167SDimitry Andric 
18a7dea167SDimitry Andric namespace clang {
19a7dea167SDimitry Andric class IdentifierInfo;
20a7dea167SDimitry Andric class ASTRecordWriter;
21a7dea167SDimitry Andric 
22a7dea167SDimitry Andric class AttributeCommonInfo {
23a7dea167SDimitry Andric public:
24a7dea167SDimitry Andric   /// The style used to specify an attribute.
25a7dea167SDimitry Andric   enum Syntax {
26a7dea167SDimitry Andric     /// __attribute__((...))
27a7dea167SDimitry Andric     AS_GNU,
28a7dea167SDimitry Andric 
29a7dea167SDimitry Andric     /// [[...]]
30a7dea167SDimitry Andric     AS_CXX11,
31a7dea167SDimitry Andric 
32a7dea167SDimitry Andric     /// [[...]]
33a7dea167SDimitry Andric     AS_C2x,
34a7dea167SDimitry Andric 
35a7dea167SDimitry Andric     /// __declspec(...)
36a7dea167SDimitry Andric     AS_Declspec,
37a7dea167SDimitry Andric 
38a7dea167SDimitry Andric     /// [uuid("...")] class Foo
39a7dea167SDimitry Andric     AS_Microsoft,
40a7dea167SDimitry Andric 
41a7dea167SDimitry Andric     /// __ptr16, alignas(...), etc.
42a7dea167SDimitry Andric     AS_Keyword,
43a7dea167SDimitry Andric 
44a7dea167SDimitry Andric     /// #pragma ...
45a7dea167SDimitry Andric     AS_Pragma,
46a7dea167SDimitry Andric 
47a7dea167SDimitry Andric     // Note TableGen depends on the order above.  Do not add or change the order
48a7dea167SDimitry Andric     // without adding related code to TableGen/ClangAttrEmitter.cpp.
49a7dea167SDimitry Andric     /// Context-sensitive version of a keyword attribute.
50a7dea167SDimitry Andric     AS_ContextSensitiveKeyword,
51a7dea167SDimitry Andric   };
52a7dea167SDimitry Andric   enum Kind {
53a7dea167SDimitry Andric #define PARSED_ATTR(NAME) AT_##NAME,
54a7dea167SDimitry Andric #include "clang/Sema/AttrParsedAttrList.inc"
55a7dea167SDimitry Andric #undef PARSED_ATTR
56a7dea167SDimitry Andric     NoSemaHandlerAttribute,
57a7dea167SDimitry Andric     IgnoredAttribute,
58a7dea167SDimitry Andric     UnknownAttribute,
59a7dea167SDimitry Andric   };
60a7dea167SDimitry Andric 
61a7dea167SDimitry Andric private:
62a7dea167SDimitry Andric   const IdentifierInfo *AttrName = nullptr;
63a7dea167SDimitry Andric   const IdentifierInfo *ScopeName = nullptr;
64a7dea167SDimitry Andric   SourceRange AttrRange;
65a7dea167SDimitry Andric   const SourceLocation ScopeLoc;
66a7dea167SDimitry Andric   // Corresponds to the Kind enum.
67a7dea167SDimitry Andric   unsigned AttrKind : 16;
68a7dea167SDimitry Andric   /// Corresponds to the Syntax enum.
69a7dea167SDimitry Andric   unsigned SyntaxUsed : 3;
70a7dea167SDimitry Andric   unsigned SpellingIndex : 4;
71a7dea167SDimitry Andric 
72a7dea167SDimitry Andric protected:
73a7dea167SDimitry Andric   static constexpr unsigned SpellingNotCalculated = 0xf;
74a7dea167SDimitry Andric 
75a7dea167SDimitry Andric public:
76a7dea167SDimitry Andric   AttributeCommonInfo(SourceRange AttrRange)
77a7dea167SDimitry Andric       : AttrRange(AttrRange), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
78a7dea167SDimitry Andric         SpellingIndex(SpellingNotCalculated) {}
79a7dea167SDimitry Andric 
80a7dea167SDimitry Andric   AttributeCommonInfo(SourceLocation AttrLoc)
81a7dea167SDimitry Andric       : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
82a7dea167SDimitry Andric         SpellingIndex(SpellingNotCalculated) {}
83a7dea167SDimitry Andric 
84a7dea167SDimitry Andric   AttributeCommonInfo(const IdentifierInfo *AttrName,
85a7dea167SDimitry Andric                       const IdentifierInfo *ScopeName, SourceRange AttrRange,
86a7dea167SDimitry Andric                       SourceLocation ScopeLoc, Syntax SyntaxUsed)
87a7dea167SDimitry Andric       : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
88a7dea167SDimitry Andric         ScopeLoc(ScopeLoc),
89a7dea167SDimitry Andric         AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
90a7dea167SDimitry Andric         SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
91a7dea167SDimitry Andric 
92a7dea167SDimitry Andric   AttributeCommonInfo(const IdentifierInfo *AttrName,
93a7dea167SDimitry Andric                       const IdentifierInfo *ScopeName, SourceRange AttrRange,
94a7dea167SDimitry Andric                       SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed)
95a7dea167SDimitry Andric       : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
96a7dea167SDimitry Andric         ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
97a7dea167SDimitry Andric         SpellingIndex(SpellingNotCalculated) {}
98a7dea167SDimitry Andric 
99a7dea167SDimitry Andric   AttributeCommonInfo(const IdentifierInfo *AttrName,
100a7dea167SDimitry Andric                       const IdentifierInfo *ScopeName, SourceRange AttrRange,
101a7dea167SDimitry Andric                       SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed,
102a7dea167SDimitry Andric                       unsigned Spelling)
103a7dea167SDimitry Andric       : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
104a7dea167SDimitry Andric         ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
105a7dea167SDimitry Andric         SpellingIndex(Spelling) {}
106a7dea167SDimitry Andric 
107a7dea167SDimitry Andric   AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
108a7dea167SDimitry Andric                       Syntax SyntaxUsed)
109a7dea167SDimitry Andric       : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange),
110a7dea167SDimitry Andric         ScopeLoc(), AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
111a7dea167SDimitry Andric         SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
112a7dea167SDimitry Andric 
113a7dea167SDimitry Andric   AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed)
114a7dea167SDimitry Andric       : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
115a7dea167SDimitry Andric         AttrKind(K), SyntaxUsed(SyntaxUsed),
116a7dea167SDimitry Andric         SpellingIndex(SpellingNotCalculated) {}
117a7dea167SDimitry Andric 
118a7dea167SDimitry Andric   AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed,
119a7dea167SDimitry Andric                       unsigned Spelling)
120a7dea167SDimitry Andric       : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
121a7dea167SDimitry Andric         AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {}
122a7dea167SDimitry Andric 
123a7dea167SDimitry Andric   AttributeCommonInfo(AttributeCommonInfo &&) = default;
124a7dea167SDimitry Andric   AttributeCommonInfo(const AttributeCommonInfo &) = default;
125a7dea167SDimitry Andric 
126a7dea167SDimitry Andric   Kind getParsedKind() const { return Kind(AttrKind); }
127a7dea167SDimitry Andric   Syntax getSyntax() const { return Syntax(SyntaxUsed); }
128a7dea167SDimitry Andric   const IdentifierInfo *getAttrName() const { return AttrName; }
129a7dea167SDimitry Andric   SourceLocation getLoc() const { return AttrRange.getBegin(); }
130a7dea167SDimitry Andric   SourceRange getRange() const { return AttrRange; }
131a7dea167SDimitry Andric   void setRange(SourceRange R) { AttrRange = R; }
132a7dea167SDimitry Andric 
133a7dea167SDimitry Andric   bool hasScope() const { return ScopeName; }
134a7dea167SDimitry Andric   const IdentifierInfo *getScopeName() const { return ScopeName; }
135a7dea167SDimitry Andric   SourceLocation getScopeLoc() const { return ScopeLoc; }
136a7dea167SDimitry Andric 
137*5ffd83dbSDimitry Andric   /// Gets the normalized full name, which consists of both scope and name and
138*5ffd83dbSDimitry Andric   /// with surrounding underscores removed as appropriate (e.g.
139*5ffd83dbSDimitry Andric   /// __gnu__::__attr__ will be normalized to gnu::attr).
140*5ffd83dbSDimitry Andric   std::string getNormalizedFullName() const;
141*5ffd83dbSDimitry Andric 
142a7dea167SDimitry Andric   bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
143a7dea167SDimitry Andric   bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
144a7dea167SDimitry Andric 
145a7dea167SDimitry Andric   bool isGNUScope() const;
146a7dea167SDimitry Andric 
147a7dea167SDimitry Andric   bool isAlignasAttribute() const {
148a7dea167SDimitry Andric     // FIXME: Use a better mechanism to determine this.
149a7dea167SDimitry Andric     return getParsedKind() == AT_Aligned && isKeywordAttribute();
150a7dea167SDimitry Andric   }
151a7dea167SDimitry Andric 
152a7dea167SDimitry Andric   bool isCXX11Attribute() const {
153a7dea167SDimitry Andric     return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
154a7dea167SDimitry Andric   }
155a7dea167SDimitry Andric 
156a7dea167SDimitry Andric   bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; }
157a7dea167SDimitry Andric 
158a7dea167SDimitry Andric   bool isKeywordAttribute() const {
159a7dea167SDimitry Andric     return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
160a7dea167SDimitry Andric   }
161a7dea167SDimitry Andric 
162a7dea167SDimitry Andric   bool isContextSensitiveKeywordAttribute() const {
163a7dea167SDimitry Andric     return SyntaxUsed == AS_ContextSensitiveKeyword;
164a7dea167SDimitry Andric   }
165a7dea167SDimitry Andric 
166a7dea167SDimitry Andric   unsigned getAttributeSpellingListIndex() const {
167a7dea167SDimitry Andric     assert((isAttributeSpellingListCalculated() || AttrName) &&
168a7dea167SDimitry Andric            "Spelling cannot be found");
169a7dea167SDimitry Andric     return isAttributeSpellingListCalculated()
170a7dea167SDimitry Andric                ? SpellingIndex
171a7dea167SDimitry Andric                : calculateAttributeSpellingListIndex();
172a7dea167SDimitry Andric   }
173a7dea167SDimitry Andric   void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
174a7dea167SDimitry Andric 
175a7dea167SDimitry Andric   static Kind getParsedKind(const IdentifierInfo *Name,
176a7dea167SDimitry Andric                             const IdentifierInfo *Scope, Syntax SyntaxUsed);
177a7dea167SDimitry Andric 
178a7dea167SDimitry Andric private:
179a7dea167SDimitry Andric   /// Get an index into the attribute spelling list
180a7dea167SDimitry Andric   /// defined in Attr.td. This index is used by an attribute
181a7dea167SDimitry Andric   /// to pretty print itself.
182a7dea167SDimitry Andric   unsigned calculateAttributeSpellingListIndex() const;
183a7dea167SDimitry Andric 
184a7dea167SDimitry Andric   friend class clang::ASTRecordWriter;
185a7dea167SDimitry Andric   // Used exclusively by ASTDeclWriter to get the raw spelling list state.
186a7dea167SDimitry Andric   unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
187a7dea167SDimitry Andric 
188a7dea167SDimitry Andric protected:
189a7dea167SDimitry Andric   bool isAttributeSpellingListCalculated() const {
190a7dea167SDimitry Andric     return SpellingIndex != SpellingNotCalculated;
191a7dea167SDimitry Andric   }
192a7dea167SDimitry Andric };
193a7dea167SDimitry Andric } // namespace clang
194a7dea167SDimitry Andric 
195a7dea167SDimitry Andric #endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
196