diff options
Diffstat (limited to 'include/clang/Basic/AttributeCommonInfo.h')
-rw-r--r-- | include/clang/Basic/AttributeCommonInfo.h | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/include/clang/Basic/AttributeCommonInfo.h b/include/clang/Basic/AttributeCommonInfo.h new file mode 100644 index 000000000000..545e7e9a2b47 --- /dev/null +++ b/include/clang/Basic/AttributeCommonInfo.h @@ -0,0 +1,190 @@ +//======- 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 |