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