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