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