| //======- AttributeCommonInfo.h - Base info about Attributes-----*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines the AttributeCommonInfo type, which is the base for a |
| // ParsedAttr and is used by Attr as a way to share info between the two. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H |
| #define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H |
| #include "clang/Basic/SourceLocation.h" |
| |
| namespace clang { |
| class IdentifierInfo; |
| class ASTRecordWriter; |
| |
| class AttributeCommonInfo { |
| public: |
| /// The style used to specify an attribute. |
| enum Syntax { |
| /// __attribute__((...)) |
| AS_GNU, |
| |
| /// [[...]] |
| AS_CXX11, |
| |
| /// [[...]] |
| AS_C2x, |
| |
| /// __declspec(...) |
| AS_Declspec, |
| |
| /// [uuid("...")] class Foo |
| AS_Microsoft, |
| |
| /// __ptr16, alignas(...), etc. |
| AS_Keyword, |
| |
| /// #pragma ... |
| AS_Pragma, |
| |
| // Note TableGen depends on the order above. Do not add or change the order |
| // without adding related code to TableGen/ClangAttrEmitter.cpp. |
| /// Context-sensitive version of a keyword attribute. |
| AS_ContextSensitiveKeyword, |
| }; |
| enum Kind { |
| #define PARSED_ATTR(NAME) AT_##NAME, |
| #include "clang/Sema/AttrParsedAttrList.inc" |
| #undef PARSED_ATTR |
| NoSemaHandlerAttribute, |
| IgnoredAttribute, |
| UnknownAttribute, |
| }; |
| |
| private: |
| const IdentifierInfo *AttrName = nullptr; |
| const IdentifierInfo *ScopeName = nullptr; |
| SourceRange AttrRange; |
| const SourceLocation ScopeLoc; |
| // Corresponds to the Kind enum. |
| unsigned AttrKind : 16; |
| /// Corresponds to the Syntax enum. |
| unsigned SyntaxUsed : 3; |
| unsigned SpellingIndex : 4; |
| |
| protected: |
| static constexpr unsigned SpellingNotCalculated = 0xf; |
| |
| public: |
| AttributeCommonInfo(SourceRange AttrRange) |
| : AttrRange(AttrRange), ScopeLoc(), AttrKind(0), SyntaxUsed(0), |
| SpellingIndex(SpellingNotCalculated) {} |
| |
| AttributeCommonInfo(SourceLocation AttrLoc) |
| : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0), |
| SpellingIndex(SpellingNotCalculated) {} |
| |
| AttributeCommonInfo(const IdentifierInfo *AttrName, |
| const IdentifierInfo *ScopeName, SourceRange AttrRange, |
| SourceLocation ScopeLoc, Syntax SyntaxUsed) |
| : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange), |
| ScopeLoc(ScopeLoc), |
| AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)), |
| SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {} |
| |
| AttributeCommonInfo(const IdentifierInfo *AttrName, |
| const IdentifierInfo *ScopeName, SourceRange AttrRange, |
| SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed) |
| : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange), |
| ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed), |
| SpellingIndex(SpellingNotCalculated) {} |
| |
| AttributeCommonInfo(const IdentifierInfo *AttrName, |
| const IdentifierInfo *ScopeName, SourceRange AttrRange, |
| SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed, |
| unsigned Spelling) |
| : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange), |
| ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed), |
| SpellingIndex(Spelling) {} |
| |
| AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange, |
| Syntax SyntaxUsed) |
| : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange), |
| ScopeLoc(), AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)), |
| SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {} |
| |
| AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed) |
| : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(), |
| AttrKind(K), SyntaxUsed(SyntaxUsed), |
| SpellingIndex(SpellingNotCalculated) {} |
| |
| AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed, |
| unsigned Spelling) |
| : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(), |
| AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {} |
| |
| AttributeCommonInfo(AttributeCommonInfo &&) = default; |
| AttributeCommonInfo(const AttributeCommonInfo &) = default; |
| |
| Kind getParsedKind() const { return Kind(AttrKind); } |
| Syntax getSyntax() const { return Syntax(SyntaxUsed); } |
| const IdentifierInfo *getAttrName() const { return AttrName; } |
| SourceLocation getLoc() const { return AttrRange.getBegin(); } |
| SourceRange getRange() const { return AttrRange; } |
| void setRange(SourceRange R) { AttrRange = R; } |
| |
| bool hasScope() const { return ScopeName; } |
| const IdentifierInfo *getScopeName() const { return ScopeName; } |
| SourceLocation getScopeLoc() const { return ScopeLoc; } |
| |
| bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } |
| bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; } |
| |
| bool isGNUScope() const; |
| |
| bool isAlignasAttribute() const { |
| // FIXME: Use a better mechanism to determine this. |
| return getParsedKind() == AT_Aligned && isKeywordAttribute(); |
| } |
| |
| bool isCXX11Attribute() const { |
| return SyntaxUsed == AS_CXX11 || isAlignasAttribute(); |
| } |
| |
| bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; } |
| |
| bool isKeywordAttribute() const { |
| return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword; |
| } |
| |
| bool isContextSensitiveKeywordAttribute() const { |
| return SyntaxUsed == AS_ContextSensitiveKeyword; |
| } |
| |
| unsigned getAttributeSpellingListIndex() const { |
| assert((isAttributeSpellingListCalculated() || AttrName) && |
| "Spelling cannot be found"); |
| return isAttributeSpellingListCalculated() |
| ? SpellingIndex |
| : calculateAttributeSpellingListIndex(); |
| } |
| void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; } |
| |
| static Kind getParsedKind(const IdentifierInfo *Name, |
| const IdentifierInfo *Scope, Syntax SyntaxUsed); |
| |
| private: |
| /// Get an index into the attribute spelling list |
| /// defined in Attr.td. This index is used by an attribute |
| /// to pretty print itself. |
| unsigned calculateAttributeSpellingListIndex() const; |
| |
| friend class clang::ASTRecordWriter; |
| // Used exclusively by ASTDeclWriter to get the raw spelling list state. |
| unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; } |
| |
| protected: |
| bool isAttributeSpellingListCalculated() const { |
| return SpellingIndex != SpellingNotCalculated; |
| } |
| }; |
| } // namespace clang |
| |
| #endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H |