clang  15.0.0git
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/ASTFwd.h"
17 #include "clang/AST/AttrIterator.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/Type.h"
20 #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 FunctionDecl;
38 class OMPTraitInfo;
39 
40 /// Attr - This represents one attribute.
41 class Attr : public AttributeCommonInfo {
42 private:
43  unsigned AttrKind : 16;
44 
45 protected:
46  /// An index into the spelling list of an
47  /// attribute defined in Attr.td file.
48  unsigned Inherited : 1;
49  unsigned IsPackExpansion : 1;
50  unsigned Implicit : 1;
51  // FIXME: These are properties of the attribute kind, not state for this
52  // instance of the attribute.
53  unsigned IsLateParsed : 1;
55 
56  void *operator new(size_t bytes) noexcept {
57  llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
58  }
59  void operator delete(void *data) noexcept {
60  llvm_unreachable("Attrs cannot be released with regular 'delete'.");
61  }
62 
63 public:
64  // Forward so that the regular new and delete do not hide global ones.
65  void *operator new(size_t Bytes, ASTContext &C,
66  size_t Alignment = 8) noexcept {
67  return ::operator new(Bytes, C, Alignment);
68  }
69  void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
70  return ::operator delete(Ptr, C, Alignment);
71  }
72 
73 protected:
74  Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
75  attr::Kind AK, bool IsLateParsed)
76  : AttributeCommonInfo(CommonInfo), AttrKind(AK), Inherited(false),
79 
80 public:
81  attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); }
82 
83  unsigned getSpellingListIndex() const {
85  }
86  const char *getSpelling() const;
87 
88  SourceLocation getLocation() const { return getRange().getBegin(); }
89 
90  bool isInherited() const { return Inherited; }
91 
92  /// Returns true if the attribute has been implicitly created instead
93  /// of explicitly written by the user.
94  bool isImplicit() const { return Implicit; }
95  void setImplicit(bool I) { Implicit = I; }
96 
97  void setPackExpansion(bool PE) { IsPackExpansion = PE; }
98  bool isPackExpansion() const { return IsPackExpansion; }
99 
100  // Clone this attribute.
101  Attr *clone(ASTContext &C) const;
102 
103  bool isLateParsed() const { return IsLateParsed; }
104 
105  // Pretty print this attribute.
106  void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
107 
108  static StringRef getDocumentation(attr::Kind);
109 };
110 
111 class TypeAttr : public Attr {
112 protected:
113  TypeAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
114  attr::Kind AK, bool IsLateParsed)
115  : Attr(Context, CommonInfo, AK, IsLateParsed) {}
116 
117 public:
118  static bool classof(const Attr *A) {
119  return A->getKind() >= attr::FirstTypeAttr &&
120  A->getKind() <= attr::LastTypeAttr;
121  }
122 };
123 
124 class StmtAttr : public Attr {
125 protected:
126  StmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
127  attr::Kind AK, bool IsLateParsed)
128  : Attr(Context, CommonInfo, AK, IsLateParsed) {}
129 
130 public:
131  static bool classof(const Attr *A) {
132  return A->getKind() >= attr::FirstStmtAttr &&
133  A->getKind() <= attr::LastStmtAttr;
134  }
135 };
136 
137 class InheritableAttr : public Attr {
138 protected:
139  InheritableAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
140  attr::Kind AK, bool IsLateParsed,
142  : Attr(Context, CommonInfo, AK, IsLateParsed) {
143  this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
144  }
145 
146 public:
147  void setInherited(bool I) { Inherited = I; }
148 
149  /// Should this attribute be inherited from a prior declaration even if it's
150  /// explicitly provided in the current declaration?
153  }
154 
155  // Implement isa/cast/dyncast/etc.
156  static bool classof(const Attr *A) {
157  return A->getKind() >= attr::FirstInheritableAttr &&
158  A->getKind() <= attr::LastInheritableAttr;
159  }
160 };
161 
163 protected:
164  DeclOrStmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
165  attr::Kind AK, bool IsLateParsed,
167  : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
169 
170 public:
171  static bool classof(const Attr *A) {
172  return A->getKind() >= attr::FirstDeclOrStmtAttr &&
173  A->getKind() <= attr::LastDeclOrStmtAttr;
174  }
175 };
176 
178 protected:
180  const AttributeCommonInfo &CommonInfo, attr::Kind AK,
182  : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
184 
185 public:
186  // Implement isa/cast/dyncast/etc.
187  static bool classof(const Attr *A) {
188  return A->getKind() >= attr::FirstInheritableParamAttr &&
189  A->getKind() <= attr::LastInheritableParamAttr;
190  }
191 };
192 
193 /// A parameter attribute which changes the argument-passing ABI rule
194 /// for the parameter.
196 protected:
197  ParameterABIAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
198  attr::Kind AK, bool IsLateParsed,
200  : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed,
202 
203 public:
205  switch (getKind()) {
206  case attr::SwiftContext:
208  case attr::SwiftAsyncContext:
210  case attr::SwiftErrorResult:
212  case attr::SwiftIndirectResult:
214  default:
215  llvm_unreachable("bad parameter ABI attribute kind");
216  }
217  }
218 
219  static bool classof(const Attr *A) {
220  return A->getKind() >= attr::FirstParameterABIAttr &&
221  A->getKind() <= attr::LastParameterABIAttr;
222  }
223 };
224 
225 /// A single parameter index whose accessors require each use to make explicit
226 /// the parameter index encoding needed.
227 class ParamIdx {
228  // Idx is exposed only via accessors that specify specific encodings.
229  unsigned Idx : 30;
230  unsigned HasThis : 1;
231  unsigned IsValid : 1;
232 
233  void assertComparable(const ParamIdx &I) const {
234  assert(isValid() && I.isValid() &&
235  "ParamIdx must be valid to be compared");
236  // It's possible to compare indices from separate functions, but so far
237  // it's not proven useful. Moreover, it might be confusing because a
238  // comparison on the results of getASTIndex might be inconsistent with a
239  // comparison on the ParamIdx objects themselves.
240  assert(HasThis == I.HasThis &&
241  "ParamIdx must be for the same function to be compared");
242  }
243 
244 public:
245  /// Construct an invalid parameter index (\c isValid returns false and
246  /// accessors fail an assert).
247  ParamIdx() : Idx(0), HasThis(false), IsValid(false) {}
248 
249  /// \param Idx is the parameter index as it is normally specified in
250  /// attributes in the source: one-origin including any C++ implicit this
251  /// parameter.
252  ///
253  /// \param D is the declaration containing the parameters. It is used to
254  /// determine if there is a C++ implicit this parameter.
255  ParamIdx(unsigned Idx, const Decl *D)
256  : Idx(Idx), HasThis(false), IsValid(true) {
257  assert(Idx >= 1 && "Idx must be one-origin");
258  if (const auto *FD = dyn_cast<FunctionDecl>(D))
259  HasThis = FD->isCXXInstanceMember();
260  }
261 
262  /// A type into which \c ParamIdx can be serialized.
263  ///
264  /// A static assertion that it's of the correct size follows the \c ParamIdx
265  /// class definition.
266  typedef uint32_t SerialType;
267 
268  /// Produce a representation that can later be passed to \c deserialize to
269  /// construct an equivalent \c ParamIdx.
271  return *reinterpret_cast<const SerialType *>(this);
272  }
273 
274  /// Construct from a result from \c serialize.
276  // Using this two-step static_cast via void * instead of reinterpret_cast
277  // silences a -Wstrict-aliasing false positive from GCC7 and earlier.
278  void *ParamIdxPtr = static_cast<void *>(&S);
279  ParamIdx P(*static_cast<ParamIdx *>(ParamIdxPtr));
280  assert((!P.IsValid || P.Idx >= 1) && "valid Idx must be one-origin");
281  return P;
282  }
283 
284  /// Is this parameter index valid?
285  bool isValid() const { return IsValid; }
286 
287  /// Get the parameter index as it would normally be encoded for attributes at
288  /// the source level of representation: one-origin including any C++ implicit
289  /// this parameter.
290  ///
291  /// This encoding thus makes sense for diagnostics, pretty printing, and
292  /// constructing new attributes from a source-like specification.
293  unsigned getSourceIndex() const {
294  assert(isValid() && "ParamIdx must be valid");
295  return Idx;
296  }
297 
298  /// Get the parameter index as it would normally be encoded at the AST level
299  /// of representation: zero-origin not including any C++ implicit this
300  /// parameter.
301  ///
302  /// This is the encoding primarily used in Sema. However, in diagnostics,
303  /// Sema uses \c getSourceIndex instead.
304  unsigned getASTIndex() const {
305  assert(isValid() && "ParamIdx must be valid");
306  assert(Idx >= 1 + HasThis &&
307  "stored index must be base-1 and not specify C++ implicit this");
308  return Idx - 1 - HasThis;
309  }
310 
311  /// Get the parameter index as it would normally be encoded at the LLVM level
312  /// of representation: zero-origin including any C++ implicit this parameter.
313  ///
314  /// This is the encoding primarily used in CodeGen.
315  unsigned getLLVMIndex() const {
316  assert(isValid() && "ParamIdx must be valid");
317  assert(Idx >= 1 && "stored index must be base-1");
318  return Idx - 1;
319  }
320 
321  bool operator==(const ParamIdx &I) const {
322  assertComparable(I);
323  return Idx == I.Idx;
324  }
325  bool operator!=(const ParamIdx &I) const {
326  assertComparable(I);
327  return Idx != I.Idx;
328  }
329  bool operator<(const ParamIdx &I) const {
330  assertComparable(I);
331  return Idx < I.Idx;
332  }
333  bool operator>(const ParamIdx &I) const {
334  assertComparable(I);
335  return Idx > I.Idx;
336  }
337  bool operator<=(const ParamIdx &I) const {
338  assertComparable(I);
339  return Idx <= I.Idx;
340  }
341  bool operator>=(const ParamIdx &I) const {
342  assertComparable(I);
343  return Idx >= I.Idx;
344  }
345 };
346 
347 static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
348  "ParamIdx does not fit its serialization type");
349 
350 /// Contains information gathered from parsing the contents of TargetAttr.
352  std::vector<std::string> Features;
353  StringRef Architecture;
354  StringRef Tune;
355  StringRef BranchProtection;
356  bool DuplicateArchitecture = false;
357  bool DuplicateTune = false;
358  bool operator ==(const ParsedTargetAttr &Other) const {
360  DuplicateTune == Other.DuplicateTune &&
361  Architecture == Other.Architecture &&
362  Tune == Other.Tune &&
364  Features == Other.Features;
365  }
366 };
367 
368 #include "clang/AST/Attrs.inc"
369 
371  const Attr *At) {
372  DB.AddTaggedVal(reinterpret_cast<uint64_t>(At), DiagnosticsEngine::ak_attr);
373  return DB;
374 }
375 } // end namespace clang
376 
377 #endif
clang::Attr::IsPackExpansion
unsigned IsPackExpansion
Definition: Attr.h:49
clang::ParamIdx::isValid
bool isValid() const
Is this parameter index valid?
Definition: Attr.h:285
clang::ParsedTargetAttr::Architecture
StringRef Architecture
Definition: Attr.h:353
clang::Attr::isImplicit
bool isImplicit() const
Returns true if the attribute has been implicitly created instead of explicitly written by the user.
Definition: Attr.h:94
AttributeCommonInfo.h
clang::ParameterABI::SwiftAsyncContext
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
clang::TypeAttr::TypeAttr
TypeAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed)
Definition: Attr.h:113
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::StmtAttr
Definition: Attr.h:124
clang::ParamIdx::ParamIdx
ParamIdx()
Construct an invalid parameter index (isValid returns false and accessors fail an assert).
Definition: Attr.h:247
clang::SourceRange::getBegin
SourceLocation getBegin() const
Definition: SourceLocation.h:219
clang::InheritableAttr::shouldInheritEvenIfAlreadyPresent
bool shouldInheritEvenIfAlreadyPresent() const
Should this attribute be inherited from a prior declaration even if it's explicitly provided in the c...
Definition: Attr.h:151
clang::Attr::getLocation
SourceLocation getLocation() const
Definition: Attr.h:88
clang::DeclOrStmtAttr
Definition: Attr.h:162
clang::ParsedTargetAttr
Contains information gathered from parsing the contents of TargetAttr.
Definition: Attr.h:351
clang::ParsedTargetAttr::BranchProtection
StringRef BranchProtection
Definition: Attr.h:355
clang::ParameterABIAttr::getABI
ParameterABI getABI() const
Definition: Attr.h:204
AttrIterator.h
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
clang::Attr::InheritEvenIfAlreadyPresent
unsigned InheritEvenIfAlreadyPresent
Definition: Attr.h:54
clang::Attr::Attr
Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed)
Definition: Attr.h:74
ASTFwd.h
clang::StreamingDiagnostic::AddTaggedVal
void AddTaggedVal(uint64_t V, DiagnosticsEngine::ArgumentKind Kind) const
Definition: Diagnostic.h:1184
clang::InheritableAttr::classof
static bool classof(const Attr *A)
Definition: Attr.h:156
clang::ParamIdx::operator<=
bool operator<=(const ParamIdx &I) const
Definition: Attr.h:337
clang::TypeAttr
Definition: Attr.h:111
Decl.h
uint64_t
unsigned long uint64_t
Definition: hlsl_basic_types.h:24
clang::InheritableAttr
Definition: Attr.h:137
clang::ParamIdx::operator<
bool operator<(const ParamIdx &I) const
Definition: Attr.h:329
clang::ParamIdx::getSourceIndex
unsigned getSourceIndex() const
Get the parameter index as it would normally be encoded for attributes at the source level of represe...
Definition: Attr.h:293
clang::ParameterABI
ParameterABI
Kinds of parameter ABI.
Definition: Specifiers.h:345
clang::InheritableAttr::setInherited
void setInherited(bool I)
Definition: Attr.h:147
clang::ParsedTargetAttr::DuplicateArchitecture
bool DuplicateArchitecture
Definition: Attr.h:356
clang::InheritableAttr::InheritableAttr
InheritableAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
Definition: Attr.h:139
clang::ParameterABIAttr::ParameterABIAttr
ParameterABIAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
Definition: Attr.h:197
clang::ParamIdx
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
Definition: Attr.h:227
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:208
clang::StreamingDiagnostic
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
Definition: Diagnostic.h:1110
LangOptions.h
clang::InheritableParamAttr::InheritableParamAttr
InheritableParamAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
Definition: Attr.h:179
clang::ParsedTargetAttr::operator==
bool operator==(const ParsedTargetAttr &Other) const
Definition: Attr.h:358
clang::DiagnosticsEngine::ak_attr
@ ak_attr
Attr *.
Definition: Diagnostic.h:248
OpenMPKinds.h
clang::TypeAttr::classof
static bool classof(const Attr *A)
Definition: Attr.h:118
clang::ParameterABI::SwiftIndirectResult
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
clang::Attr::getKind
attr::Kind getKind() const
Definition: Attr.h:81
clang::ParamIdx::getASTIndex
unsigned getASTIndex() const
Get the parameter index as it would normally be encoded at the AST level of representation: zero-orig...
Definition: Attr.h:304
clang::Attr::setPackExpansion
void setPackExpansion(bool PE)
Definition: Attr.h:97
Type.h
clang::ParamIdx::operator==
bool operator==(const ParamIdx &I) const
Definition: Attr.h:321
clang::StmtAttr::classof
static bool classof(const Attr *A)
Definition: Attr.h:131
clang::Attr::IsLateParsed
unsigned IsLateParsed
Definition: Attr.h:53
clang::Attr::Inherited
unsigned Inherited
An index into the spelling list of an attribute defined in Attr.td file.
Definition: Attr.h:48
clang::Attr::getDocumentation
static StringRef getDocumentation(attr::Kind)
Definition: AttrDocTable.cpp:23
clang::operator<<
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
Definition: ASTContext.cpp:12325
clang::ParamIdx::getLLVMIndex
unsigned getLLVMIndex() const
Get the parameter index as it would normally be encoded at the LLVM level of representation: zero-ori...
Definition: Attr.h:315
clang::ParsedTargetAttr::Tune
StringRef Tune
Definition: Attr.h:354
clang::ParamIdx::operator!=
bool operator!=(const ParamIdx &I) const
Definition: Attr.h:325
clang::ParamIdx::ParamIdx
ParamIdx(unsigned Idx, const Decl *D)
Definition: Attr.h:255
SourceLocation.h
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
clang::DeclOrStmtAttr::DeclOrStmtAttr
DeclOrStmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
Definition: Attr.h:164
clang::Attr::isInherited
bool isInherited() const
Definition: Attr.h:90
clang::Attr::clone
Attr * clone(ASTContext &C) const
clang::AttributeCommonInfo::getRange
SourceRange getRange() const
Definition: AttributeCommonInfo.h:133
clang::ParamIdx::operator>
bool operator>(const ParamIdx &I) const
Definition: Attr.h:333
clang::attr::Kind
Kind
Definition: AttrKinds.h:22
false
#define false
Definition: stdbool.h:22
clang::Attr::isPackExpansion
bool isPackExpansion() const
Definition: Attr.h:98
clang::ParameterABIAttr::classof
static bool classof(const Attr *A)
Definition: Attr.h:219
clang::DeclOrStmtAttr::classof
static bool classof(const Attr *A)
Definition: Attr.h:171
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::AttributeCommonInfo
Definition: AttributeCommonInfo.h:22
LLVM.h
clang::ParsedTargetAttr::DuplicateTune
bool DuplicateTune
Definition: Attr.h:357
clang::InheritableParamAttr::classof
static bool classof(const Attr *A)
Definition: Attr.h:187
bytes
static StringRef bytes(const std::vector< T, Allocator > &v)
Definition: ASTWriter.cpp:123
Sanitizers.h
clang::ParamIdx::SerialType
uint32_t SerialType
A type into which ParamIdx can be serialized.
Definition: Attr.h:266
clang::Attr::getSpelling
const char * getSpelling() const
clang::ParsedTargetAttr::Features
std::vector< std::string > Features
Definition: Attr.h:352
clang
Definition: CalledOnceCheck.h:17
clang::ParameterABI::SwiftErrorResult
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
clang::Attr::isLateParsed
bool isLateParsed() const
Definition: Attr.h:103
clang::StmtAttr::StmtAttr
StmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, attr::Kind AK, bool IsLateParsed)
Definition: Attr.h:126
clang::Attr
Attr - This represents one attribute.
Definition: Attr.h:41
clang::ParameterABI::SwiftContext
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
clang::ParamIdx::deserialize
static ParamIdx deserialize(SerialType S)
Construct from a result from serialize.
Definition: Attr.h:275
clang::Attr::setImplicit
void setImplicit(bool I)
Definition: Attr.h:95
clang::Attr::getSpellingListIndex
unsigned getSpellingListIndex() const
Definition: Attr.h:83
clang::ParamIdx::serialize
SerialType serialize() const
Produce a representation that can later be passed to deserialize to construct an equivalent ParamIdx.
Definition: Attr.h:270
clang::ParameterABIAttr
A parameter attribute which changes the argument-passing ABI rule for the parameter.
Definition: Attr.h:195
AttrKinds.h
clang::InheritableParamAttr
Definition: Attr.h:177
true
#define true
Definition: stdbool.h:21
clang::AttributeCommonInfo::getAttributeSpellingListIndex
unsigned getAttributeSpellingListIndex() const
Definition: AttributeCommonInfo.h:193
clang::Attr::printPretty
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const
clang::Attr::Implicit
unsigned Implicit
Definition: Attr.h:50
clang::ParamIdx::operator>=
bool operator>=(const ParamIdx &I) const
Definition: Attr.h:341