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