AttributeCommonInfo.h revision 360784
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  bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
138  bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
139
140  bool isGNUScope() const;
141
142  bool isAlignasAttribute() const {
143    // FIXME: Use a better mechanism to determine this.
144    return getParsedKind() == AT_Aligned && isKeywordAttribute();
145  }
146
147  bool isCXX11Attribute() const {
148    return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
149  }
150
151  bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; }
152
153  bool isKeywordAttribute() const {
154    return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
155  }
156
157  bool isContextSensitiveKeywordAttribute() const {
158    return SyntaxUsed == AS_ContextSensitiveKeyword;
159  }
160
161  unsigned getAttributeSpellingListIndex() const {
162    assert((isAttributeSpellingListCalculated() || AttrName) &&
163           "Spelling cannot be found");
164    return isAttributeSpellingListCalculated()
165               ? SpellingIndex
166               : calculateAttributeSpellingListIndex();
167  }
168  void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
169
170  static Kind getParsedKind(const IdentifierInfo *Name,
171                            const IdentifierInfo *Scope, Syntax SyntaxUsed);
172
173private:
174  /// Get an index into the attribute spelling list
175  /// defined in Attr.td. This index is used by an attribute
176  /// to pretty print itself.
177  unsigned calculateAttributeSpellingListIndex() const;
178
179  friend class clang::ASTRecordWriter;
180  // Used exclusively by ASTDeclWriter to get the raw spelling list state.
181  unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
182
183protected:
184  bool isAttributeSpellingListCalculated() const {
185    return SpellingIndex != SpellingNotCalculated;
186  }
187};
188} // namespace clang
189
190#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
191