1 //===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the Attr interface and subclasses. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_ATTR_H 15 #define LLVM_CLANG_AST_ATTR_H 16 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" 22 #include "clang/Basic/LLVM.h" 23 #include "clang/Basic/OpenMPKinds.h" 24 #include "clang/Basic/Sanitizers.h" 25 #include "clang/Basic/SourceLocation.h" 26 #include "clang/Basic/VersionTuple.h" 27 #include "llvm/ADT/SmallVector.h" 28 #include "llvm/ADT/StringRef.h" 29 #include "llvm/ADT/StringSwitch.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include <algorithm> 33 #include <cassert> 34 35 namespace clang { 36 class ASTContext; 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 { 46 private: 47 SourceRange Range; 48 unsigned AttrKind : 16; 49 50 protected: 51 /// An index into the spelling list of an 52 /// attribute defined in Attr.td file. 53 unsigned SpellingListIndex : 4; 54 unsigned Inherited : 1; 55 unsigned IsPackExpansion : 1; 56 unsigned Implicit : 1; 57 unsigned IsLateParsed : 1; 58 unsigned DuplicatesAllowed : 1; 59 new(size_t bytes)60 void *operator new(size_t bytes) LLVM_NOEXCEPT { 61 llvm_unreachable("Attrs cannot be allocated with regular 'new'."); 62 } delete(void * data)63 void operator delete(void *data) LLVM_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) LLVM_NOEXCEPT { 71 return ::operator new(Bytes, C, Alignment); 72 } delete(void * Ptr,ASTContext & C,size_t Alignment)73 void operator delete(void *Ptr, ASTContext &C, 74 size_t Alignment) LLVM_NOEXCEPT { 75 return ::operator delete(Ptr, C, Alignment); 76 } 77 78 protected: Attr(attr::Kind AK,SourceRange R,unsigned SpellingListIndex,bool IsLateParsed,bool DuplicatesAllowed)79 Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, 80 bool IsLateParsed, bool DuplicatesAllowed) 81 : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex), 82 Inherited(false), IsPackExpansion(false), Implicit(false), 83 IsLateParsed(IsLateParsed), DuplicatesAllowed(DuplicatesAllowed) {} 84 85 public: 86 getKind()87 attr::Kind getKind() const { 88 return static_cast<attr::Kind>(AttrKind); 89 } 90 getSpellingListIndex()91 unsigned getSpellingListIndex() const { return SpellingListIndex; } 92 const char *getSpelling() const; 93 getLocation()94 SourceLocation getLocation() const { return Range.getBegin(); } getRange()95 SourceRange getRange() const { return Range; } setRange(SourceRange R)96 void setRange(SourceRange R) { Range = R; } 97 isInherited()98 bool isInherited() const { return Inherited; } 99 100 /// \brief Returns true if the attribute has been implicitly created instead 101 /// of explicitly written by the user. isImplicit()102 bool isImplicit() const { return Implicit; } setImplicit(bool I)103 void setImplicit(bool I) { Implicit = I; } 104 setPackExpansion(bool PE)105 void setPackExpansion(bool PE) { IsPackExpansion = PE; } isPackExpansion()106 bool isPackExpansion() const { return IsPackExpansion; } 107 108 // Clone this attribute. 109 Attr *clone(ASTContext &C) const; 110 isLateParsed()111 bool isLateParsed() const { return IsLateParsed; } 112 113 // Pretty print this attribute. 114 void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const; 115 116 /// \brief By default, attributes cannot be duplicated when being merged; 117 /// however, an attribute can override this. Returns true if the attribute 118 /// can be duplicated when merging. duplicatesAllowed()119 bool duplicatesAllowed() const { return DuplicatesAllowed; } 120 }; 121 122 class StmtAttr : public Attr { 123 protected: StmtAttr(attr::Kind AK,SourceRange R,unsigned SpellingListIndex,bool IsLateParsed,bool DuplicatesAllowed)124 StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, 125 bool IsLateParsed, bool DuplicatesAllowed) 126 : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {} 127 128 public: classof(const Attr * A)129 static bool classof(const Attr *A) { 130 return A->getKind() >= attr::FirstStmtAttr && 131 A->getKind() <= attr::LastStmtAttr; 132 } 133 }; 134 135 class InheritableAttr : public Attr { 136 protected: InheritableAttr(attr::Kind AK,SourceRange R,unsigned SpellingListIndex,bool IsLateParsed,bool DuplicatesAllowed)137 InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, 138 bool IsLateParsed, bool DuplicatesAllowed) 139 : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {} 140 141 public: setInherited(bool I)142 void setInherited(bool I) { Inherited = I; } 143 144 // Implement isa/cast/dyncast/etc. classof(const Attr * A)145 static bool classof(const Attr *A) { 146 return A->getKind() >= attr::FirstInheritableAttr && 147 A->getKind() <= attr::LastInheritableAttr; 148 } 149 }; 150 151 class InheritableParamAttr : public InheritableAttr { 152 protected: InheritableParamAttr(attr::Kind AK,SourceRange R,unsigned SpellingListIndex,bool IsLateParsed,bool DuplicatesAllowed)153 InheritableParamAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, 154 bool IsLateParsed, bool DuplicatesAllowed) 155 : InheritableAttr(AK, R, SpellingListIndex, IsLateParsed, 156 DuplicatesAllowed) {} 157 158 public: 159 // Implement isa/cast/dyncast/etc. classof(const Attr * A)160 static bool classof(const Attr *A) { 161 return A->getKind() >= attr::FirstInheritableParamAttr && 162 A->getKind() <= attr::LastInheritableParamAttr; 163 } 164 }; 165 166 /// A parameter attribute which changes the argument-passing ABI rule 167 /// for the parameter. 168 class ParameterABIAttr : public InheritableParamAttr { 169 protected: ParameterABIAttr(attr::Kind AK,SourceRange R,unsigned SpellingListIndex,bool IsLateParsed,bool DuplicatesAllowed)170 ParameterABIAttr(attr::Kind AK, SourceRange R, 171 unsigned SpellingListIndex, bool IsLateParsed, 172 bool DuplicatesAllowed) 173 : InheritableParamAttr(AK, R, SpellingListIndex, IsLateParsed, 174 DuplicatesAllowed) {} 175 176 public: getABI()177 ParameterABI getABI() const { 178 switch (getKind()) { 179 case attr::SwiftContext: 180 return ParameterABI::SwiftContext; 181 case attr::SwiftErrorResult: 182 return ParameterABI::SwiftErrorResult; 183 case attr::SwiftIndirectResult: 184 return ParameterABI::SwiftIndirectResult; 185 default: 186 llvm_unreachable("bad parameter ABI attribute kind"); 187 } 188 } 189 classof(const Attr * A)190 static bool classof(const Attr *A) { 191 return A->getKind() >= attr::FirstParameterABIAttr && 192 A->getKind() <= attr::LastParameterABIAttr; 193 } 194 }; 195 196 #include "clang/AST/Attrs.inc" 197 198 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 199 const Attr *At) { 200 DB.AddTaggedVal(reinterpret_cast<intptr_t>(At), 201 DiagnosticsEngine::ak_attr); 202 return DB; 203 } 204 205 inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 206 const Attr *At) { 207 PD.AddTaggedVal(reinterpret_cast<intptr_t>(At), 208 DiagnosticsEngine::ak_attr); 209 return PD; 210 } 211 } // end namespace clang 212 213 #endif 214