1 //======- AttributeCommonInfo.h - Base info about 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 AttributeCommonInfo type, which is the base for a 10 // ParsedAttr and is used by Attr as a way to share info between the two. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H 15 #define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H 16 #include "clang/Basic/SourceLocation.h" 17 18 namespace clang { 19 class IdentifierInfo; 20 class ASTRecordWriter; 21 22 class AttributeCommonInfo { 23 public: 24 /// The style used to specify an attribute. 25 enum Syntax { 26 /// __attribute__((...)) 27 AS_GNU, 28 29 /// [[...]] 30 AS_CXX11, 31 32 /// [[...]] 33 AS_C2x, 34 35 /// __declspec(...) 36 AS_Declspec, 37 38 /// [uuid("...")] class Foo 39 AS_Microsoft, 40 41 /// __ptr16, alignas(...), etc. 42 AS_Keyword, 43 44 /// #pragma ... 45 AS_Pragma, 46 47 // Note TableGen depends on the order above. Do not add or change the order 48 // without adding related code to TableGen/ClangAttrEmitter.cpp. 49 /// Context-sensitive version of a keyword attribute. 50 AS_ContextSensitiveKeyword, 51 }; 52 enum Kind { 53 #define PARSED_ATTR(NAME) AT_##NAME, 54 #include "clang/Sema/AttrParsedAttrList.inc" 55 #undef PARSED_ATTR 56 NoSemaHandlerAttribute, 57 IgnoredAttribute, 58 UnknownAttribute, 59 }; 60 61 private: 62 const IdentifierInfo *AttrName = nullptr; 63 const IdentifierInfo *ScopeName = nullptr; 64 SourceRange AttrRange; 65 const SourceLocation ScopeLoc; 66 // Corresponds to the Kind enum. 67 unsigned AttrKind : 16; 68 /// Corresponds to the Syntax enum. 69 unsigned SyntaxUsed : 3; 70 unsigned SpellingIndex : 4; 71 72 protected: 73 static constexpr unsigned SpellingNotCalculated = 0xf; 74 75 public: AttributeCommonInfo(SourceRange AttrRange)76 AttributeCommonInfo(SourceRange AttrRange) 77 : AttrRange(AttrRange), ScopeLoc(), AttrKind(0), SyntaxUsed(0), 78 SpellingIndex(SpellingNotCalculated) {} 79 AttributeCommonInfo(SourceLocation AttrLoc)80 AttributeCommonInfo(SourceLocation AttrLoc) 81 : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0), 82 SpellingIndex(SpellingNotCalculated) {} 83 AttributeCommonInfo(const IdentifierInfo * AttrName,const IdentifierInfo * ScopeName,SourceRange AttrRange,SourceLocation ScopeLoc,Syntax SyntaxUsed)84 AttributeCommonInfo(const IdentifierInfo *AttrName, 85 const IdentifierInfo *ScopeName, SourceRange AttrRange, 86 SourceLocation ScopeLoc, Syntax SyntaxUsed) 87 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange), 88 ScopeLoc(ScopeLoc), 89 AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)), 90 SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {} 91 AttributeCommonInfo(const IdentifierInfo * AttrName,const IdentifierInfo * ScopeName,SourceRange AttrRange,SourceLocation ScopeLoc,Kind AttrKind,Syntax SyntaxUsed)92 AttributeCommonInfo(const IdentifierInfo *AttrName, 93 const IdentifierInfo *ScopeName, SourceRange AttrRange, 94 SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed) 95 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange), 96 ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed), 97 SpellingIndex(SpellingNotCalculated) {} 98 AttributeCommonInfo(const IdentifierInfo * AttrName,const IdentifierInfo * ScopeName,SourceRange AttrRange,SourceLocation ScopeLoc,Kind AttrKind,Syntax SyntaxUsed,unsigned Spelling)99 AttributeCommonInfo(const IdentifierInfo *AttrName, 100 const IdentifierInfo *ScopeName, SourceRange AttrRange, 101 SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed, 102 unsigned Spelling) 103 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange), 104 ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed), 105 SpellingIndex(Spelling) {} 106 AttributeCommonInfo(const IdentifierInfo * AttrName,SourceRange AttrRange,Syntax SyntaxUsed)107 AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange, 108 Syntax SyntaxUsed) 109 : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange), 110 ScopeLoc(), AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)), 111 SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {} 112 AttributeCommonInfo(SourceRange AttrRange,Kind K,Syntax SyntaxUsed)113 AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed) 114 : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(), 115 AttrKind(K), SyntaxUsed(SyntaxUsed), 116 SpellingIndex(SpellingNotCalculated) {} 117 AttributeCommonInfo(SourceRange AttrRange,Kind K,Syntax SyntaxUsed,unsigned Spelling)118 AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed, 119 unsigned Spelling) 120 : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(), 121 AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {} 122 123 AttributeCommonInfo(AttributeCommonInfo &&) = default; 124 AttributeCommonInfo(const AttributeCommonInfo &) = default; 125 getParsedKind()126 Kind getParsedKind() const { return Kind(AttrKind); } getSyntax()127 Syntax getSyntax() const { return Syntax(SyntaxUsed); } getAttrName()128 const IdentifierInfo *getAttrName() const { return AttrName; } getLoc()129 SourceLocation getLoc() const { return AttrRange.getBegin(); } getRange()130 SourceRange getRange() const { return AttrRange; } setRange(SourceRange R)131 void setRange(SourceRange R) { AttrRange = R; } 132 hasScope()133 bool hasScope() const { return ScopeName; } getScopeName()134 const IdentifierInfo *getScopeName() const { return ScopeName; } getScopeLoc()135 SourceLocation getScopeLoc() const { return ScopeLoc; } 136 137 /// Gets the normalized full name, which consists of both scope and name and 138 /// with surrounding underscores removed as appropriate (e.g. 139 /// __gnu__::__attr__ will be normalized to gnu::attr). 140 std::string getNormalizedFullName() const; 141 isDeclspecAttribute()142 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } isMicrosoftAttribute()143 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; } 144 145 bool isGNUScope() const; 146 isAlignasAttribute()147 bool isAlignasAttribute() const { 148 // FIXME: Use a better mechanism to determine this. 149 return getParsedKind() == AT_Aligned && isKeywordAttribute(); 150 } 151 isCXX11Attribute()152 bool isCXX11Attribute() const { 153 return SyntaxUsed == AS_CXX11 || isAlignasAttribute(); 154 } 155 isC2xAttribute()156 bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; } 157 isKeywordAttribute()158 bool isKeywordAttribute() const { 159 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword; 160 } 161 isContextSensitiveKeywordAttribute()162 bool isContextSensitiveKeywordAttribute() const { 163 return SyntaxUsed == AS_ContextSensitiveKeyword; 164 } 165 getAttributeSpellingListIndex()166 unsigned getAttributeSpellingListIndex() const { 167 assert((isAttributeSpellingListCalculated() || AttrName) && 168 "Spelling cannot be found"); 169 return isAttributeSpellingListCalculated() 170 ? SpellingIndex 171 : calculateAttributeSpellingListIndex(); 172 } setAttributeSpellingListIndex(unsigned V)173 void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; } 174 175 static Kind getParsedKind(const IdentifierInfo *Name, 176 const IdentifierInfo *Scope, Syntax SyntaxUsed); 177 178 private: 179 /// Get an index into the attribute spelling list 180 /// defined in Attr.td. This index is used by an attribute 181 /// to pretty print itself. 182 unsigned calculateAttributeSpellingListIndex() const; 183 184 friend class clang::ASTRecordWriter; 185 // Used exclusively by ASTDeclWriter to get the raw spelling list state. getAttributeSpellingListIndexRaw()186 unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; } 187 188 protected: isAttributeSpellingListCalculated()189 bool isAttributeSpellingListCalculated() const { 190 return SpellingIndex != SpellingNotCalculated; 191 } 192 }; 193 } // namespace clang 194 195 #endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H 196