123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- Attr.h - Classes for representing 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 Attr interface and subclasses.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_ATTR_H
- #define LLVM_CLANG_AST_ATTR_H
- #include "clang/AST/ASTFwd.h"
- #include "clang/AST/AttrIterator.h"
- #include "clang/AST/Decl.h"
- #include "clang/AST/Type.h"
- #include "clang/Basic/AttrKinds.h"
- #include "clang/Basic/AttributeCommonInfo.h"
- #include "clang/Basic/LangOptions.h"
- #include "clang/Basic/LLVM.h"
- #include "clang/Basic/OpenMPKinds.h"
- #include "clang/Basic/Sanitizers.h"
- #include "clang/Basic/SourceLocation.h"
- #include "llvm/ADT/StringSwitch.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/VersionTuple.h"
- #include "llvm/Support/raw_ostream.h"
- #include <algorithm>
- #include <cassert>
- namespace clang {
- class ASTContext;
- class AttributeCommonInfo;
- class FunctionDecl;
- class OMPTraitInfo;
- /// Attr - This represents one attribute.
- class Attr : public AttributeCommonInfo {
- private:
- unsigned AttrKind : 16;
- protected:
- /// An index into the spelling list of an
- /// attribute defined in Attr.td file.
- unsigned Inherited : 1;
- unsigned IsPackExpansion : 1;
- unsigned Implicit : 1;
- // FIXME: These are properties of the attribute kind, not state for this
- // instance of the attribute.
- unsigned IsLateParsed : 1;
- unsigned InheritEvenIfAlreadyPresent : 1;
- void *operator new(size_t bytes) noexcept {
- llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
- }
- void operator delete(void *data) noexcept {
- llvm_unreachable("Attrs cannot be released with regular 'delete'.");
- }
- public:
- // Forward so that the regular new and delete do not hide global ones.
- void *operator new(size_t Bytes, ASTContext &C,
- size_t Alignment = 8) noexcept {
- return ::operator new(Bytes, C, Alignment);
- }
- void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
- return ::operator delete(Ptr, C, Alignment);
- }
- protected:
- Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed)
- : AttributeCommonInfo(CommonInfo), AttrKind(AK), Inherited(false),
- IsPackExpansion(false), Implicit(false), IsLateParsed(IsLateParsed),
- InheritEvenIfAlreadyPresent(false) {}
- public:
- attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); }
- unsigned getSpellingListIndex() const {
- return getAttributeSpellingListIndex();
- }
- const char *getSpelling() const;
- SourceLocation getLocation() const { return getRange().getBegin(); }
- bool isInherited() const { return Inherited; }
- /// Returns true if the attribute has been implicitly created instead
- /// of explicitly written by the user.
- bool isImplicit() const { return Implicit; }
- void setImplicit(bool I) { Implicit = I; }
- void setPackExpansion(bool PE) { IsPackExpansion = PE; }
- bool isPackExpansion() const { return IsPackExpansion; }
- // Clone this attribute.
- Attr *clone(ASTContext &C) const;
- bool isLateParsed() const { return IsLateParsed; }
- // Pretty print this attribute.
- void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
- static StringRef getDocumentation(attr::Kind);
- };
- class TypeAttr : public Attr {
- protected:
- TypeAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed)
- : Attr(Context, CommonInfo, AK, IsLateParsed) {}
- public:
- static bool classof(const Attr *A) {
- return A->getKind() >= attr::FirstTypeAttr &&
- A->getKind() <= attr::LastTypeAttr;
- }
- };
- class StmtAttr : public Attr {
- protected:
- StmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed)
- : Attr(Context, CommonInfo, AK, IsLateParsed) {}
- public:
- static bool classof(const Attr *A) {
- return A->getKind() >= attr::FirstStmtAttr &&
- A->getKind() <= attr::LastStmtAttr;
- }
- };
- class InheritableAttr : public Attr {
- protected:
- InheritableAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed,
- bool InheritEvenIfAlreadyPresent)
- : Attr(Context, CommonInfo, AK, IsLateParsed) {
- this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
- }
- public:
- void setInherited(bool I) { Inherited = I; }
- /// Should this attribute be inherited from a prior declaration even if it's
- /// explicitly provided in the current declaration?
- bool shouldInheritEvenIfAlreadyPresent() const {
- return InheritEvenIfAlreadyPresent;
- }
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() >= attr::FirstInheritableAttr &&
- A->getKind() <= attr::LastInheritableAttr;
- }
- };
- class DeclOrStmtAttr : public InheritableAttr {
- protected:
- DeclOrStmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed,
- bool InheritEvenIfAlreadyPresent)
- : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
- InheritEvenIfAlreadyPresent) {}
- public:
- static bool classof(const Attr *A) {
- return A->getKind() >= attr::FirstDeclOrStmtAttr &&
- A->getKind() <= attr::LastDeclOrStmtAttr;
- }
- };
- class InheritableParamAttr : public InheritableAttr {
- protected:
- InheritableParamAttr(ASTContext &Context,
- const AttributeCommonInfo &CommonInfo, attr::Kind AK,
- bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
- : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
- InheritEvenIfAlreadyPresent) {}
- public:
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() >= attr::FirstInheritableParamAttr &&
- A->getKind() <= attr::LastInheritableParamAttr;
- }
- };
- /// A parameter attribute which changes the argument-passing ABI rule
- /// for the parameter.
- class ParameterABIAttr : public InheritableParamAttr {
- protected:
- ParameterABIAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed,
- bool InheritEvenIfAlreadyPresent)
- : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed,
- InheritEvenIfAlreadyPresent) {}
- public:
- ParameterABI getABI() const {
- switch (getKind()) {
- case attr::SwiftContext:
- return ParameterABI::SwiftContext;
- case attr::SwiftAsyncContext:
- return ParameterABI::SwiftAsyncContext;
- case attr::SwiftErrorResult:
- return ParameterABI::SwiftErrorResult;
- case attr::SwiftIndirectResult:
- return ParameterABI::SwiftIndirectResult;
- default:
- llvm_unreachable("bad parameter ABI attribute kind");
- }
- }
- static bool classof(const Attr *A) {
- return A->getKind() >= attr::FirstParameterABIAttr &&
- A->getKind() <= attr::LastParameterABIAttr;
- }
- };
- /// A single parameter index whose accessors require each use to make explicit
- /// the parameter index encoding needed.
- class ParamIdx {
- // Idx is exposed only via accessors that specify specific encodings.
- unsigned Idx : 30;
- unsigned HasThis : 1;
- unsigned IsValid : 1;
- void assertComparable(const ParamIdx &I) const {
- assert(isValid() && I.isValid() &&
- "ParamIdx must be valid to be compared");
- // It's possible to compare indices from separate functions, but so far
- // it's not proven useful. Moreover, it might be confusing because a
- // comparison on the results of getASTIndex might be inconsistent with a
- // comparison on the ParamIdx objects themselves.
- assert(HasThis == I.HasThis &&
- "ParamIdx must be for the same function to be compared");
- }
- public:
- /// Construct an invalid parameter index (\c isValid returns false and
- /// accessors fail an assert).
- ParamIdx() : Idx(0), HasThis(false), IsValid(false) {}
- /// \param Idx is the parameter index as it is normally specified in
- /// attributes in the source: one-origin including any C++ implicit this
- /// parameter.
- ///
- /// \param D is the declaration containing the parameters. It is used to
- /// determine if there is a C++ implicit this parameter.
- ParamIdx(unsigned Idx, const Decl *D)
- : Idx(Idx), HasThis(false), IsValid(true) {
- assert(Idx >= 1 && "Idx must be one-origin");
- if (const auto *FD = dyn_cast<FunctionDecl>(D))
- HasThis = FD->isCXXInstanceMember();
- }
- /// A type into which \c ParamIdx can be serialized.
- ///
- /// A static assertion that it's of the correct size follows the \c ParamIdx
- /// class definition.
- typedef uint32_t SerialType;
- /// Produce a representation that can later be passed to \c deserialize to
- /// construct an equivalent \c ParamIdx.
- SerialType serialize() const {
- return *reinterpret_cast<const SerialType *>(this);
- }
- /// Construct from a result from \c serialize.
- static ParamIdx deserialize(SerialType S) {
- // Using this two-step static_cast via void * instead of reinterpret_cast
- // silences a -Wstrict-aliasing false positive from GCC7 and earlier.
- void *ParamIdxPtr = static_cast<void *>(&S);
- ParamIdx P(*static_cast<ParamIdx *>(ParamIdxPtr));
- assert((!P.IsValid || P.Idx >= 1) && "valid Idx must be one-origin");
- return P;
- }
- /// Is this parameter index valid?
- bool isValid() const { return IsValid; }
- /// Get the parameter index as it would normally be encoded for attributes at
- /// the source level of representation: one-origin including any C++ implicit
- /// this parameter.
- ///
- /// This encoding thus makes sense for diagnostics, pretty printing, and
- /// constructing new attributes from a source-like specification.
- unsigned getSourceIndex() const {
- assert(isValid() && "ParamIdx must be valid");
- return Idx;
- }
- /// Get the parameter index as it would normally be encoded at the AST level
- /// of representation: zero-origin not including any C++ implicit this
- /// parameter.
- ///
- /// This is the encoding primarily used in Sema. However, in diagnostics,
- /// Sema uses \c getSourceIndex instead.
- unsigned getASTIndex() const {
- assert(isValid() && "ParamIdx must be valid");
- assert(Idx >= 1 + HasThis &&
- "stored index must be base-1 and not specify C++ implicit this");
- return Idx - 1 - HasThis;
- }
- /// Get the parameter index as it would normally be encoded at the LLVM level
- /// of representation: zero-origin including any C++ implicit this parameter.
- ///
- /// This is the encoding primarily used in CodeGen.
- unsigned getLLVMIndex() const {
- assert(isValid() && "ParamIdx must be valid");
- assert(Idx >= 1 && "stored index must be base-1");
- return Idx - 1;
- }
- bool operator==(const ParamIdx &I) const {
- assertComparable(I);
- return Idx == I.Idx;
- }
- bool operator!=(const ParamIdx &I) const {
- assertComparable(I);
- return Idx != I.Idx;
- }
- bool operator<(const ParamIdx &I) const {
- assertComparable(I);
- return Idx < I.Idx;
- }
- bool operator>(const ParamIdx &I) const {
- assertComparable(I);
- return Idx > I.Idx;
- }
- bool operator<=(const ParamIdx &I) const {
- assertComparable(I);
- return Idx <= I.Idx;
- }
- bool operator>=(const ParamIdx &I) const {
- assertComparable(I);
- return Idx >= I.Idx;
- }
- };
- static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
- "ParamIdx does not fit its serialization type");
- /// Contains information gathered from parsing the contents of TargetAttr.
- struct ParsedTargetAttr {
- std::vector<std::string> Features;
- StringRef Architecture;
- StringRef Tune;
- StringRef BranchProtection;
- bool DuplicateArchitecture = false;
- bool DuplicateTune = false;
- bool operator ==(const ParsedTargetAttr &Other) const {
- return DuplicateArchitecture == Other.DuplicateArchitecture &&
- DuplicateTune == Other.DuplicateTune &&
- Architecture == Other.Architecture &&
- Tune == Other.Tune &&
- BranchProtection == Other.BranchProtection &&
- Features == Other.Features;
- }
- };
- #include "clang/AST/Attrs.inc"
- inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
- const Attr *At) {
- DB.AddTaggedVal(reinterpret_cast<uint64_t>(At), DiagnosticsEngine::ak_attr);
- return DB;
- }
- } // end namespace clang
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|