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/Type.h" 20 #include "clang/Basic/AttrKinds.h" 21 #include "clang/Basic/LLVM.h" 22 #include "clang/Basic/SourceLocation.h" 23 #include "clang/Basic/VersionTuple.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/ADT/StringSwitch.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Support/raw_ostream.h" 29 #include <algorithm> 30 #include <cassert> 31 32 namespace clang { 33 class ASTContext; 34 class IdentifierInfo; 35 class ObjCInterfaceDecl; 36 class Expr; 37 class QualType; 38 class FunctionDecl; 39 class TypeSourceInfo; 40 41 /// Attr - This represents one attribute. 42 class Attr { 43 private: 44 SourceRange Range; 45 unsigned AttrKind : 16; 46 47 protected: 48 /// An index into the spelling list of an 49 /// attribute defined in Attr.td file. 50 unsigned SpellingListIndex : 4; 51 bool Inherited : 1; 52 bool IsPackExpansion : 1; 53 bool Implicit : 1; 54 55 virtual ~Attr(); 56 new(size_t bytes)57 void* operator new(size_t bytes) throw() { 58 llvm_unreachable("Attrs cannot be allocated with regular 'new'."); 59 } delete(void * data)60 void operator delete(void* data) throw() { 61 llvm_unreachable("Attrs cannot be released with regular 'delete'."); 62 } 63 64 public: 65 // Forward so that the regular new and delete do not hide global ones. 66 void* operator new(size_t Bytes, ASTContext &C, throw()67 size_t Alignment = 16) throw() { 68 return ::operator new(Bytes, C, Alignment); 69 } delete(void * Ptr,ASTContext & C,size_t Alignment)70 void operator delete(void *Ptr, ASTContext &C, 71 size_t Alignment) throw() { 72 return ::operator delete(Ptr, C, Alignment); 73 } 74 75 protected: 76 Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0) Range(R)77 : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex), 78 Inherited(false), IsPackExpansion(false), Implicit(false) {} 79 80 public: 81 getKind()82 attr::Kind getKind() const { 83 return static_cast<attr::Kind>(AttrKind); 84 } 85 getSpellingListIndex()86 unsigned getSpellingListIndex() const { return SpellingListIndex; } 87 virtual const char *getSpelling() const = 0; 88 getLocation()89 SourceLocation getLocation() const { return Range.getBegin(); } getRange()90 SourceRange getRange() const { return Range; } setRange(SourceRange R)91 void setRange(SourceRange R) { Range = R; } 92 isInherited()93 bool isInherited() const { return Inherited; } 94 95 /// \brief Returns true if the attribute has been implicitly created instead 96 /// of explicitly written by the user. isImplicit()97 bool isImplicit() const { return Implicit; } setImplicit(bool I)98 void setImplicit(bool I) { Implicit = I; } 99 setPackExpansion(bool PE)100 void setPackExpansion(bool PE) { IsPackExpansion = PE; } isPackExpansion()101 bool isPackExpansion() const { return IsPackExpansion; } 102 103 // Clone this attribute. 104 virtual Attr *clone(ASTContext &C) const = 0; 105 isLateParsed()106 virtual bool isLateParsed() const { return false; } 107 108 // Pretty print this attribute. 109 virtual void printPretty(raw_ostream &OS, 110 const PrintingPolicy &Policy) const = 0; 111 112 /// \brief By default, attributes cannot be duplicated when being merged; 113 /// however, an attribute can override this. Returns true if the attribute 114 /// can be duplicated when merging. duplicatesAllowed()115 virtual bool duplicatesAllowed() const { return false; } 116 }; 117 118 class InheritableAttr : public Attr { 119 virtual void anchor(); 120 protected: 121 InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0) Attr(AK,R,SpellingListIndex)122 : Attr(AK, R, SpellingListIndex) {} 123 124 public: setInherited(bool I)125 void setInherited(bool I) { Inherited = I; } 126 127 // Implement isa/cast/dyncast/etc. classof(const Attr * A)128 static bool classof(const Attr *A) { 129 return A->getKind() <= attr::LAST_INHERITABLE; 130 } 131 }; 132 133 class InheritableParamAttr : public InheritableAttr { 134 void anchor() override; 135 protected: 136 InheritableParamAttr(attr::Kind AK, SourceRange R, 137 unsigned SpellingListIndex = 0) InheritableAttr(AK,R,SpellingListIndex)138 : InheritableAttr(AK, R, SpellingListIndex) {} 139 140 public: 141 // Implement isa/cast/dyncast/etc. classof(const Attr * A)142 static bool classof(const Attr *A) { 143 // Relies on relative order of enum emission with respect to MS inheritance 144 // attrs. 145 return A->getKind() <= attr::LAST_INHERITABLE_PARAM; 146 } 147 }; 148 149 #include "clang/AST/Attrs.inc" 150 151 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 152 const Attr *At) { 153 DB.AddTaggedVal(reinterpret_cast<intptr_t>(At), 154 DiagnosticsEngine::ak_attr); 155 return DB; 156 } 157 158 inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, 159 const Attr *At) { 160 PD.AddTaggedVal(reinterpret_cast<intptr_t>(At), 161 DiagnosticsEngine::ak_attr); 162 return PD; 163 } 164 } // end namespace clang 165 166 #endif 167