clang  10.0.0svn
Attr.h
Go to the documentation of this file.
1 //===--- Attr.h - Classes for representing 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 Attr interface and subclasses.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_AST_ATTR_H
14 #define LLVM_CLANG_AST_ATTR_H
15 
16 #include "clang/AST/ASTContextAllocate.h" // For Attrs.inc
17 #include "clang/AST/AttrIterator.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Basic/AttrKinds.h"
23 #include "clang/Basic/LLVM.h"
25 #include "clang/Basic/Sanitizers.h"
27 #include "llvm/ADT/StringSwitch.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/VersionTuple.h"
30 #include "llvm/Support/raw_ostream.h"
31 #include <algorithm>
32 #include <cassert>
33 
34 namespace clang {
35  class ASTContext;
36  class AttributeCommonInfo;
37  class IdentifierInfo;
38  class ObjCInterfaceDecl;
39  class Expr;
40  class QualType;
41  class FunctionDecl;
42  class TypeSourceInfo;
43 
44 /// Attr - This represents one attribute.
45  class Attr : public AttributeCommonInfo {
46  private:
47  unsigned AttrKind : 16;
48 
49  protected:
50  /// An index into the spelling list of an
51  /// attribute defined in Attr.td file.
52  unsigned Inherited : 1;
53  unsigned IsPackExpansion : 1;
54  unsigned Implicit : 1;
55  // FIXME: These are properties of the attribute kind, not state for this
56  // instance of the attribute.
57  unsigned IsLateParsed : 1;
59 
60  void *operator new(size_t bytes) noexcept {
61  llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
62  }
63  void operator delete(void *data) noexcept {
64  llvm_unreachable("Attrs cannot be released with regular 'delete'.");
65  }
66 
67  public:
68  // Forward so that the regular new and delete do not hide global ones.
69  void *operator new(size_t Bytes, ASTContext &C,
70  size_t Alignment = 8) noexcept {
71  return ::operator new(Bytes, C, Alignment);
72  }
73  void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
74  return ::operator delete(Ptr, C, Alignment);
75  }
76 
77  protected:
78  Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
79  attr::Kind AK, bool IsLateParsed)
80  : AttributeCommonInfo(CommonInfo), AttrKind(AK), Inherited(false),
81  IsPackExpansion(false), Implicit(false), IsLateParsed(IsLateParsed),
83 
84  public:
85  attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); }
86 
87  unsigned getSpellingListIndex() const {
89  }
90  const char *getSpelling() const;
91 
92  SourceLocation getLocation() const { return getRange().getBegin(); }
93 
94  bool isInherited() const { return Inherited; }
95 
96  /// Returns true if the attribute has been implicitly created instead
97  /// of explicitly written by the user.
98  bool isImplicit() const { return Implicit; }
99  void setImplicit(bool I) { Implicit = I; }
100 
101  void setPackExpansion(bool PE) { IsPackExpansion = PE; }
102  bool isPackExpansion() const { return IsPackExpansion; }
103 
104  // Clone this attribute.
105  Attr *clone(ASTContext &C) const;
106 
107  bool isLateParsed() const { return IsLateParsed; }
108 
109  // Pretty print this attribute.
110  void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
111  };
112 
113 class TypeAttr : public Attr {
114 protected:
115  TypeAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
116  attr::Kind AK, bool IsLateParsed)
117  : Attr(Context, CommonInfo, AK, IsLateParsed) {}
118 
119 public:
120  static bool classof(const Attr *A) {
121  return A->getKind() >= attr::FirstTypeAttr &&
122  A->getKind() <= attr::LastTypeAttr;
123  }
124 };
125 
126 class StmtAttr : public Attr {
127 protected:
128  StmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
129  attr::Kind AK, bool IsLateParsed)
130  : Attr(Context, CommonInfo, AK, IsLateParsed) {}
131 
132 public:
133  static bool classof(const Attr *A) {
134  return A->getKind() >= attr::FirstStmtAttr &&
135  A->getKind() <= attr::LastStmtAttr;
136  }
137 };
138 
139 class InheritableAttr : public Attr {
140 protected:
141  InheritableAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
142  attr::Kind AK, bool IsLateParsed,
144  : Attr(Context, CommonInfo, AK, IsLateParsed) {
145  this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
146  }
147 
148 public:
149  void setInherited(bool I) { Inherited = I; }
150 
151  /// Should this attribute be inherited from a prior declaration even if it's
152  /// explicitly provided in the current declaration?
155  }
156 
157  // Implement isa/cast/dyncast/etc.
158  static bool classof(const Attr *A) {
159  return A->getKind() >= attr::FirstInheritableAttr &&
160  A->getKind() <= attr::LastInheritableAttr;
161  }
162 };
163 
165 protected:
167  const AttributeCommonInfo &CommonInfo, attr::Kind AK,
169  : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
170  InheritEvenIfAlreadyPresent) {}
171 
172 public:
173  // Implement isa/cast/dyncast/etc.
174  static bool classof(const Attr *A) {
175  return A->getKind() >= attr::FirstInheritableParamAttr &&
176  A->getKind() <= attr::LastInheritableParamAttr;
177  }
178 };
179 
180 /// A parameter attribute which changes the argument-passing ABI rule
181 /// for the parameter.
183 protected:
184  ParameterABIAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
185  attr::Kind AK, bool IsLateParsed,
187  : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed,
188  InheritEvenIfAlreadyPresent) {}
189 
190 public:
192  switch (getKind()) {
193  case attr::SwiftContext:
195  case attr::SwiftErrorResult:
197  case attr::SwiftIndirectResult:
199  default:
200  llvm_unreachable("bad parameter ABI attribute kind");
201  }
202  }
203 
204  static bool classof(const Attr *A) {
205  return A->getKind() >= attr::FirstParameterABIAttr &&
206  A->getKind() <= attr::LastParameterABIAttr;
207  }
208 };
209 
210 /// A single parameter index whose accessors require each use to make explicit
211 /// the parameter index encoding needed.
212 class ParamIdx {
213  // Idx is exposed only via accessors that specify specific encodings.
214  unsigned Idx : 30;
215  unsigned HasThis : 1;
216  unsigned IsValid : 1;
217 
218  void assertComparable(const ParamIdx &I) const {
219  assert(isValid() && I.isValid() &&
220  "ParamIdx must be valid to be compared");
221  // It's possible to compare indices from separate functions, but so far
222  // it's not proven useful. Moreover, it might be confusing because a
223  // comparison on the results of getASTIndex might be inconsistent with a
224  // comparison on the ParamIdx objects themselves.
225  assert(HasThis == I.HasThis &&
226  "ParamIdx must be for the same function to be compared");
227  }
228 
229 public:
230  /// Construct an invalid parameter index (\c isValid returns false and
231  /// accessors fail an assert).
232  ParamIdx() : Idx(0), HasThis(false), IsValid(false) {}
233 
234  /// \param Idx is the parameter index as it is normally specified in
235  /// attributes in the source: one-origin including any C++ implicit this
236  /// parameter.
237  ///
238  /// \param D is the declaration containing the parameters. It is used to
239  /// determine if there is a C++ implicit this parameter.
240  ParamIdx(unsigned Idx, const Decl *D)
241  : Idx(Idx), HasThis(false), IsValid(true) {
242  assert(Idx >= 1 && "Idx must be one-origin");
243  if (const auto *FD = dyn_cast<FunctionDecl>(D))
244  HasThis = FD->isCXXInstanceMember();
245  }
246 
247  /// A type into which \c ParamIdx can be serialized.
248  ///
249  /// A static assertion that it's of the correct size follows the \c ParamIdx
250  /// class definition.
251  typedef uint32_t SerialType;
252 
253  /// Produce a representation that can later be passed to \c deserialize to
254  /// construct an equivalent \c ParamIdx.
255  SerialType serialize() const {
256  return *reinterpret_cast<const SerialType *>(this);
257  }
258 
259  /// Construct from a result from \c serialize.
260  static ParamIdx deserialize(SerialType S) {
261  ParamIdx P(*reinterpret_cast<ParamIdx *>(&S));
262  assert((!P.IsValid || P.Idx >= 1) && "valid Idx must be one-origin");
263  return P;
264  }
265 
266  /// Is this parameter index valid?
267  bool isValid() const { return IsValid; }
268 
269  /// Get the parameter index as it would normally be encoded for attributes at
270  /// the source level of representation: one-origin including any C++ implicit
271  /// this parameter.
272  ///
273  /// This encoding thus makes sense for diagnostics, pretty printing, and
274  /// constructing new attributes from a source-like specification.
275  unsigned getSourceIndex() const {
276  assert(isValid() && "ParamIdx must be valid");
277  return Idx;
278  }
279 
280  /// Get the parameter index as it would normally be encoded at the AST level
281  /// of representation: zero-origin not including any C++ implicit this
282  /// parameter.
283  ///
284  /// This is the encoding primarily used in Sema. However, in diagnostics,
285  /// Sema uses \c getSourceIndex instead.
286  unsigned getASTIndex() const {
287  assert(isValid() && "ParamIdx must be valid");
288  assert(Idx >= 1 + HasThis &&
289  "stored index must be base-1 and not specify C++ implicit this");
290  return Idx - 1 - HasThis;
291  }
292 
293  /// Get the parameter index as it would normally be encoded at the LLVM level
294  /// of representation: zero-origin including any C++ implicit this parameter.
295  ///
296  /// This is the encoding primarily used in CodeGen.
297  unsigned getLLVMIndex() const {
298  assert(isValid() && "ParamIdx must be valid");
299  assert(Idx >= 1 && "stored index must be base-1");
300  return Idx - 1;
301  }
302 
303  bool operator==(const ParamIdx &I) const {
304  assertComparable(I);
305  return Idx == I.Idx;
306  }
307  bool operator!=(const ParamIdx &I) const {
308  assertComparable(I);
309  return Idx != I.Idx;
310  }
311  bool operator<(const ParamIdx &I) const {
312  assertComparable(I);
313  return Idx < I.Idx;
314  }
315  bool operator>(const ParamIdx &I) const {
316  assertComparable(I);
317  return Idx > I.Idx;
318  }
319  bool operator<=(const ParamIdx &I) const {
320  assertComparable(I);
321  return Idx <= I.Idx;
322  }
323  bool operator>=(const ParamIdx &I) const {
324  assertComparable(I);
325  return Idx >= I.Idx;
326  }
327 };
328 
329 static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
330  "ParamIdx does not fit its serialization type");
331 
332 #include "clang/AST/Attrs.inc"
333 
335  const Attr *At) {
336  DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
338  return DB;
339 }
340 
342  const Attr *At) {
343  PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
345  return PD;
346 }
347 } // end namespace clang
348 
349 #endif
const char * getSpelling() const
ParamIdx()
Construct an invalid parameter index (isValid returns false and accessors fail an assert)...
Definition: Attr.h:232
C Language Family Type Representation.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const
unsigned Implicit
Definition: Attr.h:54
StringRef P
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
Definition: Attr.h:334
unsigned Inherited
An index into the spelling list of an attribute defined in Attr.td file.
Definition: Attr.h:52
Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed)
Definition: Attr.h:78
static bool classof(const Attr *A)
Definition: Attr.h:204
bool operator<=(const ParamIdx &I) const
Definition: Attr.h:319
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:37
static StringRef bytes(const std::vector< T, Allocator > &v)
Definition: ASTWriter.cpp:119
bool isValid() const
Is this parameter index valid?
Definition: Attr.h:267
Defines the clang::SanitizerKind enum.
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const
Definition: Diagnostic.h:1151
unsigned InheritEvenIfAlreadyPresent
Definition: Attr.h:58
bool isImplicit() const
Returns true if the attribute has been implicitly created instead of explicitly written by the user...
Definition: Attr.h:98
ParameterABI getABI() const
Definition: Attr.h:191
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
unsigned getSourceIndex() const
Get the parameter index as it would normally be encoded for attributes at the source level of represe...
Definition: Attr.h:275
Defines the clang::attr::Kind enum.
Defines some OpenMP-specific enums and functions.
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
static bool classof(const Attr *A)
Definition: Attr.h:133
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:1043
static bool classof(const Attr *A)
Definition: Attr.h:158
unsigned getLLVMIndex() const
Get the parameter index as it would normally be encoded at the LLVM level of representation: zero-ori...
Definition: Attr.h:297
bool operator<(const ParamIdx &I) const
Definition: Attr.h:311
bool operator!=(const ParamIdx &I) const
Definition: Attr.h:307
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
Definition: Attr.h:212
bool isPackExpansion() const
Definition: Attr.h:102
unsigned IsPackExpansion
Definition: Attr.h:53
bool shouldInheritEvenIfAlreadyPresent() const
Should this attribute be inherited from a prior declaration even if it&#39;s explicitly provided in the c...
Definition: Attr.h:153
bool operator==(const ParamIdx &I) const
Definition: Attr.h:303
InheritableParamAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
Definition: Attr.h:166
static bool classof(const Attr *A)
Definition: Attr.h:120
bool operator>(const ParamIdx &I) const
Definition: Attr.h:315
unsigned getASTIndex() const
Get the parameter index as it would normally be encoded at the AST level of representation: zero-orig...
Definition: Attr.h:286
A parameter attribute which changes the argument-passing ABI rule for the parameter.
Definition: Attr.h:182
void setImplicit(bool I)
Definition: Attr.h:99
#define false
Definition: stdbool.h:17
Encodes a location in the source.
Attr * clone(ASTContext &C) const
unsigned getSpellingListIndex() const
Definition: Attr.h:87
void setPackExpansion(bool PE)
Definition: Attr.h:101
ParamIdx(unsigned Idx, const Decl *D)
Definition: Attr.h:240
SourceLocation getLocation() const
Definition: Attr.h:92
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const
ParameterABI
Kinds of parameter ABI.
Definition: Specifiers.h:338
Dataflow Directional Tag Classes.
static ParamIdx deserialize(SerialType S)
Construct from a result from serialize.
Definition: Attr.h:260
bool isLateParsed() const
Definition: Attr.h:107
SerialType serialize() const
Produce a representation that can later be passed to deserialize to construct an equivalent ParamIdx...
Definition: Attr.h:255
uint32_t SerialType
A type into which ParamIdx can be serialized.
Definition: Attr.h:251
void setInherited(bool I)
Definition: Attr.h:149
static bool classof(const Attr *A)
Definition: Attr.h:174
Defines the clang::SourceLocation class and associated facilities.
ParameterABIAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
Definition: Attr.h:184
StmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed)
Definition: Attr.h:128
unsigned getAttributeSpellingListIndex() const
bool isInherited() const
Definition: Attr.h:94
bool operator>=(const ParamIdx &I) const
Definition: Attr.h:323
#define true
Definition: stdbool.h:16
TypeAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed)
Definition: Attr.h:115
unsigned IsLateParsed
Definition: Attr.h:57
attr::Kind getKind() const
Definition: Attr.h:85
SourceLocation getBegin() const
Attr - This represents one attribute.
Definition: Attr.h:45
This parameter (which must have pointer type) is a Swift indirect result parameter.
InheritableAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
Definition: Attr.h:141