Index: vendor/clang/dist-release_70/include/clang/AST/DeclBase.h =================================================================== --- vendor/clang/dist-release_70/include/clang/AST/DeclBase.h (revision 341729) +++ vendor/clang/dist-release_70/include/clang/AST/DeclBase.h (revision 341730) @@ -1,2075 +1,2074 @@ //===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the Decl and DeclContext interfaces. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_DECLBASE_H #define LLVM_CLANG_AST_DECLBASE_H #include "clang/AST/AttrIterator.h" #include "clang/AST/DeclarationName.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/VersionTuple.h" #include #include #include #include #include #include #include namespace clang { class ASTContext; class ASTMutationListener; class Attr; class DeclContext; class ExternalSourceSymbolAttr; class FunctionDecl; class FunctionType; class IdentifierInfo; enum Linkage : unsigned char; class LinkageSpecDecl; class Module; class NamedDecl; class ObjCCategoryDecl; class ObjCCategoryImplDecl; class ObjCContainerDecl; class ObjCImplDecl; class ObjCImplementationDecl; class ObjCInterfaceDecl; class ObjCMethodDecl; class ObjCProtocolDecl; struct PrintingPolicy; class RecordDecl; class SourceManager; class Stmt; class StoredDeclsMap; class TemplateDecl; class TranslationUnitDecl; class UsingDirectiveDecl; /// Captures the result of checking the availability of a /// declaration. enum AvailabilityResult { AR_Available = 0, AR_NotYetIntroduced, AR_Deprecated, AR_Unavailable }; /// Decl - This represents one declaration (or definition), e.g. a variable, /// typedef, function, struct, etc. /// /// Note: There are objects tacked on before the *beginning* of Decl /// (and its subclasses) in its Decl::operator new(). Proper alignment /// of all subclasses (not requiring more than the alignment of Decl) is /// asserted in DeclBase.cpp. class alignas(8) Decl { public: /// Lists the kind of concrete classes of Decl. enum Kind { #define DECL(DERIVED, BASE) DERIVED, #define ABSTRACT_DECL(DECL) #define DECL_RANGE(BASE, START, END) \ first##BASE = START, last##BASE = END, #define LAST_DECL_RANGE(BASE, START, END) \ first##BASE = START, last##BASE = END #include "clang/AST/DeclNodes.inc" }; /// A placeholder type used to construct an empty shell of a /// decl-derived type that will be filled in later (e.g., by some /// deserialization method). struct EmptyShell {}; /// IdentifierNamespace - The different namespaces in which /// declarations may appear. According to C99 6.2.3, there are /// four namespaces, labels, tags, members and ordinary /// identifiers. C++ describes lookup completely differently: /// certain lookups merely "ignore" certain kinds of declarations, /// usually based on whether the declaration is of a type, etc. /// /// These are meant as bitmasks, so that searches in /// C++ can look into the "tag" namespace during ordinary lookup. /// /// Decl currently provides 15 bits of IDNS bits. enum IdentifierNamespace { /// Labels, declared with 'x:' and referenced with 'goto x'. IDNS_Label = 0x0001, /// Tags, declared with 'struct foo;' and referenced with /// 'struct foo'. All tags are also types. This is what /// elaborated-type-specifiers look for in C. /// This also contains names that conflict with tags in the /// same scope but that are otherwise ordinary names (non-type /// template parameters and indirect field declarations). IDNS_Tag = 0x0002, /// Types, declared with 'struct foo', typedefs, etc. /// This is what elaborated-type-specifiers look for in C++, /// but note that it's ill-formed to find a non-tag. IDNS_Type = 0x0004, /// Members, declared with object declarations within tag /// definitions. In C, these can only be found by "qualified" /// lookup in member expressions. In C++, they're found by /// normal lookup. IDNS_Member = 0x0008, /// Namespaces, declared with 'namespace foo {}'. /// Lookup for nested-name-specifiers find these. IDNS_Namespace = 0x0010, /// Ordinary names. In C, everything that's not a label, tag, /// member, or function-local extern ends up here. IDNS_Ordinary = 0x0020, /// Objective C \@protocol. IDNS_ObjCProtocol = 0x0040, /// This declaration is a friend function. A friend function /// declaration is always in this namespace but may also be in /// IDNS_Ordinary if it was previously declared. IDNS_OrdinaryFriend = 0x0080, /// This declaration is a friend class. A friend class /// declaration is always in this namespace but may also be in /// IDNS_Tag|IDNS_Type if it was previously declared. IDNS_TagFriend = 0x0100, /// This declaration is a using declaration. A using declaration /// *introduces* a number of other declarations into the current /// scope, and those declarations use the IDNS of their targets, /// but the actual using declarations go in this namespace. IDNS_Using = 0x0200, /// This declaration is a C++ operator declared in a non-class /// context. All such operators are also in IDNS_Ordinary. /// C++ lexical operator lookup looks for these. IDNS_NonMemberOperator = 0x0400, /// This declaration is a function-local extern declaration of a /// variable or function. This may also be IDNS_Ordinary if it /// has been declared outside any function. These act mostly like /// invisible friend declarations, but are also visible to unqualified /// lookup within the scope of the declaring function. IDNS_LocalExtern = 0x0800, /// This declaration is an OpenMP user defined reduction construction. IDNS_OMPReduction = 0x1000 }; /// ObjCDeclQualifier - 'Qualifiers' written next to the return and /// parameter types in method declarations. Other than remembering /// them and mangling them into the method's signature string, these /// are ignored by the compiler; they are consumed by certain /// remote-messaging frameworks. /// /// in, inout, and out are mutually exclusive and apply only to /// method parameters. bycopy and byref are mutually exclusive and /// apply only to method parameters (?). oneway applies only to /// results. All of these expect their corresponding parameter to /// have a particular type. None of this is currently enforced by /// clang. /// /// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier. enum ObjCDeclQualifier { OBJC_TQ_None = 0x0, OBJC_TQ_In = 0x1, OBJC_TQ_Inout = 0x2, OBJC_TQ_Out = 0x4, OBJC_TQ_Bycopy = 0x8, OBJC_TQ_Byref = 0x10, OBJC_TQ_Oneway = 0x20, /// The nullability qualifier is set when the nullability of the /// result or parameter was expressed via a context-sensitive /// keyword. OBJC_TQ_CSNullability = 0x40 }; /// The kind of ownership a declaration has, for visibility purposes. /// This enumeration is designed such that higher values represent higher /// levels of name hiding. enum class ModuleOwnershipKind : unsigned { /// This declaration is not owned by a module. Unowned, /// This declaration has an owning module, but is globally visible /// (typically because its owning module is visible and we know that /// modules cannot later become hidden in this compilation). /// After serialization and deserialization, this will be converted /// to VisibleWhenImported. Visible, /// This declaration has an owning module, and is visible when that /// module is imported. VisibleWhenImported, /// This declaration has an owning module, but is only visible to /// lookups that occur within that module. ModulePrivate }; protected: /// The next declaration within the same lexical /// DeclContext. These pointers form the linked list that is /// traversed via DeclContext's decls_begin()/decls_end(). /// /// The extra two bits are used for the ModuleOwnershipKind. llvm::PointerIntPair NextInContextAndBits; private: friend class DeclContext; struct MultipleDC { DeclContext *SemanticDC; DeclContext *LexicalDC; }; /// DeclCtx - Holds either a DeclContext* or a MultipleDC*. /// For declarations that don't contain C++ scope specifiers, it contains /// the DeclContext where the Decl was declared. /// For declarations with C++ scope specifiers, it contains a MultipleDC* /// with the context where it semantically belongs (SemanticDC) and the /// context where it was lexically declared (LexicalDC). /// e.g.: /// /// namespace A { /// void f(); // SemanticDC == LexicalDC == 'namespace A' /// } /// void A::f(); // SemanticDC == namespace 'A' /// // LexicalDC == global namespace llvm::PointerUnion DeclCtx; bool isInSemaDC() const { return DeclCtx.is(); } bool isOutOfSemaDC() const { return DeclCtx.is(); } MultipleDC *getMultipleDC() const { return DeclCtx.get(); } DeclContext *getSemanticDC() const { return DeclCtx.get(); } /// Loc - The location of this decl. SourceLocation Loc; /// DeclKind - This indicates which class this is. unsigned DeclKind : 7; /// InvalidDecl - This indicates a semantic error occurred. unsigned InvalidDecl : 1; /// HasAttrs - This indicates whether the decl has attributes or not. unsigned HasAttrs : 1; /// Implicit - Whether this declaration was implicitly generated by /// the implementation rather than explicitly written by the user. unsigned Implicit : 1; /// Whether this declaration was "used", meaning that a definition is /// required. unsigned Used : 1; /// Whether this declaration was "referenced". /// The difference with 'Used' is whether the reference appears in a /// evaluated context or not, e.g. functions used in uninstantiated templates /// are regarded as "referenced" but not "used". unsigned Referenced : 1; /// Whether this declaration is a top-level declaration (function, /// global variable, etc.) that is lexically inside an objc container /// definition. unsigned TopLevelDeclInObjCContainer : 1; /// Whether statistic collection is enabled. static bool StatisticsEnabled; protected: friend class ASTDeclReader; friend class ASTDeclWriter; friend class ASTNodeImporter; friend class ASTReader; friend class CXXClassMemberWrapper; friend class LinkageComputer; template friend class Redeclarable; /// Access - Used by C++ decls for the access specifier. // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum unsigned Access : 2; /// Whether this declaration was loaded from an AST file. unsigned FromASTFile : 1; /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. unsigned IdentifierNamespace : 13; /// If 0, we have not computed the linkage of this declaration. /// Otherwise, it is the linkage + 1. mutable unsigned CacheValidAndLinkage : 3; /// Allocate memory for a deserialized declaration. /// /// This routine must be used to allocate memory for any declaration that is /// deserialized from a module file. /// /// \param Size The size of the allocated object. /// \param Ctx The context in which we will allocate memory. /// \param ID The global ID of the deserialized declaration. /// \param Extra The amount of extra space to allocate after the object. void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID, std::size_t Extra = 0); /// Allocate memory for a non-deserialized declaration. void *operator new(std::size_t Size, const ASTContext &Ctx, DeclContext *Parent, std::size_t Extra = 0); private: bool AccessDeclContextSanity() const; /// Get the module ownership kind to use for a local lexical child of \p DC, /// which may be either a local or (rarely) an imported declaration. static ModuleOwnershipKind getModuleOwnershipKindForChildOf(DeclContext *DC) { if (DC) { auto *D = cast(DC); auto MOK = D->getModuleOwnershipKind(); if (MOK != ModuleOwnershipKind::Unowned && (!D->isFromASTFile() || D->hasLocalOwningModuleStorage())) return MOK; // If D is not local and we have no local module storage, then we don't // need to track module ownership at all. } return ModuleOwnershipKind::Unowned; } protected: Decl(Kind DK, DeclContext *DC, SourceLocation L) : NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)), DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), CacheValidAndLinkage(0) { if (StatisticsEnabled) add(DK); } Decl(Kind DK, EmptyShell Empty) : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), CacheValidAndLinkage(0) { if (StatisticsEnabled) add(DK); } virtual ~Decl(); /// Update a potentially out-of-date declaration. void updateOutOfDate(IdentifierInfo &II) const; Linkage getCachedLinkage() const { return Linkage(CacheValidAndLinkage - 1); } void setCachedLinkage(Linkage L) const { CacheValidAndLinkage = L + 1; } bool hasCachedLinkage() const { return CacheValidAndLinkage; } public: /// Source range that this declaration covers. virtual SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getLocation(), getLocation()); } SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); } SourceLocation getBeginLoc() const LLVM_READONLY { return getSourceRange().getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } SourceLocation getEndLoc() const LLVM_READONLY { return getSourceRange().getEnd(); } SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } Kind getKind() const { return static_cast(DeclKind); } const char *getDeclKindName() const; Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); } const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();} DeclContext *getDeclContext() { if (isInSemaDC()) return getSemanticDC(); return getMultipleDC()->SemanticDC; } const DeclContext *getDeclContext() const { return const_cast(this)->getDeclContext(); } /// Find the innermost non-closure ancestor of this declaration, /// walking up through blocks, lambdas, etc. If that ancestor is /// not a code context (!isFunctionOrMethod()), returns null. /// /// A declaration may be its own non-closure context. Decl *getNonClosureContext(); const Decl *getNonClosureContext() const { return const_cast(this)->getNonClosureContext(); } TranslationUnitDecl *getTranslationUnitDecl(); const TranslationUnitDecl *getTranslationUnitDecl() const { return const_cast(this)->getTranslationUnitDecl(); } bool isInAnonymousNamespace() const; bool isInStdNamespace() const; ASTContext &getASTContext() const LLVM_READONLY; void setAccess(AccessSpecifier AS) { Access = AS; assert(AccessDeclContextSanity()); } AccessSpecifier getAccess() const { assert(AccessDeclContextSanity()); return AccessSpecifier(Access); } /// Retrieve the access specifier for this declaration, even though /// it may not yet have been properly set. AccessSpecifier getAccessUnsafe() const { return AccessSpecifier(Access); } bool hasAttrs() const { return HasAttrs; } void setAttrs(const AttrVec& Attrs) { return setAttrsImpl(Attrs, getASTContext()); } AttrVec &getAttrs() { return const_cast(const_cast(this)->getAttrs()); } const AttrVec &getAttrs() const; void dropAttrs(); void addAttr(Attr *A) { if (hasAttrs()) getAttrs().push_back(A); else setAttrs(AttrVec(1, A)); } using attr_iterator = AttrVec::const_iterator; using attr_range = llvm::iterator_range; attr_range attrs() const { return attr_range(attr_begin(), attr_end()); } attr_iterator attr_begin() const { return hasAttrs() ? getAttrs().begin() : nullptr; } attr_iterator attr_end() const { return hasAttrs() ? getAttrs().end() : nullptr; } template void dropAttr() { if (!HasAttrs) return; AttrVec &Vec = getAttrs(); Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa), Vec.end()); if (Vec.empty()) HasAttrs = false; } template llvm::iterator_range> specific_attrs() const { return llvm::make_range(specific_attr_begin(), specific_attr_end()); } template specific_attr_iterator specific_attr_begin() const { return specific_attr_iterator(attr_begin()); } template specific_attr_iterator specific_attr_end() const { return specific_attr_iterator(attr_end()); } template T *getAttr() const { return hasAttrs() ? getSpecificAttr(getAttrs()) : nullptr; } template bool hasAttr() const { return hasAttrs() && hasSpecificAttr(getAttrs()); } /// getMaxAlignment - return the maximum alignment specified by attributes /// on this decl, 0 if there are none. unsigned getMaxAlignment() const; /// setInvalidDecl - Indicates the Decl had a semantic error. This /// allows for graceful error recovery. void setInvalidDecl(bool Invalid = true); bool isInvalidDecl() const { return (bool) InvalidDecl; } /// isImplicit - Indicates whether the declaration was implicitly /// generated by the implementation. If false, this declaration /// was written explicitly in the source code. bool isImplicit() const { return Implicit; } void setImplicit(bool I = true) { Implicit = I; } /// Whether *any* (re-)declaration of the entity was used, meaning that /// a definition is required. /// /// \param CheckUsedAttr When true, also consider the "used" attribute /// (in addition to the "used" bit set by \c setUsed()) when determining /// whether the function is used. bool isUsed(bool CheckUsedAttr = true) const; /// Set whether the declaration is used, in the sense of odr-use. /// /// This should only be used immediately after creating a declaration. /// It intentionally doesn't notify any listeners. void setIsUsed() { getCanonicalDecl()->Used = true; } /// Mark the declaration used, in the sense of odr-use. /// /// This notifies any mutation listeners in addition to setting a bit /// indicating the declaration is used. void markUsed(ASTContext &C); /// Whether any declaration of this entity was referenced. bool isReferenced() const; /// Whether this declaration was referenced. This should not be relied /// upon for anything other than debugging. bool isThisDeclarationReferenced() const { return Referenced; } void setReferenced(bool R = true) { Referenced = R; } /// Whether this declaration is a top-level declaration (function, /// global variable, etc.) that is lexically inside an objc container /// definition. bool isTopLevelDeclInObjCContainer() const { return TopLevelDeclInObjCContainer; } void setTopLevelDeclInObjCContainer(bool V = true) { TopLevelDeclInObjCContainer = V; } /// Looks on this and related declarations for an applicable /// external source symbol attribute. ExternalSourceSymbolAttr *getExternalSourceSymbolAttr() const; /// Whether this declaration was marked as being private to the /// module in which it was defined. bool isModulePrivate() const { return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate; } /// Whether this declaration is exported (by virtue of being lexically /// within an ExportDecl or by being a NamespaceDecl). bool isExported() const; /// Return true if this declaration has an attribute which acts as /// definition of the entity, such as 'alias' or 'ifunc'. bool hasDefiningAttr() const; /// Return this declaration's defining attribute if it has one. const Attr *getDefiningAttr() const; protected: /// Specify that this declaration was marked as being private /// to the module in which it was defined. void setModulePrivate() { // The module-private specifier has no effect on unowned declarations. // FIXME: We should track this in some way for source fidelity. if (getModuleOwnershipKind() == ModuleOwnershipKind::Unowned) return; setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate); } /// Set the owning module ID. void setOwningModuleID(unsigned ID) { assert(isFromASTFile() && "Only works on a deserialized declaration"); *((unsigned*)this - 2) = ID; } public: /// Determine the availability of the given declaration. /// /// This routine will determine the most restrictive availability of /// the given declaration (e.g., preferring 'unavailable' to /// 'deprecated'). /// /// \param Message If non-NULL and the result is not \c /// AR_Available, will be set to a (possibly empty) message /// describing why the declaration has not been introduced, is /// deprecated, or is unavailable. /// /// \param EnclosingVersion The version to compare with. If empty, assume the /// deployment target version. /// /// \param RealizedPlatform If non-NULL and the availability result is found /// in an available attribute it will set to the platform which is written in /// the available attribute. AvailabilityResult getAvailability(std::string *Message = nullptr, VersionTuple EnclosingVersion = VersionTuple(), StringRef *RealizedPlatform = nullptr) const; /// Retrieve the version of the target platform in which this /// declaration was introduced. /// /// \returns An empty version tuple if this declaration has no 'introduced' /// availability attributes, or the version tuple that's specified in the /// attribute otherwise. VersionTuple getVersionIntroduced() const; /// Determine whether this declaration is marked 'deprecated'. /// /// \param Message If non-NULL and the declaration is deprecated, /// this will be set to the message describing why the declaration /// was deprecated (which may be empty). bool isDeprecated(std::string *Message = nullptr) const { return getAvailability(Message) == AR_Deprecated; } /// Determine whether this declaration is marked 'unavailable'. /// /// \param Message If non-NULL and the declaration is unavailable, /// this will be set to the message describing why the declaration /// was made unavailable (which may be empty). bool isUnavailable(std::string *Message = nullptr) const { return getAvailability(Message) == AR_Unavailable; } /// Determine whether this is a weak-imported symbol. /// /// Weak-imported symbols are typically marked with the /// 'weak_import' attribute, but may also be marked with an /// 'availability' attribute where we're targing a platform prior to /// the introduction of this feature. bool isWeakImported() const; /// Determines whether this symbol can be weak-imported, /// e.g., whether it would be well-formed to add the weak_import /// attribute. /// /// \param IsDefinition Set to \c true to indicate that this /// declaration cannot be weak-imported because it has a definition. bool canBeWeakImported(bool &IsDefinition) const; /// Determine whether this declaration came from an AST file (such as /// a precompiled header or module) rather than having been parsed. bool isFromASTFile() const { return FromASTFile; } /// Retrieve the global declaration ID associated with this /// declaration, which specifies where this Decl was loaded from. unsigned getGlobalID() const { if (isFromASTFile()) return *((const unsigned*)this - 1); return 0; } /// Retrieve the global ID of the module that owns this particular /// declaration. unsigned getOwningModuleID() const { if (isFromASTFile()) return *((const unsigned*)this - 2); return 0; } private: Module *getOwningModuleSlow() const; protected: bool hasLocalOwningModuleStorage() const; public: /// Get the imported owning module, if this decl is from an imported /// (non-local) module. Module *getImportedOwningModule() const { if (!isFromASTFile() || !hasOwningModule()) return nullptr; return getOwningModuleSlow(); } /// Get the local owning module, if known. Returns nullptr if owner is /// not yet known or declaration is not from a module. Module *getLocalOwningModule() const { if (isFromASTFile() || !hasOwningModule()) return nullptr; assert(hasLocalOwningModuleStorage() && "owned local decl but no local module storage"); return reinterpret_cast(this)[-1]; } void setLocalOwningModule(Module *M) { assert(!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage() && "should not have a cached owning module"); reinterpret_cast(this)[-1] = M; } /// Is this declaration owned by some module? bool hasOwningModule() const { return getModuleOwnershipKind() != ModuleOwnershipKind::Unowned; } /// Get the module that owns this declaration (for visibility purposes). Module *getOwningModule() const { return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule(); } /// Get the module that owns this declaration for linkage purposes. /// There only ever is such a module under the C++ Modules TS. /// /// \param IgnoreLinkage Ignore the linkage of the entity; assume that /// all declarations in a global module fragment are unowned. Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const; /// Determine whether this declaration might be hidden from name /// lookup. Note that the declaration might be visible even if this returns /// \c false, if the owning module is visible within the query context. // FIXME: Rename this to make it clearer what it does. bool isHidden() const { return (int)getModuleOwnershipKind() > (int)ModuleOwnershipKind::Visible; } /// Set that this declaration is globally visible, even if it came from a /// module that is not visible. void setVisibleDespiteOwningModule() { if (isHidden()) setModuleOwnershipKind(ModuleOwnershipKind::Visible); } /// Get the kind of module ownership for this declaration. ModuleOwnershipKind getModuleOwnershipKind() const { return NextInContextAndBits.getInt(); } /// Set whether this declaration is hidden from name lookup. void setModuleOwnershipKind(ModuleOwnershipKind MOK) { assert(!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && "no storage available for owning module for this declaration"); NextInContextAndBits.setInt(MOK); } unsigned getIdentifierNamespace() const { return IdentifierNamespace; } bool isInIdentifierNamespace(unsigned NS) const { return getIdentifierNamespace() & NS; } static unsigned getIdentifierNamespaceForKind(Kind DK); bool hasTagIdentifierNamespace() const { return isTagIdentifierNamespace(getIdentifierNamespace()); } static bool isTagIdentifierNamespace(unsigned NS) { // TagDecls have Tag and Type set and may also have TagFriend. return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type); } /// getLexicalDeclContext - The declaration context where this Decl was /// lexically declared (LexicalDC). May be different from /// getDeclContext() (SemanticDC). /// e.g.: /// /// namespace A { /// void f(); // SemanticDC == LexicalDC == 'namespace A' /// } /// void A::f(); // SemanticDC == namespace 'A' /// // LexicalDC == global namespace DeclContext *getLexicalDeclContext() { if (isInSemaDC()) return getSemanticDC(); return getMultipleDC()->LexicalDC; } const DeclContext *getLexicalDeclContext() const { return const_cast(this)->getLexicalDeclContext(); } /// Determine whether this declaration is declared out of line (outside its /// semantic context). virtual bool isOutOfLine() const; /// setDeclContext - Set both the semantic and lexical DeclContext /// to DC. void setDeclContext(DeclContext *DC); void setLexicalDeclContext(DeclContext *DC); /// Determine whether this declaration is a templated entity (whether it is // within the scope of a template parameter). bool isTemplated() const; /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this /// scoped decl is defined outside the current function or method. This is /// roughly global variables and functions, but also handles enums (which /// could be defined inside or outside a function etc). bool isDefinedOutsideFunctionOrMethod() const { return getParentFunctionOrMethod() == nullptr; } /// Returns true if this declaration lexically is inside a function. /// It recognizes non-defining declarations as well as members of local /// classes: /// \code /// void foo() { void bar(); } /// void foo2() { class ABC { void bar(); }; } /// \endcode bool isLexicallyWithinFunctionOrMethod() const; /// If this decl is defined inside a function/method/block it returns /// the corresponding DeclContext, otherwise it returns null. const DeclContext *getParentFunctionOrMethod() const; DeclContext *getParentFunctionOrMethod() { return const_cast( const_cast(this)->getParentFunctionOrMethod()); } /// Retrieves the "canonical" declaration of the given declaration. virtual Decl *getCanonicalDecl() { return this; } const Decl *getCanonicalDecl() const { return const_cast(this)->getCanonicalDecl(); } /// Whether this particular Decl is a canonical one. bool isCanonicalDecl() const { return getCanonicalDecl() == this; } protected: /// Returns the next redeclaration or itself if this is the only decl. /// /// Decl subclasses that can be redeclared should override this method so that /// Decl::redecl_iterator can iterate over them. virtual Decl *getNextRedeclarationImpl() { return this; } /// Implementation of getPreviousDecl(), to be overridden by any /// subclass that has a redeclaration chain. virtual Decl *getPreviousDeclImpl() { return nullptr; } /// Implementation of getMostRecentDecl(), to be overridden by any /// subclass that has a redeclaration chain. virtual Decl *getMostRecentDeclImpl() { return this; } public: /// Iterates through all the redeclarations of the same decl. class redecl_iterator { /// Current - The current declaration. Decl *Current = nullptr; Decl *Starter; public: using value_type = Decl *; using reference = const value_type &; using pointer = const value_type *; using iterator_category = std::forward_iterator_tag; using difference_type = std::ptrdiff_t; redecl_iterator() = default; explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {} reference operator*() const { return Current; } value_type operator->() const { return Current; } redecl_iterator& operator++() { assert(Current && "Advancing while iterator has reached end"); // Get either previous decl or latest decl. Decl *Next = Current->getNextRedeclarationImpl(); assert(Next && "Should return next redeclaration or itself, never null!"); Current = (Next != Starter) ? Next : nullptr; return *this; } redecl_iterator operator++(int) { redecl_iterator tmp(*this); ++(*this); return tmp; } friend bool operator==(redecl_iterator x, redecl_iterator y) { return x.Current == y.Current; } friend bool operator!=(redecl_iterator x, redecl_iterator y) { return x.Current != y.Current; } }; using redecl_range = llvm::iterator_range; /// Returns an iterator range for all the redeclarations of the same /// decl. It will iterate at least once (when this decl is the only one). redecl_range redecls() const { return redecl_range(redecls_begin(), redecls_end()); } redecl_iterator redecls_begin() const { return redecl_iterator(const_cast(this)); } redecl_iterator redecls_end() const { return redecl_iterator(); } /// Retrieve the previous declaration that declares the same entity /// as this declaration, or NULL if there is no previous declaration. Decl *getPreviousDecl() { return getPreviousDeclImpl(); } /// Retrieve the most recent declaration that declares the same entity /// as this declaration, or NULL if there is no previous declaration. const Decl *getPreviousDecl() const { return const_cast(this)->getPreviousDeclImpl(); } /// True if this is the first declaration in its redeclaration chain. bool isFirstDecl() const { return getPreviousDecl() == nullptr; } /// Retrieve the most recent declaration that declares the same entity /// as this declaration (which may be this declaration). Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); } /// Retrieve the most recent declaration that declares the same entity /// as this declaration (which may be this declaration). const Decl *getMostRecentDecl() const { return const_cast(this)->getMostRecentDeclImpl(); } /// getBody - If this Decl represents a declaration for a body of code, /// such as a function or method definition, this method returns the /// top-level Stmt* of that body. Otherwise this method returns null. virtual Stmt* getBody() const { return nullptr; } /// Returns true if this \c Decl represents a declaration for a body of /// code, such as a function or method definition. /// Note that \c hasBody can also return true if any redeclaration of this /// \c Decl represents a declaration for a body of code. virtual bool hasBody() const { return getBody() != nullptr; } /// getBodyRBrace - Gets the right brace of the body, if a body exists. /// This works whether the body is a CompoundStmt or a CXXTryStmt. SourceLocation getBodyRBrace() const; // global temp stats (until we have a per-module visitor) static void add(Kind k); static void EnableStatistics(); static void PrintStats(); /// isTemplateParameter - Determines whether this declaration is a /// template parameter. bool isTemplateParameter() const; /// isTemplateParameter - Determines whether this declaration is a /// template parameter pack. bool isTemplateParameterPack() const; /// Whether this declaration is a parameter pack. bool isParameterPack() const; /// returns true if this declaration is a template bool isTemplateDecl() const; /// Whether this declaration is a function or function template. bool isFunctionOrFunctionTemplate() const { return (DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction) || DeclKind == FunctionTemplate; } /// If this is a declaration that describes some template, this /// method returns that template declaration. TemplateDecl *getDescribedTemplate() const; /// Returns the function itself, or the templated function if this is a /// function template. FunctionDecl *getAsFunction() LLVM_READONLY; const FunctionDecl *getAsFunction() const { return const_cast(this)->getAsFunction(); } /// Changes the namespace of this declaration to reflect that it's /// a function-local extern declaration. /// /// These declarations appear in the lexical context of the extern /// declaration, but in the semantic context of the enclosing namespace /// scope. void setLocalExternDecl() { Decl *Prev = getPreviousDecl(); IdentifierNamespace &= ~IDNS_Ordinary; // It's OK for the declaration to still have the "invisible friend" flag or // the "conflicts with tag declarations in this scope" flag for the outer // scope. assert((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 && "namespace is not ordinary"); IdentifierNamespace |= IDNS_LocalExtern; if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary) IdentifierNamespace |= IDNS_Ordinary; } /// Determine whether this is a block-scope declaration with linkage. /// This will either be a local variable declaration declared 'extern', or a /// local function declaration. bool isLocalExternDecl() { return IdentifierNamespace & IDNS_LocalExtern; } /// Changes the namespace of this declaration to reflect that it's /// the object of a friend declaration. /// /// These declarations appear in the lexical context of the friending /// class, but in the semantic context of the actual entity. This property /// applies only to a specific decl object; other redeclarations of the /// same entity may not (and probably don't) share this property. void setObjectOfFriendDecl(bool PerformFriendInjection = false) { unsigned OldNS = IdentifierNamespace; assert((OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern)) && "namespace includes neither ordinary nor tag"); assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern)) && "namespace includes other than ordinary or tag"); Decl *Prev = getPreviousDecl(); IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type); if (OldNS & (IDNS_Tag | IDNS_TagFriend)) { IdentifierNamespace |= IDNS_TagFriend; if (PerformFriendInjection || (Prev && Prev->getIdentifierNamespace() & IDNS_Tag)) IdentifierNamespace |= IDNS_Tag | IDNS_Type; } if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) { IdentifierNamespace |= IDNS_OrdinaryFriend; if (PerformFriendInjection || (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)) IdentifierNamespace |= IDNS_Ordinary; } } enum FriendObjectKind { FOK_None, ///< Not a friend object. FOK_Declared, ///< A friend of a previously-declared entity. FOK_Undeclared ///< A friend of a previously-undeclared entity. }; /// Determines whether this declaration is the object of a /// friend declaration and, if so, what kind. /// /// There is currently no direct way to find the associated FriendDecl. FriendObjectKind getFriendObjectKind() const { unsigned mask = (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend)); if (!mask) return FOK_None; return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? FOK_Declared : FOK_Undeclared); } /// Specifies that this declaration is a C++ overloaded non-member. void setNonMemberOperator() { assert(getKind() == Function || getKind() == FunctionTemplate); assert((IdentifierNamespace & IDNS_Ordinary) && "visible non-member operators should be in ordinary namespace"); IdentifierNamespace |= IDNS_NonMemberOperator; } static bool classofKind(Kind K) { return true; } static DeclContext *castToDeclContext(const Decl *); static Decl *castFromDeclContext(const DeclContext *); void print(raw_ostream &Out, unsigned Indentation = 0, bool PrintInstantiation = false) const; void print(raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0, bool PrintInstantiation = false) const; static void printGroup(Decl** Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); // Debuggers don't usually respect default arguments. void dump() const; // Same as dump(), but forces color printing. void dumpColor() const; void dump(raw_ostream &Out, bool Deserialize = false) const; /// Looks through the Decl's underlying type to extract a FunctionType /// when possible. Will return null if the type underlying the Decl does not /// have a FunctionType. const FunctionType *getFunctionType(bool BlocksToo = true) const; private: void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx); void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, ASTContext &Ctx); protected: ASTMutationListener *getASTMutationListener() const; }; /// Determine whether two declarations declare the same entity. inline bool declaresSameEntity(const Decl *D1, const Decl *D2) { if (!D1 || !D2) return false; if (D1 == D2) return true; return D1->getCanonicalDecl() == D2->getCanonicalDecl(); } /// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when /// doing something to a specific decl. class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry { const Decl *TheDecl; SourceLocation Loc; SourceManager &SM; const char *Message; public: PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L, SourceManager &sm, const char *Msg) : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} void print(raw_ostream &OS) const override; }; /// The results of name lookup within a DeclContext. This is either a /// single result (with no stable storage) or a collection of results (with /// stable storage provided by the lookup table). class DeclContextLookupResult { using ResultTy = ArrayRef; ResultTy Result; // If there is only one lookup result, it would be invalidated by // reallocations of the name table, so store it separately. NamedDecl *Single = nullptr; static NamedDecl *const SingleElementDummyList; public: DeclContextLookupResult() = default; DeclContextLookupResult(ArrayRef Result) : Result(Result) {} DeclContextLookupResult(NamedDecl *Single) : Result(SingleElementDummyList), Single(Single) {} class iterator; using IteratorBase = llvm::iterator_adaptor_base; class iterator : public IteratorBase { value_type SingleElement; public: - iterator() = default; explicit iterator(pointer Pos, value_type Single = nullptr) : IteratorBase(Pos), SingleElement(Single) {} reference operator*() const { return SingleElement ? SingleElement : IteratorBase::operator*(); } }; using const_iterator = iterator; using pointer = iterator::pointer; using reference = iterator::reference; iterator begin() const { return iterator(Result.begin(), Single); } iterator end() const { return iterator(Result.end(), Single); } bool empty() const { return Result.empty(); } pointer data() const { return Single ? &Single : Result.data(); } size_t size() const { return Single ? 1 : Result.size(); } reference front() const { return Single ? Single : Result.front(); } reference back() const { return Single ? Single : Result.back(); } reference operator[](size_t N) const { return Single ? Single : Result[N]; } // FIXME: Remove this from the interface DeclContextLookupResult slice(size_t N) const { DeclContextLookupResult Sliced = Result.slice(N); Sliced.Single = Single; return Sliced; } }; /// DeclContext - This is used only as base class of specific decl types that /// can act as declaration contexts. These decls are (only the top classes /// that directly derive from DeclContext are mentioned, not their subclasses): /// /// TranslationUnitDecl /// NamespaceDecl /// FunctionDecl /// TagDecl /// ObjCMethodDecl /// ObjCContainerDecl /// LinkageSpecDecl /// ExportDecl /// BlockDecl /// OMPDeclareReductionDecl class DeclContext { /// DeclKind - This indicates which class this is. unsigned DeclKind : 8; /// Whether this declaration context also has some external /// storage that contains additional declarations that are lexically /// part of this context. mutable bool ExternalLexicalStorage : 1; /// Whether this declaration context also has some external /// storage that contains additional declarations that are visible /// in this context. mutable bool ExternalVisibleStorage : 1; /// Whether this declaration context has had external visible /// storage added since the last lookup. In this case, \c LookupPtr's /// invariant may not hold and needs to be fixed before we perform /// another lookup. mutable bool NeedToReconcileExternalVisibleStorage : 1; /// If \c true, this context may have local lexical declarations /// that are missing from the lookup table. mutable bool HasLazyLocalLexicalLookups : 1; /// If \c true, the external source may have lexical declarations /// that are missing from the lookup table. mutable bool HasLazyExternalLexicalLookups : 1; /// If \c true, lookups should only return identifier from /// DeclContext scope (for example TranslationUnit). Used in /// LookupQualifiedName() mutable bool UseQualifiedLookup : 1; /// Pointer to the data structure used to lookup declarations /// within this context (or a DependentStoredDeclsMap if this is a /// dependent context). We maintain the invariant that, if the map /// contains an entry for a DeclarationName (and we haven't lazily /// omitted anything), then it contains all relevant entries for that /// name (modulo the hasExternalDecls() flag). mutable StoredDeclsMap *LookupPtr = nullptr; protected: friend class ASTDeclReader; friend class ASTWriter; friend class ExternalASTSource; /// FirstDecl - The first declaration stored within this declaration /// context. mutable Decl *FirstDecl = nullptr; /// LastDecl - The last declaration stored within this declaration /// context. FIXME: We could probably cache this value somewhere /// outside of the DeclContext, to reduce the size of DeclContext by /// another pointer. mutable Decl *LastDecl = nullptr; /// Build up a chain of declarations. /// /// \returns the first/last pair of declarations. static std::pair BuildDeclChain(ArrayRef Decls, bool FieldsAlreadyLoaded); DeclContext(Decl::Kind K) : DeclKind(K), ExternalLexicalStorage(false), ExternalVisibleStorage(false), NeedToReconcileExternalVisibleStorage(false), HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), UseQualifiedLookup(false) {} public: ~DeclContext(); Decl::Kind getDeclKind() const { return static_cast(DeclKind); } const char *getDeclKindName() const; /// getParent - Returns the containing DeclContext. DeclContext *getParent() { return cast(this)->getDeclContext(); } const DeclContext *getParent() const { return const_cast(this)->getParent(); } /// getLexicalParent - Returns the containing lexical DeclContext. May be /// different from getParent, e.g.: /// /// namespace A { /// struct S; /// } /// struct A::S {}; // getParent() == namespace 'A' /// // getLexicalParent() == translation unit /// DeclContext *getLexicalParent() { return cast(this)->getLexicalDeclContext(); } const DeclContext *getLexicalParent() const { return const_cast(this)->getLexicalParent(); } DeclContext *getLookupParent(); const DeclContext *getLookupParent() const { return const_cast(this)->getLookupParent(); } ASTContext &getParentASTContext() const { return cast(this)->getASTContext(); } bool isClosure() const { return DeclKind == Decl::Block; } bool isObjCContainer() const { switch (DeclKind) { case Decl::ObjCCategory: case Decl::ObjCCategoryImpl: case Decl::ObjCImplementation: case Decl::ObjCInterface: case Decl::ObjCProtocol: return true; } return false; } bool isFunctionOrMethod() const { switch (DeclKind) { case Decl::Block: case Decl::Captured: case Decl::ObjCMethod: return true; default: return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction; } } /// Test whether the context supports looking up names. bool isLookupContext() const { return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec && DeclKind != Decl::Export; } bool isFileContext() const { return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace; } bool isTranslationUnit() const { return DeclKind == Decl::TranslationUnit; } bool isRecord() const { return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord; } bool isNamespace() const { return DeclKind == Decl::Namespace; } bool isStdNamespace() const; bool isInlineNamespace() const; /// Determines whether this context is dependent on a /// template parameter. bool isDependentContext() const; /// isTransparentContext - Determines whether this context is a /// "transparent" context, meaning that the members declared in this /// context are semantically declared in the nearest enclosing /// non-transparent (opaque) context but are lexically declared in /// this context. For example, consider the enumerators of an /// enumeration type: /// @code /// enum E { /// Val1 /// }; /// @endcode /// Here, E is a transparent context, so its enumerator (Val1) will /// appear (semantically) that it is in the same context of E. /// Examples of transparent contexts include: enumerations (except for /// C++0x scoped enums), and C++ linkage specifications. bool isTransparentContext() const; /// Determines whether this context or some of its ancestors is a /// linkage specification context that specifies C linkage. bool isExternCContext() const; /// Retrieve the nearest enclosing C linkage specification context. const LinkageSpecDecl *getExternCContext() const; /// Determines whether this context or some of its ancestors is a /// linkage specification context that specifies C++ linkage. bool isExternCXXContext() const; /// Determine whether this declaration context is equivalent /// to the declaration context DC. bool Equals(const DeclContext *DC) const { return DC && this->getPrimaryContext() == DC->getPrimaryContext(); } /// Determine whether this declaration context encloses the /// declaration context DC. bool Encloses(const DeclContext *DC) const; /// Find the nearest non-closure ancestor of this context, /// i.e. the innermost semantic parent of this context which is not /// a closure. A context may be its own non-closure ancestor. Decl *getNonClosureAncestor(); const Decl *getNonClosureAncestor() const { return const_cast(this)->getNonClosureAncestor(); } /// getPrimaryContext - There may be many different /// declarations of the same entity (including forward declarations /// of classes, multiple definitions of namespaces, etc.), each with /// a different set of declarations. This routine returns the /// "primary" DeclContext structure, which will contain the /// information needed to perform name lookup into this context. DeclContext *getPrimaryContext(); const DeclContext *getPrimaryContext() const { return const_cast(this)->getPrimaryContext(); } /// getRedeclContext - Retrieve the context in which an entity conflicts with /// other entities of the same name, or where it is a redeclaration if the /// two entities are compatible. This skips through transparent contexts. DeclContext *getRedeclContext(); const DeclContext *getRedeclContext() const { return const_cast(this)->getRedeclContext(); } /// Retrieve the nearest enclosing namespace context. DeclContext *getEnclosingNamespaceContext(); const DeclContext *getEnclosingNamespaceContext() const { return const_cast(this)->getEnclosingNamespaceContext(); } /// Retrieve the outermost lexically enclosing record context. RecordDecl *getOuterLexicalRecordContext(); const RecordDecl *getOuterLexicalRecordContext() const { return const_cast(this)->getOuterLexicalRecordContext(); } /// Test if this context is part of the enclosing namespace set of /// the context NS, as defined in C++0x [namespace.def]p9. If either context /// isn't a namespace, this is equivalent to Equals(). /// /// The enclosing namespace set of a namespace is the namespace and, if it is /// inline, its enclosing namespace, recursively. bool InEnclosingNamespaceSetOf(const DeclContext *NS) const; /// Collects all of the declaration contexts that are semantically /// connected to this declaration context. /// /// For declaration contexts that have multiple semantically connected but /// syntactically distinct contexts, such as C++ namespaces, this routine /// retrieves the complete set of such declaration contexts in source order. /// For example, given: /// /// \code /// namespace N { /// int x; /// } /// namespace N { /// int y; /// } /// \endcode /// /// The \c Contexts parameter will contain both definitions of N. /// /// \param Contexts Will be cleared and set to the set of declaration /// contexts that are semanticaly connected to this declaration context, /// in source order, including this context (which may be the only result, /// for non-namespace contexts). void collectAllContexts(SmallVectorImpl &Contexts); /// decl_iterator - Iterates through the declarations stored /// within this context. class decl_iterator { /// Current - The current declaration. Decl *Current = nullptr; public: using value_type = Decl *; using reference = const value_type &; using pointer = const value_type *; using iterator_category = std::forward_iterator_tag; using difference_type = std::ptrdiff_t; decl_iterator() = default; explicit decl_iterator(Decl *C) : Current(C) {} reference operator*() const { return Current; } // This doesn't meet the iterator requirements, but it's convenient value_type operator->() const { return Current; } decl_iterator& operator++() { Current = Current->getNextDeclInContext(); return *this; } decl_iterator operator++(int) { decl_iterator tmp(*this); ++(*this); return tmp; } friend bool operator==(decl_iterator x, decl_iterator y) { return x.Current == y.Current; } friend bool operator!=(decl_iterator x, decl_iterator y) { return x.Current != y.Current; } }; using decl_range = llvm::iterator_range; /// decls_begin/decls_end - Iterate over the declarations stored in /// this context. decl_range decls() const { return decl_range(decls_begin(), decls_end()); } decl_iterator decls_begin() const; decl_iterator decls_end() const { return decl_iterator(); } bool decls_empty() const; /// noload_decls_begin/end - Iterate over the declarations stored in this /// context that are currently loaded; don't attempt to retrieve anything /// from an external source. decl_range noload_decls() const { return decl_range(noload_decls_begin(), noload_decls_end()); } decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); } decl_iterator noload_decls_end() const { return decl_iterator(); } /// specific_decl_iterator - Iterates over a subrange of /// declarations stored in a DeclContext, providing only those that /// are of type SpecificDecl (or a class derived from it). This /// iterator is used, for example, to provide iteration over just /// the fields within a RecordDecl (with SpecificDecl = FieldDecl). template class specific_decl_iterator { /// Current - The current, underlying declaration iterator, which /// will either be NULL or will point to a declaration of /// type SpecificDecl. DeclContext::decl_iterator Current; /// SkipToNextDecl - Advances the current position up to the next /// declaration of type SpecificDecl that also meets the criteria /// required by Acceptable. void SkipToNextDecl() { while (*Current && !isa(*Current)) ++Current; } public: using value_type = SpecificDecl *; // TODO: Add reference and pointer types (with some appropriate proxy type) // if we ever have a need for them. using reference = void; using pointer = void; using difference_type = std::iterator_traits::difference_type; using iterator_category = std::forward_iterator_tag; specific_decl_iterator() = default; /// specific_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, /// end-of-declarations). If A is non-NULL, it is a pointer to a /// member function of SpecificDecl that should return true for /// all of the SpecificDecl instances that will be in the subset /// of iterators. For example, if you want Objective-C instance /// methods, SpecificDecl will be ObjCMethodDecl and A will be /// &ObjCMethodDecl::isInstanceMethod. explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) { SkipToNextDecl(); } value_type operator*() const { return cast(*Current); } // This doesn't meet the iterator requirements, but it's convenient value_type operator->() const { return **this; } specific_decl_iterator& operator++() { ++Current; SkipToNextDecl(); return *this; } specific_decl_iterator operator++(int) { specific_decl_iterator tmp(*this); ++(*this); return tmp; } friend bool operator==(const specific_decl_iterator& x, const specific_decl_iterator& y) { return x.Current == y.Current; } friend bool operator!=(const specific_decl_iterator& x, const specific_decl_iterator& y) { return x.Current != y.Current; } }; /// Iterates over a filtered subrange of declarations stored /// in a DeclContext. /// /// This iterator visits only those declarations that are of type /// SpecificDecl (or a class derived from it) and that meet some /// additional run-time criteria. This iterator is used, for /// example, to provide access to the instance methods within an /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and /// Acceptable = ObjCMethodDecl::isInstanceMethod). template class filtered_decl_iterator { /// Current - The current, underlying declaration iterator, which /// will either be NULL or will point to a declaration of /// type SpecificDecl. DeclContext::decl_iterator Current; /// SkipToNextDecl - Advances the current position up to the next /// declaration of type SpecificDecl that also meets the criteria /// required by Acceptable. void SkipToNextDecl() { while (*Current && (!isa(*Current) || (Acceptable && !(cast(*Current)->*Acceptable)()))) ++Current; } public: using value_type = SpecificDecl *; // TODO: Add reference and pointer types (with some appropriate proxy type) // if we ever have a need for them. using reference = void; using pointer = void; using difference_type = std::iterator_traits::difference_type; using iterator_category = std::forward_iterator_tag; filtered_decl_iterator() = default; /// filtered_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, /// end-of-declarations). If A is non-NULL, it is a pointer to a /// member function of SpecificDecl that should return true for /// all of the SpecificDecl instances that will be in the subset /// of iterators. For example, if you want Objective-C instance /// methods, SpecificDecl will be ObjCMethodDecl and A will be /// &ObjCMethodDecl::isInstanceMethod. explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) { SkipToNextDecl(); } value_type operator*() const { return cast(*Current); } value_type operator->() const { return cast(*Current); } filtered_decl_iterator& operator++() { ++Current; SkipToNextDecl(); return *this; } filtered_decl_iterator operator++(int) { filtered_decl_iterator tmp(*this); ++(*this); return tmp; } friend bool operator==(const filtered_decl_iterator& x, const filtered_decl_iterator& y) { return x.Current == y.Current; } friend bool operator!=(const filtered_decl_iterator& x, const filtered_decl_iterator& y) { return x.Current != y.Current; } }; /// Add the declaration D into this context. /// /// This routine should be invoked when the declaration D has first /// been declared, to place D into the context where it was /// (lexically) defined. Every declaration must be added to one /// (and only one!) context, where it can be visited via /// [decls_begin(), decls_end()). Once a declaration has been added /// to its lexical context, the corresponding DeclContext owns the /// declaration. /// /// If D is also a NamedDecl, it will be made visible within its /// semantic context via makeDeclVisibleInContext. void addDecl(Decl *D); /// Add the declaration D into this context, but suppress /// searches for external declarations with the same name. /// /// Although analogous in function to addDecl, this removes an /// important check. This is only useful if the Decl is being /// added in response to an external search; in all other cases, /// addDecl() is the right function to use. /// See the ASTImporter for use cases. void addDeclInternal(Decl *D); /// Add the declaration D to this context without modifying /// any lookup tables. /// /// This is useful for some operations in dependent contexts where /// the semantic context might not be dependent; this basically /// only happens with friends. void addHiddenDecl(Decl *D); /// Removes a declaration from this context. void removeDecl(Decl *D); /// Checks whether a declaration is in this context. bool containsDecl(Decl *D) const; /// Checks whether a declaration is in this context. /// This also loads the Decls from the external source before the check. bool containsDeclAndLoad(Decl *D) const; using lookup_result = DeclContextLookupResult; using lookup_iterator = lookup_result::iterator; /// lookup - Find the declarations (if any) with the given Name in /// this context. Returns a range of iterators that contains all of /// the declarations with this name, with object, function, member, /// and enumerator names preceding any tag name. Note that this /// routine will not look into parent contexts. lookup_result lookup(DeclarationName Name) const; /// Find the declarations with the given name that are visible /// within this context; don't attempt to retrieve anything from an /// external source. lookup_result noload_lookup(DeclarationName Name); /// A simplistic name lookup mechanism that performs name lookup /// into this declaration context without consulting the external source. /// /// This function should almost never be used, because it subverts the /// usual relationship between a DeclContext and the external source. /// See the ASTImporter for the (few, but important) use cases. /// /// FIXME: This is very inefficient; replace uses of it with uses of /// noload_lookup. void localUncachedLookup(DeclarationName Name, SmallVectorImpl &Results); /// Makes a declaration visible within this context. /// /// This routine makes the declaration D visible to name lookup /// within this context and, if this is a transparent context, /// within its parent contexts up to the first enclosing /// non-transparent context. Making a declaration visible within a /// context does not transfer ownership of a declaration, and a /// declaration can be visible in many contexts that aren't its /// lexical context. /// /// If D is a redeclaration of an existing declaration that is /// visible from this context, as determined by /// NamedDecl::declarationReplaces, the previous declaration will be /// replaced with D. void makeDeclVisibleInContext(NamedDecl *D); /// all_lookups_iterator - An iterator that provides a view over the results /// of looking up every possible name. class all_lookups_iterator; using lookups_range = llvm::iterator_range; lookups_range lookups() const; // Like lookups(), but avoids loading external declarations. // If PreserveInternalState, avoids building lookup data structures too. lookups_range noload_lookups(bool PreserveInternalState) const; /// Iterators over all possible lookups within this context. all_lookups_iterator lookups_begin() const; all_lookups_iterator lookups_end() const; /// Iterators over all possible lookups within this context that are /// currently loaded; don't attempt to retrieve anything from an external /// source. all_lookups_iterator noload_lookups_begin() const; all_lookups_iterator noload_lookups_end() const; struct udir_iterator; using udir_iterator_base = llvm::iterator_adaptor_base; struct udir_iterator : udir_iterator_base { udir_iterator(lookup_iterator I) : udir_iterator_base(I) {} UsingDirectiveDecl *operator*() const; }; using udir_range = llvm::iterator_range; udir_range using_directives() const; // These are all defined in DependentDiagnostic.h. class ddiag_iterator; using ddiag_range = llvm::iterator_range; inline ddiag_range ddiags() const; // Low-level accessors /// Mark that there are external lexical declarations that we need /// to include in our lookup table (and that are not available as external /// visible lookups). These extra lookup results will be found by walking /// the lexical declarations of this context. This should be used only if /// setHasExternalLexicalStorage() has been called on any decl context for /// which this is the primary context. void setMustBuildLookupTable() { assert(this == getPrimaryContext() && "should only be called on primary context"); HasLazyExternalLexicalLookups = true; } /// Retrieve the internal representation of the lookup structure. /// This may omit some names if we are lazily building the structure. StoredDeclsMap *getLookupPtr() const { return LookupPtr; } /// Ensure the lookup structure is fully-built and return it. StoredDeclsMap *buildLookup(); /// Whether this DeclContext has external storage containing /// additional declarations that are lexically in this context. bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; } /// State whether this DeclContext has external storage for /// declarations lexically in this context. void setHasExternalLexicalStorage(bool ES = true) { ExternalLexicalStorage = ES; } /// Whether this DeclContext has external storage containing /// additional declarations that are visible in this context. bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; } /// State whether this DeclContext has external storage for /// declarations visible in this context. void setHasExternalVisibleStorage(bool ES = true) { ExternalVisibleStorage = ES; if (ES && LookupPtr) NeedToReconcileExternalVisibleStorage = true; } /// Determine whether the given declaration is stored in the list of /// declarations lexically within this context. bool isDeclInLexicalTraversal(const Decl *D) const { return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl || D == LastDecl); } bool setUseQualifiedLookup(bool use = true) { bool old_value = UseQualifiedLookup; UseQualifiedLookup = use; return old_value; } bool shouldUseQualifiedLookup() const { return UseQualifiedLookup; } static bool classof(const Decl *D); static bool classof(const DeclContext *D) { return true; } void dumpDeclContext() const; void dumpLookups() const; void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false, bool Deserialize = false) const; private: friend class DependentDiagnostic; void reconcileExternalVisibleStorage() const; bool LoadLexicalDeclsFromExternalStorage() const; /// Makes a declaration visible within this context, but /// suppresses searches for external declarations with the same /// name. /// /// Analogous to makeDeclVisibleInContext, but for the exclusive /// use of addDeclInternal(). void makeDeclVisibleInContextInternal(NamedDecl *D); StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; void loadLazyLocalLexicalLookups(); void buildLookupImpl(DeclContext *DCtx, bool Internal); void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, bool Rediscoverable); void makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal); }; inline bool Decl::isTemplateParameter() const { return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm || getKind() == TemplateTemplateParm; } // Specialization selected when ToTy is not a known subclass of DeclContext. template ::value> struct cast_convert_decl_context { static const ToTy *doit(const DeclContext *Val) { return static_cast(Decl::castFromDeclContext(Val)); } static ToTy *doit(DeclContext *Val) { return static_cast(Decl::castFromDeclContext(Val)); } }; // Specialization selected when ToTy is a known subclass of DeclContext. template struct cast_convert_decl_context { static const ToTy *doit(const DeclContext *Val) { return static_cast(Val); } static ToTy *doit(DeclContext *Val) { return static_cast(Val); } }; } // namespace clang namespace llvm { /// isa(DeclContext*) template struct isa_impl { static bool doit(const ::clang::DeclContext &Val) { return To::classofKind(Val.getDeclKind()); } }; /// cast(DeclContext*) template struct cast_convert_val { static const ToTy &doit(const ::clang::DeclContext &Val) { return *::clang::cast_convert_decl_context::doit(&Val); } }; template struct cast_convert_val { static ToTy &doit(::clang::DeclContext &Val) { return *::clang::cast_convert_decl_context::doit(&Val); } }; template struct cast_convert_val { static const ToTy *doit(const ::clang::DeclContext *Val) { return ::clang::cast_convert_decl_context::doit(Val); } }; template struct cast_convert_val { static ToTy *doit(::clang::DeclContext *Val) { return ::clang::cast_convert_decl_context::doit(Val); } }; /// Implement cast_convert_val for Decl -> DeclContext conversions. template struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> { static ::clang::DeclContext &doit(const FromTy &Val) { return *FromTy::castToDeclContext(&Val); } }; template struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> { static ::clang::DeclContext *doit(const FromTy *Val) { return FromTy::castToDeclContext(Val); } }; template struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> { static const ::clang::DeclContext &doit(const FromTy &Val) { return *FromTy::castToDeclContext(&Val); } }; template struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> { static const ::clang::DeclContext *doit(const FromTy *Val) { return FromTy::castToDeclContext(Val); } }; } // namespace llvm #endif // LLVM_CLANG_AST_DECLBASE_H Index: vendor/clang/dist-release_70/include/clang/Basic/Attr.td =================================================================== --- vendor/clang/dist-release_70/include/clang/Basic/Attr.td (revision 341729) +++ vendor/clang/dist-release_70/include/clang/Basic/Attr.td (revision 341730) @@ -1,2973 +1,3006 @@ //==--- Attr.td - attribute definitions -----------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // The documentation is organized by category. Attributes can have category- // specific documentation that is collated within the larger document. class DocumentationCategory { string Name = name; code Content = [{}]; } def DocCatFunction : DocumentationCategory<"Function Attributes">; def DocCatVariable : DocumentationCategory<"Variable Attributes">; def DocCatType : DocumentationCategory<"Type Attributes">; def DocCatStmt : DocumentationCategory<"Statement Attributes">; // Attributes listed under the Undocumented category do not generate any public // documentation. Ideally, this category should be used for internal-only // attributes which contain no spellings. def DocCatUndocumented : DocumentationCategory<"Undocumented">; class DocDeprecated { // If the Replacement field is empty, no replacement will be listed with the // documentation. Otherwise, the documentation will specify the attribute has // been superseded by this replacement. string Replacement = replacement; } // Specifies the documentation to be associated with the given category. class Documentation { DocumentationCategory Category; code Content; // If the heading is empty, one may be picked automatically. If the attribute // only has one spelling, no heading is required as the attribute's sole // spelling is sufficient. If all spellings are semantically common, the // heading will be the semantic spelling. If the spellings are not // semantically common and no heading is provided, an error will be emitted. string Heading = ""; // When set, specifies that the attribute is deprecated and can optionally // specify a replacement attribute. DocDeprecated Deprecated; } // Specifies that the attribute is explicitly undocumented. This can be a // helpful placeholder for the attribute while working on the implementation, // but should not be used once feature work has been completed. def Undocumented : Documentation { let Category = DocCatUndocumented; } include "clang/Basic/AttrDocs.td" // An attribute's subject is whatever it appertains to. In this file, it is // more accurately a list of things that an attribute can appertain to. All // Decls and Stmts are possibly AttrSubjects (even though the syntax may not // allow attributes on a given Decl or Stmt). class AttrSubject; include "clang/Basic/DeclNodes.td" include "clang/Basic/StmtNodes.td" // A subset-subject is an AttrSubject constrained to operate only on some subset // of that subject. // // The code fragment is a boolean expression that will confirm that the subject // meets the requirements; the subject will have the name S, and will have the // type specified by the base. It should be a simple boolean expression. The // diagnostic string should be a comma-separated list of subject names. class SubsetSubject : AttrSubject { AttrSubject Base = base; code CheckCode = check; string DiagSpelling = diag; } def LocalVar : SubsetSubjecthasLocalStorage() && !isa(S)}], "local variables">; def NonParmVar : SubsetSubjectgetKind() != Decl::ParmVar}], "variables">; def NonLocalVar : SubsetSubjecthasLocalStorage()}], "variables with non-local storage">; def NonBitField : SubsetSubjectisBitField()}], "non-bit-field non-static data members">; def ObjCInstanceMethod : SubsetSubjectisInstanceMethod()}], "Objective-C instance methods">; def ObjCInterfaceDeclInitMethod : SubsetSubjectgetMethodFamily() == OMF_init && (isa(S->getDeclContext()) || (isa(S->getDeclContext()) && cast(S->getDeclContext())->IsClassExtension()))}], "init methods of interface or class extension declarations">; def Struct : SubsetSubjectisUnion()}], "structs">; def TLSVar : SubsetSubjectgetTLSKind() != 0}], "thread-local variables">; def SharedVar : SubsetSubjecthasGlobalStorage() && !S->getTLSKind()}], "global variables">; def GlobalVar : SubsetSubjecthasGlobalStorage()}], "global variables">; def InlineFunction : SubsetSubjectisInlineSpecified()}], "inline functions">; // FIXME: this hack is needed because DeclNodes.td defines the base Decl node // type to be a class, not a definition. This makes it impossible to create an // attribute subject which accepts a Decl. Normally, this is not a problem, // because the attribute can have no Subjects clause to accomplish this. But in // the case of a SubsetSubject, there's no way to express it without this hack. def DeclBase : AttrSubject; def FunctionLike : SubsetSubjectgetFunctionType(false) != nullptr}], "functions, function pointers">; def OpenCLKernelFunction : SubsetSubjecthasAttr()}], "kernel functions">; // HasFunctionProto is a more strict version of FunctionLike, so it should // never be specified in a Subjects list along with FunctionLike (due to the // inclusive nature of subject testing). def HasFunctionProto : SubsetSubjectgetFunctionType(true) != nullptr && isa(S->getFunctionType())) || isa(S) || isa(S)}], "non-K&R-style functions">; // A subject that matches the implicit object parameter of a non-static member // function. Accepted as a function type attribute on the type of such a // member function. // FIXME: This does not actually ever match currently. def ImplicitObjectParameter : SubsetSubject; // A single argument to an attribute class Argument { string Name = name; bit Optional = optional; /// A fake argument is used to store and serialize additional information /// in an attribute without actually changing its parsing or pretty-printing. bit Fake = fake; } class BoolArgument : Argument; class IdentifierArgument : Argument; class IntArgument : Argument; class StringArgument : Argument; class ExprArgument : Argument; class FunctionArgument : Argument; class NamedArgument : Argument; class TypeArgument : Argument; class UnsignedArgument : Argument; class VariadicUnsignedArgument : Argument; class VariadicExprArgument : Argument; class VariadicStringArgument : Argument; class VariadicIdentifierArgument : Argument; // Like VariadicUnsignedArgument except values are ParamIdx. class VariadicParamIdxArgument : Argument; // Like VariadicParamIdxArgument but for a single function parameter index. class ParamIdxArgument : Argument; // A version of the form major.minor[.subminor]. class VersionArgument : Argument; // This one's a doozy, so it gets its own special type // It can be an unsigned integer, or a type. Either can // be dependent. class AlignedArgument : Argument; // A bool argument with a default value class DefaultBoolArgument : BoolArgument { bit Default = default; } // An integer argument with a default value class DefaultIntArgument : IntArgument { int Default = default; } // This argument is more complex, it includes the enumerator type name, // a list of strings to accept, and a list of enumerators to map them to. class EnumArgument values, list enums, bit opt = 0, bit fake = 0> : Argument { string Type = type; list Values = values; list Enums = enums; } // FIXME: There should be a VariadicArgument type that takes any other type // of argument and generates the appropriate type. class VariadicEnumArgument values, list enums> : Argument { string Type = type; list Values = values; list Enums = enums; } // This handles one spelling of an attribute. class Spelling { string Name = name; string Variety = variety; bit KnownToGCC; } class GNU : Spelling; class Declspec : Spelling; class Microsoft : Spelling; class CXX11 : Spelling { string Namespace = namespace; int Version = version; } class C2x : Spelling { string Namespace = namespace; } class Keyword : Spelling; class Pragma : Spelling { string Namespace = namespace; } // The GCC spelling implies GNU and CXX11<"gnu", name> and also sets // KnownToGCC to 1. This spelling should be used for any GCC-compatible // attributes. class GCC : Spelling { let KnownToGCC = 1; } // The Clang spelling implies GNU, CXX11<"clang", name>, and optionally, // C2x<"clang", name>. This spelling should be used for any Clang-specific // attributes. class Clang : Spelling { bit AllowInC = allowInC; } class Accessor spellings> { string Name = name; list Spellings = spellings; } class SubjectDiag { bit Warn = warn; } def WarnDiag : SubjectDiag<1>; def ErrorDiag : SubjectDiag<0>; class SubjectList subjects, SubjectDiag diag = WarnDiag, string customDiag = ""> { list Subjects = subjects; SubjectDiag Diag = diag; string CustomDiag = customDiag; } class LangOpt { string Name = name; bit Negated = negated; } def MicrosoftExt : LangOpt<"MicrosoftExt">; def Borland : LangOpt<"Borland">; def CUDA : LangOpt<"CUDA">; def COnly : LangOpt<"CPlusPlus", 1>; def CPlusPlus : LangOpt<"CPlusPlus">; def OpenCL : LangOpt<"OpenCL">; def RenderScript : LangOpt<"RenderScript">; def ObjC : LangOpt<"ObjC1">; def BlocksSupported : LangOpt<"Blocks">; // Defines targets for target-specific attributes. Empty lists are unchecked. class TargetSpec { // Specifies Architectures for which the target applies, based off the // ArchType enumeration in Triple.h. list Arches = []; // Specifies Operating Systems for which the target applies, based off the // OSType enumeration in Triple.h list OSes; // Specifies the C++ ABIs for which the target applies, based off the // TargetCXXABI::Kind in TargetCXXABI.h. list CXXABIs; // Specifies Object Formats for which the target applies, based off the // ObjectFormatType enumeration in Triple.h list ObjectFormats; } class TargetArch arches> : TargetSpec { let Arches = arches; } def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; def TargetAVR : TargetArch<["avr"]>; def TargetMips32 : TargetArch<["mips", "mipsel"]>; def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>; def TargetMSP430 : TargetArch<["msp430"]>; def TargetRISCV : TargetArch<["riscv32", "riscv64"]>; def TargetX86 : TargetArch<["x86"]>; def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { let OSes = ["Win32"]; } def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { let CXXABIs = ["Microsoft"]; } def TargetELF : TargetSpec { let ObjectFormats = ["ELF"]; } // Attribute subject match rules that are used for #pragma clang attribute. // // A instance of AttrSubjectMatcherRule represents an individual match rule. // An individual match rule can correspond to a number of different attribute // subjects, e.g. "record" matching rule corresponds to the Record and // CXXRecord attribute subjects. // // Match rules are used in the subject list of the #pragma clang attribute. // Match rules can have sub-match rules that are instances of // AttrSubjectMatcherSubRule. A sub-match rule can correspond to a number // of different attribute subjects, and it can have a negated spelling as well. // For example, "variable(unless(is_parameter))" matching rule corresponds to // the NonParmVar attribute subject. class AttrSubjectMatcherSubRule subjects, bit negated = 0> { string Name = name; list Subjects = subjects; bit Negated = negated; // Lists language options, one of which is required to be true for the // attribute to be applicable. If empty, the language options are taken // from the parent matcher rule. list LangOpts = []; } class AttrSubjectMatcherRule subjects, list subrules = []> { string Name = name; list Subjects = subjects; list Constraints = subrules; // Lists language options, one of which is required to be true for the // attribute to be applicable. If empty, no language options are required. list LangOpts = []; } // function(is_member) def SubRuleForCXXMethod : AttrSubjectMatcherSubRule<"is_member", [CXXMethod]> { let LangOpts = [CPlusPlus]; } def SubjectMatcherForFunction : AttrSubjectMatcherRule<"function", [Function], [ SubRuleForCXXMethod ]>; // hasType is abstract, it should be used with one of the sub-rules. def SubjectMatcherForType : AttrSubjectMatcherRule<"hasType", [], [ AttrSubjectMatcherSubRule<"functionType", [FunctionLike]> // FIXME: There's a matcher ambiguity with objc methods and blocks since // functionType excludes them but functionProtoType includes them. // AttrSubjectMatcherSubRule<"functionProtoType", [HasFunctionProto]> ]>; def SubjectMatcherForTypedef : AttrSubjectMatcherRule<"type_alias", [TypedefName]>; def SubjectMatcherForRecord : AttrSubjectMatcherRule<"record", [Record, CXXRecord], [ // unless(is_union) AttrSubjectMatcherSubRule<"is_union", [Struct], 1> ]>; def SubjectMatcherForEnum : AttrSubjectMatcherRule<"enum", [Enum]>; def SubjectMatcherForEnumConstant : AttrSubjectMatcherRule<"enum_constant", [EnumConstant]>; def SubjectMatcherForVar : AttrSubjectMatcherRule<"variable", [Var], [ AttrSubjectMatcherSubRule<"is_thread_local", [TLSVar]>, AttrSubjectMatcherSubRule<"is_global", [GlobalVar]>, AttrSubjectMatcherSubRule<"is_parameter", [ParmVar]>, // unless(is_parameter) AttrSubjectMatcherSubRule<"is_parameter", [NonParmVar], 1> ]>; def SubjectMatcherForField : AttrSubjectMatcherRule<"field", [Field]>; def SubjectMatcherForNamespace : AttrSubjectMatcherRule<"namespace", [Namespace]> { let LangOpts = [CPlusPlus]; } def SubjectMatcherForObjCInterface : AttrSubjectMatcherRule<"objc_interface", [ObjCInterface]> { let LangOpts = [ObjC]; } def SubjectMatcherForObjCProtocol : AttrSubjectMatcherRule<"objc_protocol", [ObjCProtocol]> { let LangOpts = [ObjC]; } def SubjectMatcherForObjCCategory : AttrSubjectMatcherRule<"objc_category", [ObjCCategory]> { let LangOpts = [ObjC]; } def SubjectMatcherForObjCMethod : AttrSubjectMatcherRule<"objc_method", [ObjCMethod], [ AttrSubjectMatcherSubRule<"is_instance", [ObjCInstanceMethod]> ]> { let LangOpts = [ObjC]; } def SubjectMatcherForObjCProperty : AttrSubjectMatcherRule<"objc_property", [ObjCProperty]> { let LangOpts = [ObjC]; } def SubjectMatcherForBlock : AttrSubjectMatcherRule<"block", [Block]> { let LangOpts = [BlocksSupported]; } // Aggregate attribute subject match rules are abstract match rules that can't // be used directly in #pragma clang attribute. Instead, users have to use // subject match rules that correspond to attribute subjects that derive from // the specified subject. class AttrSubjectMatcherAggregateRule { AttrSubject Subject = subject; } def SubjectMatcherForNamed : AttrSubjectMatcherAggregateRule; class Attr { // The various ways in which an attribute can be spelled in source list Spellings; // The things to which an attribute can appertain SubjectList Subjects; // The arguments allowed on an attribute list Args = []; // Accessors which should be generated for the attribute. list Accessors = []; // Set to true for attributes with arguments which require delayed parsing. bit LateParsed = 0; // Set to false to prevent an attribute from being propagated from a template // to the instantiation. bit Clone = 1; // Set to true for attributes which must be instantiated within templates bit TemplateDependent = 0; // Set to true for attributes that have a corresponding AST node. bit ASTNode = 1; // Set to true for attributes which have handler in Sema. bit SemaHandler = 1; // Set to true for attributes that are completely ignored. bit Ignored = 0; // Set to true if the attribute's parsing does not match its semantic // content. Eg) It parses 3 args, but semantically takes 4 args. Opts out of // common attribute error checking. bit HasCustomParsing = 0; // Set to true if all of the attribute's arguments should be parsed in an // unevaluated context. bit ParseArgumentsAsUnevaluated = 0; // Set to true if this attribute meaningful when applied to or inherited // in a class template definition. bit MeaningfulToClassTemplateDefinition = 0; // Set to true if this attribute can be used with '#pragma clang attribute'. // By default, when this value is false, an attribute is supported by the // '#pragma clang attribute' only when: // - It has documentation. // - It has a subject list whose subjects can be represented using subject // match rules. // - It has GNU/CXX11 spelling and doesn't require delayed parsing. bit ForcePragmaAttributeSupport = 0; // Lists language options, one of which is required to be true for the // attribute to be applicable. If empty, no language options are required. list LangOpts = []; // Any additional text that should be included verbatim in the class. // Note: Any additional data members will leak and should be constructed // externally on the ASTContext. code AdditionalMembers = [{}]; // Any documentation that should be associated with the attribute. Since an // attribute may be documented under multiple categories, more than one // Documentation entry may be listed. list Documentation; } /// A type attribute is not processed on a declaration or a statement. class TypeAttr : Attr { // By default, type attributes do not get an AST node. let ASTNode = 0; } /// A stmt attribute is not processed on a declaration or a type. class StmtAttr : Attr; /// An inheritable attribute is inherited by later redeclarations. class InheritableAttr : Attr { // Set to true if this attribute can be duplicated on a subject when inheriting // attributes from prior declarations. bit InheritEvenIfAlreadyPresent = 0; } /// Some attributes, like calling conventions, can appear in either the /// declaration or the type position. These attributes are morally type /// attributes, but have historically been written on declarations. class DeclOrTypeAttr : InheritableAttr; /// A target-specific attribute. This class is meant to be used as a mixin /// with InheritableAttr or Attr depending on the attribute's needs. class TargetSpecificAttr { TargetSpec Target = target; // Attributes are generally required to have unique spellings for their names // so that the parser can determine what kind of attribute it has parsed. // However, target-specific attributes are special in that the attribute only // "exists" for a given target. So two target-specific attributes can share // the same name when they exist in different targets. To support this, a // Kind can be explicitly specified for a target-specific attribute. This // corresponds to the ParsedAttr::AT_* enum that is generated and it // should contain a shared value between the attributes. // // Target-specific attributes which use this feature should ensure that the // spellings match exactly between the attributes, and if the arguments or // subjects differ, should specify HasCustomParsing = 1 and implement their // own parsing and semantic handling requirements as-needed. string ParseKind; } /// An inheritable parameter attribute is inherited by later /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; /// An attribute which changes the ABI rules for a specific parameter. class ParameterABIAttr : InheritableParamAttr { let Subjects = SubjectList<[ParmVar]>; } /// An ignored attribute, which we parse but discard with no checking. class IgnoredAttr : Attr { let Ignored = 1; let ASTNode = 0; let SemaHandler = 0; let Documentation = [Undocumented]; } // // Attributes begin here // def AbiTag : Attr { let Spellings = [GCC<"abi_tag">]; let Args = [VariadicStringArgument<"Tags">]; let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag>; let MeaningfulToClassTemplateDefinition = 1; let Documentation = [AbiTagsDocs]; } def AddressSpace : TypeAttr { let Spellings = [Clang<"address_space">]; let Args = [IntArgument<"AddressSpace">]; let Documentation = [Undocumented]; } def Alias : Attr { let Spellings = [GCC<"alias">]; let Args = [StringArgument<"Aliasee">]; let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>; let Documentation = [Undocumented]; } def Aligned : InheritableAttr { let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">, Keyword<"_Alignas">]; let Args = [AlignedArgument<"Alignment", 1>]; let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>, Accessor<"isC11", [Keyword<"_Alignas">]>, Accessor<"isAlignas", [Keyword<"alignas">, Keyword<"_Alignas">]>, Accessor<"isDeclspec",[Declspec<"align">]>]; let Documentation = [Undocumented]; } def AlignValue : Attr { let Spellings = [ // Unfortunately, this is semantically an assertion, not a directive // (something else must ensure the alignment), so aligned_value is a // probably a better name. We might want to add an aligned_value spelling in // the future (and a corresponding C++ attribute), but this can be done // later once we decide if we also want them to have slightly-different // semantics than Intel's align_value. // // Does not get a [[]] spelling because the attribute is not exposed as such // by Intel. GNU<"align_value"> // Intel's compiler on Windows also supports: // , Declspec<"align_value"> ]; let Args = [ExprArgument<"Alignment">]; let Subjects = SubjectList<[Var, TypedefName]>; let Documentation = [AlignValueDocs]; } def AlignMac68k : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; let Documentation = [Undocumented]; } def AlwaysInline : InheritableAttr { let Spellings = [GCC<"always_inline">, Keyword<"__forceinline">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def Artificial : InheritableAttr { let Spellings = [GCC<"artificial">]; let Subjects = SubjectList<[InlineFunction], WarnDiag>; let Documentation = [ArtificialDocs]; } def XRayInstrument : InheritableAttr { let Spellings = [Clang<"xray_always_instrument">, Clang<"xray_never_instrument">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let Accessors = [Accessor<"alwaysXRayInstrument", [Clang<"xray_always_instrument">]>, Accessor<"neverXRayInstrument", [Clang<"xray_never_instrument">]>]; let Documentation = [XRayDocs]; } def XRayLogArgs : InheritableAttr { let Spellings = [Clang<"xray_log_args">]; let Subjects = SubjectList<[Function, ObjCMethod]>; // This argument is a count not an index, so it has the same encoding (base // 1 including C++ implicit this parameter) at the source and LLVM levels of // representation, so ParamIdxArgument is inappropriate. It is never used // at the AST level of representation, so it never needs to be adjusted not // to include any C++ implicit this parameter. Thus, we just store it and // use it as an unsigned that never needs adjustment. let Args = [UnsignedArgument<"ArgumentCount">]; let Documentation = [XRayDocs]; } def TLSModel : InheritableAttr { let Spellings = [GCC<"tls_model">]; let Subjects = SubjectList<[TLSVar], ErrorDiag>; let Args = [StringArgument<"Model">]; let Documentation = [TLSModelDocs]; } def AnalyzerNoReturn : InheritableAttr { // TODO: should this attribute be exposed with a [[]] spelling under the clang // vendor namespace, or should it use a vendor namespace specific to the // analyzer? let Spellings = [GNU<"analyzer_noreturn">]; let Documentation = [Undocumented]; } def Annotate : InheritableParamAttr { let Spellings = [Clang<"annotate">]; let Args = [StringArgument<"Annotation">]; // Ensure that the annotate attribute can be used with // '#pragma clang attribute' even though it has no subject list. let ForcePragmaAttributeSupport = 1; let Documentation = [Undocumented]; } def ARMInterrupt : InheritableAttr, TargetSpecificAttr { // NOTE: If you add any additional spellings, MSP430Interrupt's, // MipsInterrupt's and AnyX86Interrupt's spellings must match. let Spellings = [GCC<"interrupt">]; let Args = [EnumArgument<"Interrupt", "InterruptType", ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"], 1>]; let ParseKind = "Interrupt"; let HasCustomParsing = 1; let Documentation = [ARMInterruptDocs]; } def AVRInterrupt : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"interrupt">]; let Subjects = SubjectList<[Function]>; let ParseKind = "Interrupt"; let Documentation = [AVRInterruptDocs]; } def AVRSignal : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"signal">]; let Subjects = SubjectList<[Function]>; let Documentation = [AVRSignalDocs]; } def AsmLabel : InheritableAttr { let Spellings = [Keyword<"asm">, Keyword<"__asm__">]; let Args = [StringArgument<"Label">]; let SemaHandler = 0; let Documentation = [Undocumented]; } def Availability : InheritableAttr { let Spellings = [Clang<"availability">]; let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">, VersionArgument<"deprecated">, VersionArgument<"obsoleted">, BoolArgument<"unavailable">, StringArgument<"message">, BoolArgument<"strict">, StringArgument<"replacement">]; let AdditionalMembers = [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch(Platform) .Case("android", "Android") .Case("ios", "iOS") .Case("macos", "macOS") .Case("tvos", "tvOS") .Case("watchos", "watchOS") .Case("ios_app_extension", "iOS (App Extension)") .Case("macos_app_extension", "macOS (App Extension)") .Case("tvos_app_extension", "tvOS (App Extension)") .Case("watchos_app_extension", "watchOS (App Extension)") .Default(llvm::StringRef()); } static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) { return llvm::StringSwitch(Platform) .Case("ios", "iOS") .Case("macos", "macOS") .Case("tvos", "tvOS") .Case("watchos", "watchOS") .Case("ios_app_extension", "iOSApplicationExtension") .Case("macos_app_extension", "macOSApplicationExtension") .Case("tvos_app_extension", "tvOSApplicationExtension") .Case("watchos_app_extension", "watchOSApplicationExtension") .Default(Platform); } static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) { return llvm::StringSwitch(Platform) .Case("iOS", "ios") .Case("macOS", "macos") .Case("tvOS", "tvos") .Case("watchOS", "watchos") .Case("iOSApplicationExtension", "ios_app_extension") .Case("macOSApplicationExtension", "macos_app_extension") .Case("tvOSApplicationExtension", "tvos_app_extension") .Case("watchOSApplicationExtension", "watchos_app_extension") .Default(Platform); } }]; let HasCustomParsing = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Named]>; let Documentation = [AvailabilityDocs]; } def ExternalSourceSymbol : InheritableAttr { let Spellings = [Clang<"external_source_symbol">]; let Args = [StringArgument<"language", 1>, StringArgument<"definedIn", 1>, BoolArgument<"generatedDeclaration", 1>]; let HasCustomParsing = 1; let Subjects = SubjectList<[Named]>; let Documentation = [ExternalSourceSymbolDocs]; } def Blocks : InheritableAttr { let Spellings = [Clang<"blocks">]; let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>]; let Documentation = [Undocumented]; } def Bounded : IgnoredAttr { // Does not have a [[]] spelling because the attribute is ignored. let Spellings = [GNU<"bounded">]; } def CarriesDependency : InheritableParamAttr { let Spellings = [GNU<"carries_dependency">, CXX11<"","carries_dependency", 200809>]; let Subjects = SubjectList<[ParmVar, ObjCMethod, Function], ErrorDiag>; let Documentation = [CarriesDependencyDocs]; } def CDecl : DeclOrTypeAttr { let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } // cf_audited_transfer indicates that the given function has been // audited and has been marked with the appropriate cf_consumed and // cf_returns_retained attributes. It is generally applied by // '#pragma clang arc_cf_code_audited' rather than explicitly. def CFAuditedTransfer : InheritableAttr { let Spellings = [Clang<"cf_audited_transfer">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } // cf_unknown_transfer is an explicit opt-out of cf_audited_transfer. // It indicates that the function has unknown or unautomatable // transfer semantics. def CFUnknownTransfer : InheritableAttr { let Spellings = [Clang<"cf_unknown_transfer">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def CFReturnsRetained : InheritableAttr { let Spellings = [Clang<"cf_returns_retained">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def CFReturnsNotRetained : InheritableAttr { let Spellings = [Clang<"cf_returns_not_retained">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def CFConsumed : InheritableParamAttr { let Spellings = [Clang<"cf_consumed">]; let Subjects = SubjectList<[ParmVar]>; let Documentation = [Undocumented]; } def Cleanup : InheritableAttr { let Spellings = [GCC<"cleanup">]; let Args = [FunctionArgument<"FunctionDecl">]; let Subjects = SubjectList<[LocalVar]>; let Documentation = [Undocumented]; } def Cold : InheritableAttr { let Spellings = [GCC<"cold">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def Common : InheritableAttr { let Spellings = [GCC<"common">]; let Subjects = SubjectList<[Var]>; let Documentation = [Undocumented]; } def Const : InheritableAttr { let Spellings = [GCC<"const">, GCC<"__const">]; let Documentation = [Undocumented]; } def Constructor : InheritableAttr { let Spellings = [GCC<"constructor">]; let Args = [DefaultIntArgument<"Priority", 65535>]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def CPUSpecific : InheritableAttr { let Spellings = [Clang<"cpu_specific">]; let Args = [VariadicIdentifierArgument<"Cpus">]; let Subjects = SubjectList<[Function]>; let Documentation = [CPUSpecificCPUDispatchDocs]; let AdditionalMembers = [{ unsigned ActiveArgIndex = 0; IdentifierInfo *getCurCPUName() const { return *(cpus_begin() + ActiveArgIndex); } }]; } def CPUDispatch : InheritableAttr { let Spellings = [Clang<"cpu_dispatch">]; let Args = [VariadicIdentifierArgument<"Cpus">]; let Subjects = SubjectList<[Function]>; let Documentation = [CPUSpecificCPUDispatchDocs]; } // CUDA attributes are spelled __attribute__((attr)) or __declspec(__attr__), // and they do not receive a [[]] spelling. def CUDAConstant : InheritableAttr { let Spellings = [GNU<"constant">, Declspec<"__constant__">]; let Subjects = SubjectList<[Var]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def CUDACudartBuiltin : IgnoredAttr { let Spellings = [GNU<"cudart_builtin">, Declspec<"__cudart_builtin__">]; let LangOpts = [CUDA]; } def CUDADevice : InheritableAttr { let Spellings = [GNU<"device">, Declspec<"__device__">]; let Subjects = SubjectList<[Function, Var]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def CUDADeviceBuiltin : IgnoredAttr { let Spellings = [GNU<"device_builtin">, Declspec<"__device_builtin__">]; let LangOpts = [CUDA]; } def CUDADeviceBuiltinSurfaceType : IgnoredAttr { let Spellings = [GNU<"device_builtin_surface_type">, Declspec<"__device_builtin_surface_type__">]; let LangOpts = [CUDA]; } def CUDADeviceBuiltinTextureType : IgnoredAttr { let Spellings = [GNU<"device_builtin_texture_type">, Declspec<"__device_builtin_texture_type__">]; let LangOpts = [CUDA]; } def CUDAGlobal : InheritableAttr { let Spellings = [GNU<"global">, Declspec<"__global__">]; let Subjects = SubjectList<[Function]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def CUDAHost : InheritableAttr { let Spellings = [GNU<"host">, Declspec<"__host__">]; let Subjects = SubjectList<[Function]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def CUDAInvalidTarget : InheritableAttr { let Spellings = []; let Subjects = SubjectList<[Function]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def CUDALaunchBounds : InheritableAttr { let Spellings = [GNU<"launch_bounds">, Declspec<"__launch_bounds__">]; let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>]; let LangOpts = [CUDA]; let Subjects = SubjectList<[ObjCMethod, FunctionLike]>; // An AST node is created for this attribute, but is not used by other parts // of the compiler. However, this node needs to exist in the AST because // non-LLVM backends may be relying on the attribute's presence. let Documentation = [Undocumented]; } def CUDAShared : InheritableAttr { let Spellings = [GNU<"shared">, Declspec<"__shared__">]; let Subjects = SubjectList<[Var]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def C11NoReturn : InheritableAttr { let Spellings = [Keyword<"_Noreturn">]; let Subjects = SubjectList<[Function], ErrorDiag>; let SemaHandler = 0; let Documentation = [C11NoReturnDocs]; } def CXX11NoReturn : InheritableAttr { let Spellings = [CXX11<"", "noreturn", 200809>]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [CXX11NoReturnDocs]; } // Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because // the specification does not expose them with one currently. def OpenCLKernel : InheritableAttr { let Spellings = [Keyword<"__kernel">, Keyword<"kernel">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def OpenCLUnrollHint : InheritableAttr { let Spellings = [GNU<"opencl_unroll_hint">]; let Args = [UnsignedArgument<"UnrollHint">]; let Documentation = [OpenCLUnrollHintDocs]; } def OpenCLIntelReqdSubGroupSize: InheritableAttr { let Spellings = [GNU<"intel_reqd_sub_group_size">]; let Args = [UnsignedArgument<"SubGroupSize">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [OpenCLIntelReqdSubGroupSizeDocs]; } // This attribute is both a type attribute, and a declaration attribute (for // parameter variables). def OpenCLAccess : Attr { let Spellings = [Keyword<"__read_only">, Keyword<"read_only">, Keyword<"__write_only">, Keyword<"write_only">, Keyword<"__read_write">, Keyword<"read_write">]; let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag>; let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">, Keyword<"read_only">]>, Accessor<"isReadWrite", [Keyword<"__read_write">, Keyword<"read_write">]>, Accessor<"isWriteOnly", [Keyword<"__write_only">, Keyword<"write_only">]>]; let Documentation = [OpenCLAccessDocs]; } def OpenCLPrivateAddressSpace : TypeAttr { let Spellings = [Keyword<"__private">, Keyword<"private">]; let Documentation = [OpenCLAddressSpacePrivateDocs]; } def OpenCLGlobalAddressSpace : TypeAttr { let Spellings = [Keyword<"__global">, Keyword<"global">]; let Documentation = [OpenCLAddressSpaceGlobalDocs]; } def OpenCLLocalAddressSpace : TypeAttr { let Spellings = [Keyword<"__local">, Keyword<"local">]; let Documentation = [OpenCLAddressSpaceLocalDocs]; } def OpenCLConstantAddressSpace : TypeAttr { let Spellings = [Keyword<"__constant">, Keyword<"constant">]; let Documentation = [OpenCLAddressSpaceConstantDocs]; } def OpenCLGenericAddressSpace : TypeAttr { let Spellings = [Keyword<"__generic">, Keyword<"generic">]; let Documentation = [OpenCLAddressSpaceGenericDocs]; } def OpenCLNoSVM : Attr { let Spellings = [GNU<"nosvm">]; let Subjects = SubjectList<[Var]>; let Documentation = [OpenCLNoSVMDocs]; let LangOpts = [OpenCL]; let ASTNode = 0; } def RenderScriptKernel : Attr { let Spellings = [GNU<"kernel">]; let Subjects = SubjectList<[Function]>; let Documentation = [RenderScriptKernelAttributeDocs]; let LangOpts = [RenderScript]; } def Deprecated : InheritableAttr { let Spellings = [GCC<"deprecated">, Declspec<"deprecated">, CXX11<"","deprecated", 201309>, C2x<"", "deprecated">]; let Args = [StringArgument<"Message", 1>, // An optional string argument that enables us to provide a // Fix-It. StringArgument<"Replacement", 1>]; let MeaningfulToClassTemplateDefinition = 1; let Documentation = [DeprecatedDocs]; } def Destructor : InheritableAttr { let Spellings = [GCC<"destructor">]; let Args = [DefaultIntArgument<"Priority", 65535>]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def EmptyBases : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"empty_bases">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [EmptyBasesDocs]; } def AllocSize : InheritableAttr { let Spellings = [GCC<"alloc_size">]; let Subjects = SubjectList<[Function]>; let Args = [ParamIdxArgument<"ElemSizeParam">, ParamIdxArgument<"NumElemsParam", /*opt*/ 1>]; let TemplateDependent = 1; let Documentation = [AllocSizeDocs]; } def EnableIf : InheritableAttr { // Does not have a [[]] spelling because this attribute requires the ability // to parse function arguments but the attribute is not written in the type // position. let Spellings = [GNU<"enable_if">]; let Subjects = SubjectList<[Function]>; let Args = [ExprArgument<"Cond">, StringArgument<"Message">]; let TemplateDependent = 1; let Documentation = [EnableIfDocs]; } def ExtVectorType : Attr { // This is an OpenCL-related attribute and does not receive a [[]] spelling. let Spellings = [GNU<"ext_vector_type">]; let Subjects = SubjectList<[TypedefName], ErrorDiag>; let Args = [ExprArgument<"NumElements">]; let ASTNode = 0; let Documentation = [Undocumented]; } def FallThrough : StmtAttr { let Spellings = [CXX11<"", "fallthrough", 201603>, C2x<"", "fallthrough">, CXX11<"clang", "fallthrough">]; // let Subjects = [NullStmt]; let Documentation = [FallthroughDocs]; } def FastCall : DeclOrTypeAttr { let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">, Keyword<"_fastcall">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [FastCallDocs]; } def RegCall : DeclOrTypeAttr { let Spellings = [GCC<"regcall">, Keyword<"__regcall">]; let Documentation = [RegCallDocs]; } def Final : InheritableAttr { let Spellings = [Keyword<"final">, Keyword<"sealed">]; let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>]; let SemaHandler = 0; let Documentation = [Undocumented]; } def MinSize : InheritableAttr { let Spellings = [Clang<"minsize">]; let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>; let Documentation = [Undocumented]; } def FlagEnum : InheritableAttr { let Spellings = [Clang<"flag_enum">]; let Subjects = SubjectList<[Enum]>; let Documentation = [FlagEnumDocs]; } def EnumExtensibility : InheritableAttr { let Spellings = [Clang<"enum_extensibility">]; let Subjects = SubjectList<[Enum]>; let Args = [EnumArgument<"Extensibility", "Kind", ["closed", "open"], ["Closed", "Open"]>]; let Documentation = [EnumExtensibilityDocs]; } def Flatten : InheritableAttr { let Spellings = [GCC<"flatten">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [FlattenDocs]; } def Format : InheritableAttr { let Spellings = [GCC<"format">]; let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">, IntArgument<"FirstArg">]; let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto]>; let Documentation = [FormatDocs]; } def FormatArg : InheritableAttr { let Spellings = [GCC<"format_arg">]; let Args = [ParamIdxArgument<"FormatIdx">]; let Subjects = SubjectList<[ObjCMethod, HasFunctionProto]>; let Documentation = [Undocumented]; } def GNUInline : InheritableAttr { let Spellings = [GCC<"gnu_inline">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def Hot : InheritableAttr { let Spellings = [GCC<"hot">]; let Subjects = SubjectList<[Function]>; // An AST node is created for this attribute, but not actually used beyond // semantic checking for mutual exclusion with the Cold attribute. let Documentation = [Undocumented]; } def IBAction : InheritableAttr { let Spellings = [Clang<"ibaction">]; let Subjects = SubjectList<[ObjCInstanceMethod]>; // An AST node is created for this attribute, but is not used by other parts // of the compiler. However, this node needs to exist in the AST because // external tools rely on it. let Documentation = [Undocumented]; } def IBOutlet : InheritableAttr { let Spellings = [Clang<"iboutlet">]; // let Subjects = [ObjCIvar, ObjCProperty]; let Documentation = [Undocumented]; } def IBOutletCollection : InheritableAttr { let Spellings = [Clang<"iboutletcollection">]; let Args = [TypeArgument<"Interface", 1>]; // let Subjects = [ObjCIvar, ObjCProperty]; let Documentation = [Undocumented]; } def IFunc : Attr, TargetSpecificAttr { let Spellings = [GCC<"ifunc">]; let Args = [StringArgument<"Resolver">]; let Subjects = SubjectList<[Function]>; let Documentation = [IFuncDocs]; } def Restrict : InheritableAttr { let Spellings = [Declspec<"restrict">, GCC<"malloc">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def LayoutVersion : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"layout_version">]; let Args = [UnsignedArgument<"Version">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [LayoutVersionDocs]; } def LifetimeBound : InheritableAttr { let Spellings = [Clang<"lifetimebound", 0>]; let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>; let Documentation = [LifetimeBoundDocs]; let LangOpts = [CPlusPlus]; } def TrivialABI : InheritableAttr { // This attribute does not have a C [[]] spelling because it requires the // CPlusPlus language option. let Spellings = [Clang<"trivial_abi", 0>]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [TrivialABIDocs]; let LangOpts = [CPlusPlus]; } def MaxFieldAlignment : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let Args = [UnsignedArgument<"Alignment">]; let SemaHandler = 0; let Documentation = [Undocumented]; } def MayAlias : InheritableAttr { // FIXME: this is a type attribute in GCC, but a declaration attribute here. let Spellings = [GCC<"may_alias">]; let Documentation = [Undocumented]; } def MSABI : DeclOrTypeAttr { let Spellings = [GCC<"ms_abi">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [MSABIDocs]; } def MSP430Interrupt : InheritableAttr, TargetSpecificAttr { // NOTE: If you add any additional spellings, ARMInterrupt's, MipsInterrupt's // and AnyX86Interrupt's spellings must match. let Spellings = [GCC<"interrupt">]; let Args = [UnsignedArgument<"Number">]; let ParseKind = "Interrupt"; let HasCustomParsing = 1; let Documentation = [Undocumented]; } def Mips16 : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"mips16">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def MipsInterrupt : InheritableAttr, TargetSpecificAttr { // NOTE: If you add any additional spellings, ARMInterrupt's, // MSP430Interrupt's and AnyX86Interrupt's spellings must match. let Spellings = [GCC<"interrupt">]; let Subjects = SubjectList<[Function]>; let Args = [EnumArgument<"Interrupt", "InterruptType", ["vector=sw0", "vector=sw1", "vector=hw0", "vector=hw1", "vector=hw2", "vector=hw3", "vector=hw4", "vector=hw5", "eic", ""], ["sw0", "sw1", "hw0", "hw1", "hw2", "hw3", "hw4", "hw5", "eic", "eic"] >]; let ParseKind = "Interrupt"; let Documentation = [MipsInterruptDocs]; } def MicroMips : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"micromips">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [MicroMipsDocs]; } def MipsLongCall : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"long_call">, GCC<"far">]; let Subjects = SubjectList<[Function]>; let Documentation = [MipsLongCallStyleDocs]; } def MipsShortCall : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"short_call">, GCC<"near">]; let Subjects = SubjectList<[Function]>; let Documentation = [MipsShortCallStyleDocs]; } def Mode : Attr { let Spellings = [GCC<"mode">]; let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag>; let Args = [IdentifierArgument<"Mode">]; let Documentation = [Undocumented]; } def Naked : InheritableAttr { let Spellings = [GCC<"naked">, Declspec<"naked">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def NeonPolyVectorType : TypeAttr { let Spellings = [Clang<"neon_polyvector_type">]; let Args = [IntArgument<"NumElements">]; let Documentation = [Undocumented]; } def NeonVectorType : TypeAttr { let Spellings = [Clang<"neon_vector_type">]; let Args = [IntArgument<"NumElements">]; let Documentation = [Undocumented]; } def ReturnsTwice : InheritableAttr { let Spellings = [GCC<"returns_twice">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def DisableTailCalls : InheritableAttr { let Spellings = [Clang<"disable_tail_calls">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let Documentation = [DisableTailCallsDocs]; } def NoAlias : InheritableAttr { let Spellings = [Declspec<"noalias">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoAliasDocs]; } def NoCommon : InheritableAttr { let Spellings = [GCC<"nocommon">]; let Subjects = SubjectList<[Var]>; let Documentation = [Undocumented]; } def NoDebug : InheritableAttr { let Spellings = [GCC<"nodebug">]; let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar]>; let Documentation = [NoDebugDocs]; } def NoDuplicate : InheritableAttr { let Spellings = [Clang<"noduplicate">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoDuplicateDocs]; } def Convergent : InheritableAttr { let Spellings = [Clang<"convergent">]; let Subjects = SubjectList<[Function]>; let Documentation = [ConvergentDocs]; } def NoInline : InheritableAttr { let Spellings = [GCC<"noinline">, Declspec<"noinline">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def NoMips16 : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"nomips16">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def NoMicroMips : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"nomicromips">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [MicroMipsDocs]; } def RISCVInterrupt : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"interrupt">]; let Subjects = SubjectList<[Function]>; let Args = [EnumArgument<"Interrupt", "InterruptType", ["user", "supervisor", "machine"], ["user", "supervisor", "machine"], 1>]; let ParseKind = "Interrupt"; let Documentation = [RISCVInterruptDocs]; } // This is not a TargetSpecificAttr so that is silently accepted and // ignored on other targets as encouraged by the OpenCL spec. // // See OpenCL 1.2 6.11.5: "It is our intention that a particular // implementation of OpenCL be free to ignore all attributes and the // resulting executable binary will produce the same result." // // However, only AMD GPU targets will emit the corresponding IR // attribute. // // FIXME: This provides a sub-optimal error message if you attempt to // use this in CUDA, since CUDA does not use the same terminology. // // FIXME: SubjectList should be for OpenCLKernelFunction, but is not to // workaround needing to see kernel attribute before others to know if // this should be rejected on non-kernels. def AMDGPUFlatWorkGroupSize : InheritableAttr { let Spellings = [Clang<"amdgpu_flat_work_group_size", 0>]; let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">]; let Documentation = [AMDGPUFlatWorkGroupSizeDocs]; let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } def AMDGPUWavesPerEU : InheritableAttr { let Spellings = [Clang<"amdgpu_waves_per_eu", 0>]; let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>]; let Documentation = [AMDGPUWavesPerEUDocs]; let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } def AMDGPUNumSGPR : InheritableAttr { let Spellings = [Clang<"amdgpu_num_sgpr", 0>]; let Args = [UnsignedArgument<"NumSGPR">]; let Documentation = [AMDGPUNumSGPRNumVGPRDocs]; let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } def AMDGPUNumVGPR : InheritableAttr { let Spellings = [Clang<"amdgpu_num_vgpr", 0>]; let Args = [UnsignedArgument<"NumVGPR">]; let Documentation = [AMDGPUNumSGPRNumVGPRDocs]; let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } def NoSplitStack : InheritableAttr { let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [NoSplitStackDocs]; } def NonNull : InheritableParamAttr { let Spellings = [GCC<"nonnull">]; let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag, "functions, methods, and parameters">; let Args = [VariadicParamIdxArgument<"Args">]; let AdditionalMembers = [{ bool isNonNull(unsigned IdxAST) const { if (!args_size()) return true; return args_end() != std::find_if( args_begin(), args_end(), [=](const ParamIdx &Idx) { return Idx.getASTIndex() == IdxAST; }); } }]; // FIXME: We should merge duplicates into a single nonnull attribute. let InheritEvenIfAlreadyPresent = 1; let Documentation = [NonNullDocs]; } def ReturnsNonNull : InheritableAttr { let Spellings = [GCC<"returns_nonnull">]; let Subjects = SubjectList<[ObjCMethod, Function]>; let Documentation = [ReturnsNonNullDocs]; } // pass_object_size(N) indicates that the parameter should have // __builtin_object_size with Type=N evaluated on the parameter at the callsite. def PassObjectSize : InheritableParamAttr { let Spellings = [Clang<"pass_object_size">]; let Args = [IntArgument<"Type">]; let Subjects = SubjectList<[ParmVar]>; let Documentation = [PassObjectSizeDocs]; } // Nullability type attributes. def TypeNonNull : TypeAttr { let Spellings = [Keyword<"_Nonnull">]; let Documentation = [TypeNonNullDocs]; } def TypeNullable : TypeAttr { let Spellings = [Keyword<"_Nullable">]; let Documentation = [TypeNullableDocs]; } def TypeNullUnspecified : TypeAttr { let Spellings = [Keyword<"_Null_unspecified">]; let Documentation = [TypeNullUnspecifiedDocs]; } def ObjCKindOf : TypeAttr { let Spellings = [Keyword<"__kindof">]; let Documentation = [Undocumented]; } def NoEscape : Attr { let Spellings = [Clang<"noescape">]; let Subjects = SubjectList<[ParmVar]>; let Documentation = [NoEscapeDocs]; } def AssumeAligned : InheritableAttr { let Spellings = [GCC<"assume_aligned">]; let Subjects = SubjectList<[ObjCMethod, Function]>; let Args = [ExprArgument<"Alignment">, ExprArgument<"Offset", 1>]; let Documentation = [AssumeAlignedDocs]; } def AllocAlign : InheritableAttr { let Spellings = [GCC<"alloc_align">]; let Subjects = SubjectList<[HasFunctionProto]>; let Args = [ParamIdxArgument<"ParamIndex">]; let Documentation = [AllocAlignDocs]; } def NoReturn : InheritableAttr { let Spellings = [GCC<"noreturn">, Declspec<"noreturn">]; // FIXME: Does GCC allow this on the function instead? let Documentation = [Undocumented]; } def NoInstrumentFunction : InheritableAttr { let Spellings = [GCC<"no_instrument_function">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def NotTailCalled : InheritableAttr { let Spellings = [Clang<"not_tail_called">]; let Subjects = SubjectList<[Function]>; let Documentation = [NotTailCalledDocs]; } def NoStackProtector : InheritableAttr { let Spellings = [Clang<"no_stack_protector">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoStackProtectorDocs]; } def NoThrow : InheritableAttr { let Spellings = [GCC<"nothrow">, Declspec<"nothrow">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoThrowDocs]; } def NvWeak : IgnoredAttr { // No Declspec spelling of this attribute; the CUDA headers use // __attribute__((nv_weak)) unconditionally. Does not receive an [[]] // spelling because it is a CUDA attribute. let Spellings = [GNU<"nv_weak">]; let LangOpts = [CUDA]; } def ObjCBridge : InheritableAttr { let Spellings = [Clang<"objc_bridge">]; let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>; let Args = [IdentifierArgument<"BridgedType">]; let Documentation = [Undocumented]; } def ObjCBridgeMutable : InheritableAttr { let Spellings = [Clang<"objc_bridge_mutable">]; let Subjects = SubjectList<[Record], ErrorDiag>; let Args = [IdentifierArgument<"BridgedType">]; let Documentation = [Undocumented]; } def ObjCBridgeRelated : InheritableAttr { let Spellings = [Clang<"objc_bridge_related">]; let Subjects = SubjectList<[Record], ErrorDiag>; let Args = [IdentifierArgument<"RelatedClass">, IdentifierArgument<"ClassMethod">, IdentifierArgument<"InstanceMethod">]; let HasCustomParsing = 1; let Documentation = [Undocumented]; } def NSReturnsRetained : InheritableAttr { let Spellings = [Clang<"ns_returns_retained">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def NSReturnsNotRetained : InheritableAttr { let Spellings = [Clang<"ns_returns_not_retained">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def NSReturnsAutoreleased : InheritableAttr { let Spellings = [Clang<"ns_returns_autoreleased">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def NSConsumesSelf : InheritableAttr { let Spellings = [Clang<"ns_consumes_self">]; let Subjects = SubjectList<[ObjCMethod]>; let Documentation = [Undocumented]; } def NSConsumed : InheritableParamAttr { let Spellings = [Clang<"ns_consumed">]; let Subjects = SubjectList<[ParmVar]>; let Documentation = [Undocumented]; } def ObjCException : InheritableAttr { let Spellings = [Clang<"objc_exception">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCMethodFamily : InheritableAttr { let Spellings = [Clang<"objc_method_family">]; let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; let Args = [EnumArgument<"Family", "FamilyKind", ["none", "alloc", "copy", "init", "mutableCopy", "new"], ["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init", "OMF_mutableCopy", "OMF_new"]>]; let Documentation = [ObjCMethodFamilyDocs]; } def ObjCNSObject : InheritableAttr { let Spellings = [Clang<"NSObject">]; let Documentation = [Undocumented]; } def ObjCIndependentClass : InheritableAttr { let Spellings = [Clang<"objc_independent_class">]; let Documentation = [Undocumented]; } def ObjCPreciseLifetime : InheritableAttr { let Spellings = [Clang<"objc_precise_lifetime">]; let Subjects = SubjectList<[Var], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCReturnsInnerPointer : InheritableAttr { let Spellings = [Clang<"objc_returns_inner_pointer">]; let Subjects = SubjectList<[ObjCMethod, ObjCProperty], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCRequiresSuper : InheritableAttr { let Spellings = [Clang<"objc_requires_super">]; let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; let Documentation = [ObjCRequiresSuperDocs]; } def ObjCRootClass : InheritableAttr { let Spellings = [Clang<"objc_root_class">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCSubclassingRestricted : InheritableAttr { let Spellings = [Clang<"objc_subclassing_restricted">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [ObjCSubclassingRestrictedDocs]; } def ObjCExplicitProtocolImpl : InheritableAttr { let Spellings = [Clang<"objc_protocol_requires_explicit_implementation">]; let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCDesignatedInitializer : Attr { let Spellings = [Clang<"objc_designated_initializer">]; let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCRuntimeName : Attr { let Spellings = [Clang<"objc_runtime_name">]; let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>; let Args = [StringArgument<"MetadataName">]; let Documentation = [ObjCRuntimeNameDocs]; } def ObjCRuntimeVisible : Attr { let Spellings = [Clang<"objc_runtime_visible">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [ObjCRuntimeVisibleDocs]; } def ObjCBoxable : Attr { let Spellings = [Clang<"objc_boxable">]; let Subjects = SubjectList<[Record], ErrorDiag>; let Documentation = [ObjCBoxableDocs]; } def OptimizeNone : InheritableAttr { let Spellings = [Clang<"optnone">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let Documentation = [OptnoneDocs]; } def Overloadable : Attr { let Spellings = [Clang<"overloadable">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [OverloadableDocs]; } def Override : InheritableAttr { let Spellings = [Keyword<"override">]; let SemaHandler = 0; let Documentation = [Undocumented]; } def Ownership : InheritableAttr { let Spellings = [Clang<"ownership_holds">, Clang<"ownership_returns">, Clang<"ownership_takes">]; let Accessors = [Accessor<"isHolds", [Clang<"ownership_holds">]>, Accessor<"isReturns", [Clang<"ownership_returns">]>, Accessor<"isTakes", [Clang<"ownership_takes">]>]; let AdditionalMembers = [{ enum OwnershipKind { Holds, Returns, Takes }; OwnershipKind getOwnKind() const { return isHolds() ? Holds : isTakes() ? Takes : Returns; } }]; let Args = [IdentifierArgument<"Module">, VariadicParamIdxArgument<"Args">]; let Subjects = SubjectList<[HasFunctionProto]>; let Documentation = [Undocumented]; } def Packed : InheritableAttr { let Spellings = [GCC<"packed">]; // let Subjects = [Tag, Field]; let Documentation = [Undocumented]; } def IntelOclBicc : DeclOrTypeAttr { let Spellings = [Clang<"intel_ocl_bicc", 0>]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def Pcs : DeclOrTypeAttr { let Spellings = [GCC<"pcs">]; let Args = [EnumArgument<"PCS", "PCSType", ["aapcs", "aapcs-vfp"], ["AAPCS", "AAPCS_VFP"]>]; // let Subjects = [Function, ObjCMethod]; let Documentation = [PcsDocs]; } def Pure : InheritableAttr { let Spellings = [GCC<"pure">]; let Documentation = [Undocumented]; } def Regparm : TypeAttr { let Spellings = [GCC<"regparm">]; let Args = [UnsignedArgument<"NumParams">]; let Documentation = [RegparmDocs]; } def ReqdWorkGroupSize : InheritableAttr { // Does not have a [[]] spelling because it is an OpenCL-related attribute. let Spellings = [GNU<"reqd_work_group_size">]; let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">, UnsignedArgument<"ZDim">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def RequireConstantInit : InheritableAttr { // This attribute does not have a C [[]] spelling because it requires the // CPlusPlus language option. let Spellings = [Clang<"require_constant_initialization", 0>]; let Subjects = SubjectList<[GlobalVar], ErrorDiag>; let Documentation = [RequireConstantInitDocs]; let LangOpts = [CPlusPlus]; } def WorkGroupSizeHint : InheritableAttr { // Does not have a [[]] spelling because it is an OpenCL-related attribute. let Spellings = [GNU<"work_group_size_hint">]; let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">, UnsignedArgument<"ZDim">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def InitPriority : InheritableAttr { let Spellings = [GCC<"init_priority">]; let Args = [UnsignedArgument<"Priority">]; let Subjects = SubjectList<[Var], ErrorDiag>; let Documentation = [Undocumented]; } def Section : InheritableAttr { let Spellings = [GCC<"section">, Declspec<"allocate">]; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[ Function, GlobalVar, ObjCMethod, ObjCProperty ], ErrorDiag>; let Documentation = [SectionDocs]; } def CodeSeg : InheritableAttr { let Spellings = [Declspec<"code_seg">]; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[Function, CXXRecord], ErrorDiag>; let Documentation = [CodeSegDocs]; } def PragmaClangBSSSection : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[GlobalVar], ErrorDiag>; let Documentation = [Undocumented]; } def PragmaClangDataSection : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[GlobalVar], ErrorDiag>; let Documentation = [Undocumented]; } def PragmaClangRodataSection : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[GlobalVar], ErrorDiag>; let Documentation = [Undocumented]; } def PragmaClangTextSection : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let Args = [StringArgument<"Name">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def Sentinel : InheritableAttr { let Spellings = [GCC<"sentinel">]; let Args = [DefaultIntArgument<"Sentinel", 0>, DefaultIntArgument<"NullPos", 0>]; // let Subjects = SubjectList<[Function, ObjCMethod, Block, Var]>; let Documentation = [Undocumented]; } def StdCall : DeclOrTypeAttr { let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [StdCallDocs]; } def SwiftCall : DeclOrTypeAttr { let Spellings = [Clang<"swiftcall">]; // let Subjects = SubjectList<[Function]>; let Documentation = [SwiftCallDocs]; } def SwiftContext : ParameterABIAttr { let Spellings = [Clang<"swift_context">]; let Documentation = [SwiftContextDocs]; } def SwiftErrorResult : ParameterABIAttr { let Spellings = [Clang<"swift_error_result">]; let Documentation = [SwiftErrorResultDocs]; } def SwiftIndirectResult : ParameterABIAttr { let Spellings = [Clang<"swift_indirect_result">]; let Documentation = [SwiftIndirectResultDocs]; } def Suppress : StmtAttr { let Spellings = [CXX11<"gsl", "suppress">]; let Args = [VariadicStringArgument<"DiagnosticIdentifiers">]; let Documentation = [SuppressDocs]; } def SysVABI : DeclOrTypeAttr { let Spellings = [GCC<"sysv_abi">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def ThisCall : DeclOrTypeAttr { let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">, Keyword<"_thiscall">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [ThisCallDocs]; } def VectorCall : DeclOrTypeAttr { let Spellings = [Clang<"vectorcall">, Keyword<"__vectorcall">, Keyword<"_vectorcall">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [VectorCallDocs]; } def Pascal : DeclOrTypeAttr { let Spellings = [Clang<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def PreserveMost : DeclOrTypeAttr { let Spellings = [Clang<"preserve_most">]; let Documentation = [PreserveMostDocs]; } def PreserveAll : DeclOrTypeAttr { let Spellings = [Clang<"preserve_all">]; let Documentation = [PreserveAllDocs]; } def Target : InheritableAttr { let Spellings = [GCC<"target">]; let Args = [StringArgument<"featuresStr">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [TargetDocs]; let AdditionalMembers = [{ struct ParsedTargetAttr { std::vector Features; StringRef Architecture; bool DuplicateArchitecture = false; bool operator ==(const ParsedTargetAttr &Other) const { return DuplicateArchitecture == Other.DuplicateArchitecture && Architecture == Other.Architecture && Features == Other.Features; } }; ParsedTargetAttr parse() const { return parse(getFeaturesStr()); } + StringRef getArchitecture() const { + StringRef Features = getFeaturesStr(); + if (Features == "default") return {}; + + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { + Feature = Feature.trim(); + if (Feature.startswith("arch=")) + return Feature.drop_front(sizeof("arch=") - 1); + } + return ""; + } + + // Gets the list of features as simple string-refs with no +/- or 'no-'. + // Only adds the items to 'Out' that are additions. + void getAddedFeatures(llvm::SmallVectorImpl &Out) const { + StringRef Features = getFeaturesStr(); + if (Features == "default") return; + + SmallVector AttrFeatures; + Features.split(AttrFeatures, ","); + + for (auto &Feature : AttrFeatures) { + Feature = Feature.trim(); + + if (!Feature.startswith("no-") && !Feature.startswith("arch=") && + !Feature.startswith("fpmath=") && !Feature.startswith("tune=")) + Out.push_back(Feature); + } + } + template ParsedTargetAttr parse(Compare cmp) const { ParsedTargetAttr Attrs = parse(); llvm::sort(std::begin(Attrs.Features), std::end(Attrs.Features), cmp); return Attrs; } bool isDefaultVersion() const { return getFeaturesStr() == "default"; } static ParsedTargetAttr parse(StringRef Features) { ParsedTargetAttr Ret; if (Features == "default") return Ret; SmallVector AttrFeatures; Features.split(AttrFeatures, ","); // Grab the various features and prepend a "+" to turn on the feature to // the backend and add them to our existing set of features. for (auto &Feature : AttrFeatures) { // Go ahead and trim whitespace rather than either erroring or // accepting it weirdly. Feature = Feature.trim(); // We don't support cpu tuning this way currently. // TODO: Support the fpmath option. It will require checking // overall feature validity for the function with the rest of the // attributes on the function. if (Feature.startswith("fpmath=") || Feature.startswith("tune=")) continue; // While we're here iterating check for a different target cpu. if (Feature.startswith("arch=")) { if (!Ret.Architecture.empty()) Ret.DuplicateArchitecture = true; else Ret.Architecture = Feature.split("=").second.trim(); } else if (Feature.startswith("no-")) Ret.Features.push_back("-" + Feature.split("-").second.str()); else Ret.Features.push_back("+" + Feature.str()); } return Ret; } }]; } def MinVectorWidth : InheritableAttr { let Spellings = [Clang<"min_vector_width">]; let Args = [UnsignedArgument<"VectorWidth">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [MinVectorWidthDocs]; } def TransparentUnion : InheritableAttr { let Spellings = [GCC<"transparent_union">]; // let Subjects = SubjectList<[Record, TypedefName]>; let Documentation = [TransparentUnionDocs]; let LangOpts = [COnly]; } def Unavailable : InheritableAttr { let Spellings = [Clang<"unavailable">]; let Args = [StringArgument<"Message", 1>, EnumArgument<"ImplicitReason", "ImplicitReason", ["", "", "", ""], ["IR_None", "IR_ARCForbiddenType", "IR_ForbiddenWeak", "IR_ARCForbiddenConversion", "IR_ARCInitReturnsUnrelated", "IR_ARCFieldWithOwnership"], 1, /*fake*/ 1>]; let Documentation = [Undocumented]; } def DiagnoseIf : InheritableAttr { // Does not have a [[]] spelling because this attribute requires the ability // to parse function arguments but the attribute is not written in the type // position. let Spellings = [GNU<"diagnose_if">]; let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>; let Args = [ExprArgument<"Cond">, StringArgument<"Message">, EnumArgument<"DiagnosticType", "DiagnosticType", ["error", "warning"], ["DT_Error", "DT_Warning"]>, BoolArgument<"ArgDependent", 0, /*fake*/ 1>, NamedArgument<"Parent", 0, /*fake*/ 1>]; let InheritEvenIfAlreadyPresent = 1; let LateParsed = 1; let AdditionalMembers = [{ bool isError() const { return diagnosticType == DT_Error; } bool isWarning() const { return diagnosticType == DT_Warning; } }]; let TemplateDependent = 1; let Documentation = [DiagnoseIfDocs]; } def ArcWeakrefUnavailable : InheritableAttr { let Spellings = [Clang<"objc_arc_weak_reference_unavailable">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCGC : TypeAttr { let Spellings = [Clang<"objc_gc">]; let Args = [IdentifierArgument<"Kind">]; let Documentation = [Undocumented]; } def ObjCOwnership : InheritableAttr { let Spellings = [Clang<"objc_ownership">]; let Args = [IdentifierArgument<"Kind">]; let ASTNode = 0; let Documentation = [Undocumented]; } def ObjCRequiresPropertyDefs : InheritableAttr { let Spellings = [Clang<"objc_requires_property_definitions">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; } def Unused : InheritableAttr { let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">, C2x<"", "maybe_unused">]; let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label, Field, ObjCMethod, FunctionLike]>; let Documentation = [WarnMaybeUnusedDocs]; } def Used : InheritableAttr { let Spellings = [GCC<"used">]; let Subjects = SubjectList<[NonLocalVar, Function, ObjCMethod]>; let Documentation = [Undocumented]; } def Uuid : InheritableAttr { let Spellings = [Declspec<"uuid">, Microsoft<"uuid">]; let Args = [StringArgument<"Guid">]; let Subjects = SubjectList<[Record, Enum]>; // FIXME: Allow expressing logical AND for LangOpts. Our condition should be: // CPlusPlus && (MicrosoftExt || Borland) let LangOpts = [MicrosoftExt, Borland]; let Documentation = [Undocumented]; } def VectorSize : TypeAttr { let Spellings = [GCC<"vector_size">]; let Args = [ExprArgument<"NumBytes">]; let Documentation = [Undocumented]; } def VecTypeHint : InheritableAttr { // Does not have a [[]] spelling because it is an OpenCL-related attribute. let Spellings = [GNU<"vec_type_hint">]; let Args = [TypeArgument<"TypeHint">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def Visibility : InheritableAttr { let Clone = 0; let Spellings = [GCC<"visibility">]; let Args = [EnumArgument<"Visibility", "VisibilityType", ["default", "hidden", "internal", "protected"], ["Default", "Hidden", "Hidden", "Protected"]>]; let MeaningfulToClassTemplateDefinition = 1; let Documentation = [Undocumented]; } def TypeVisibility : InheritableAttr { let Clone = 0; let Spellings = [Clang<"type_visibility">]; let Args = [EnumArgument<"Visibility", "VisibilityType", ["default", "hidden", "internal", "protected"], ["Default", "Hidden", "Hidden", "Protected"]>]; // let Subjects = [Tag, ObjCInterface, Namespace]; let Documentation = [Undocumented]; } def VecReturn : InheritableAttr { // This attribute does not have a C [[]] spelling because it only appertains // to C++ struct/class/union. // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"vecreturn", 0>]; let Subjects = SubjectList<[CXXRecord], ErrorDiag>; let Documentation = [Undocumented]; } def WarnUnused : InheritableAttr { let Spellings = [GCC<"warn_unused">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; } def WarnUnusedResult : InheritableAttr { let Spellings = [CXX11<"", "nodiscard", 201603>, C2x<"", "nodiscard">, CXX11<"clang", "warn_unused_result">, GCC<"warn_unused_result">]; let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike]>; let Documentation = [WarnUnusedResultsDocs]; } def Weak : InheritableAttr { let Spellings = [GCC<"weak">]; let Subjects = SubjectList<[Var, Function, CXXRecord]>; let Documentation = [Undocumented]; } def WeakImport : InheritableAttr { let Spellings = [Clang<"weak_import">]; let Documentation = [Undocumented]; } def WeakRef : InheritableAttr { let Spellings = [GCC<"weakref">]; // A WeakRef that has an argument is treated as being an AliasAttr let Args = [StringArgument<"Aliasee", 1>]; let Subjects = SubjectList<[Var, Function], ErrorDiag>; let Documentation = [Undocumented]; } def LTOVisibilityPublic : InheritableAttr { let Spellings = [Clang<"lto_visibility_public">]; let Subjects = SubjectList<[Record]>; let Documentation = [LTOVisibilityDocs]; } def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr { // NOTE: If you add any additional spellings, ARMInterrupt's, // MSP430Interrupt's and MipsInterrupt's spellings must match. let Spellings = [GCC<"interrupt">]; let Subjects = SubjectList<[HasFunctionProto]>; let ParseKind = "Interrupt"; let HasCustomParsing = 1; let Documentation = [Undocumented]; } def AnyX86NoCallerSavedRegisters : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"no_caller_saved_registers">]; let Documentation = [AnyX86NoCallerSavedRegistersDocs]; } def AnyX86NoCfCheck : InheritableAttr, TargetSpecificAttr{ let Spellings = [GCC<"nocf_check">]; let Subjects = SubjectList<[FunctionLike]>; let Documentation = [AnyX86NoCfCheckDocs]; } def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"force_align_arg_pointer">]; // Technically, this appertains to a FunctionDecl, but the target-specific // code silently allows anything function-like (such as typedefs or function // pointers), but does not apply the attribute to them. let Documentation = [X86ForceAlignArgPointerDocs]; } def NoSanitize : InheritableAttr { let Spellings = [Clang<"no_sanitize">]; let Args = [VariadicStringArgument<"Sanitizers">]; let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag>; let Documentation = [NoSanitizeDocs]; let AdditionalMembers = [{ SanitizerMask getMask() const { SanitizerMask Mask = 0; for (auto SanitizerName : sanitizers()) { SanitizerMask ParsedMask = parseSanitizerValue(SanitizerName, /*AllowGroups=*/true); Mask |= expandSanitizerGroups(ParsedMask); } return Mask; } }]; } // Attributes to disable a specific sanitizer. No new sanitizers should be added // to this list; the no_sanitize attribute should be extended instead. def NoSanitizeSpecific : InheritableAttr { let Spellings = [GCC<"no_address_safety_analysis">, GCC<"no_sanitize_address">, GCC<"no_sanitize_thread">, Clang<"no_sanitize_memory">]; let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>; let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs, NoSanitizeMemoryDocs]; let ASTNode = 0; } // C/C++ Thread safety attributes (e.g. for deadlock, data race checking) // Not all of these attributes will be given a [[]] spelling. The attributes // which require access to function parameter names cannot use the [[]] spelling // because they are not written in the type position. Some attributes are given // an updated captability-based name and the older name will only be supported // under the GNU-style spelling. def GuardedVar : InheritableAttr { let Spellings = [Clang<"guarded_var", 0>]; let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } def PtGuardedVar : InheritableAttr { let Spellings = [Clang<"pt_guarded_var", 0>]; let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } def Lockable : InheritableAttr { let Spellings = [GNU<"lockable">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; let ASTNode = 0; // Replaced by Capability } def ScopedLockable : InheritableAttr { let Spellings = [Clang<"scoped_lockable", 0>]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; } def Capability : InheritableAttr { let Spellings = [Clang<"capability", 0>, Clang<"shared_capability", 0>]; let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>; let Args = [StringArgument<"Name">]; let Accessors = [Accessor<"isShared", [Clang<"shared_capability", 0>]>]; let Documentation = [Undocumented]; let AdditionalMembers = [{ bool isMutex() const { return getName().equals_lower("mutex"); } bool isRole() const { return getName().equals_lower("role"); } }]; } def AssertCapability : InheritableAttr { let Spellings = [Clang<"assert_capability", 0>, Clang<"assert_shared_capability", 0>]; let Subjects = SubjectList<[Function]>; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Args = [VariadicExprArgument<"Args">]; let Accessors = [Accessor<"isShared", [Clang<"assert_shared_capability", 0>]>]; let Documentation = [AssertCapabilityDocs]; } def AcquireCapability : InheritableAttr { let Spellings = [Clang<"acquire_capability", 0>, Clang<"acquire_shared_capability", 0>, GNU<"exclusive_lock_function">, GNU<"shared_lock_function">]; let Subjects = SubjectList<[Function]>; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Args = [VariadicExprArgument<"Args">]; let Accessors = [Accessor<"isShared", [Clang<"acquire_shared_capability", 0>, GNU<"shared_lock_function">]>]; let Documentation = [AcquireCapabilityDocs]; } def TryAcquireCapability : InheritableAttr { let Spellings = [Clang<"try_acquire_capability", 0>, Clang<"try_acquire_shared_capability", 0>]; let Subjects = SubjectList<[Function], ErrorDiag>; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; let Accessors = [Accessor<"isShared", [Clang<"try_acquire_shared_capability", 0>]>]; let Documentation = [TryAcquireCapabilityDocs]; } def ReleaseCapability : InheritableAttr { let Spellings = [Clang<"release_capability", 0>, Clang<"release_shared_capability", 0>, Clang<"release_generic_capability", 0>, Clang<"unlock_function", 0>]; let Subjects = SubjectList<[Function]>; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Args = [VariadicExprArgument<"Args">]; let Accessors = [Accessor<"isShared", [Clang<"release_shared_capability", 0>]>, Accessor<"isGeneric", [Clang<"release_generic_capability", 0>, Clang<"unlock_function", 0>]>]; let Documentation = [ReleaseCapabilityDocs]; } def RequiresCapability : InheritableAttr { let Spellings = [Clang<"requires_capability", 0>, Clang<"exclusive_locks_required", 0>, Clang<"requires_shared_capability", 0>, Clang<"shared_locks_required", 0>]; let Args = [VariadicExprArgument<"Args">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Function]>; let Accessors = [Accessor<"isShared", [Clang<"requires_shared_capability", 0>, Clang<"shared_locks_required", 0>]>]; let Documentation = [Undocumented]; } def NoThreadSafetyAnalysis : InheritableAttr { let Spellings = [Clang<"no_thread_safety_analysis">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def GuardedBy : InheritableAttr { let Spellings = [GNU<"guarded_by">]; let Args = [ExprArgument<"Arg">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } def PtGuardedBy : InheritableAttr { let Spellings = [GNU<"pt_guarded_by">]; let Args = [ExprArgument<"Arg">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } def AcquiredAfter : InheritableAttr { let Spellings = [GNU<"acquired_after">]; let Args = [VariadicExprArgument<"Args">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } def AcquiredBefore : InheritableAttr { let Spellings = [GNU<"acquired_before">]; let Args = [VariadicExprArgument<"Args">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } def AssertExclusiveLock : InheritableAttr { let Spellings = [GNU<"assert_exclusive_lock">]; let Args = [VariadicExprArgument<"Args">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def AssertSharedLock : InheritableAttr { let Spellings = [GNU<"assert_shared_lock">]; let Args = [VariadicExprArgument<"Args">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } // The first argument is an integer or boolean value specifying the return value // of a successful lock acquisition. def ExclusiveTrylockFunction : InheritableAttr { let Spellings = [GNU<"exclusive_trylock_function">]; let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } // The first argument is an integer or boolean value specifying the return value // of a successful lock acquisition. def SharedTrylockFunction : InheritableAttr { let Spellings = [GNU<"shared_trylock_function">]; let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def LockReturned : InheritableAttr { let Spellings = [GNU<"lock_returned">]; let Args = [ExprArgument<"Arg">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def LocksExcluded : InheritableAttr { let Spellings = [GNU<"locks_excluded">]; let Args = [VariadicExprArgument<"Args">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } // C/C++ consumed attributes. def Consumable : InheritableAttr { // This attribute does not have a C [[]] spelling because it only appertains // to C++ struct/class/union. // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"consumable", 0>]; let Subjects = SubjectList<[CXXRecord]>; let Args = [EnumArgument<"DefaultState", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [ConsumableDocs]; } def ConsumableAutoCast : InheritableAttr { // This attribute does not have a C [[]] spelling because it only appertains // to C++ struct/class/union. // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"consumable_auto_cast_state", 0>]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [Undocumented]; } def ConsumableSetOnRead : InheritableAttr { // This attribute does not have a C [[]] spelling because it only appertains // to C++ struct/class/union. // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"consumable_set_state_on_read", 0>]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [Undocumented]; } def CallableWhen : InheritableAttr { // This attribute does not have a C [[]] spelling because it only appertains // to C++ function (but doesn't require it to be a member function). // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"callable_when", 0>]; let Subjects = SubjectList<[CXXMethod]>; let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [CallableWhenDocs]; } def ParamTypestate : InheritableAttr { // This attribute does not have a C [[]] spelling because it only appertains // to a parameter whose type is a consumable C++ class. // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"param_typestate", 0>]; let Subjects = SubjectList<[ParmVar]>; let Args = [EnumArgument<"ParamState", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [ParamTypestateDocs]; } def ReturnTypestate : InheritableAttr { // This attribute does not have a C [[]] spelling because it only appertains // to a parameter or function return type that is a consumable C++ class. // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"return_typestate", 0>]; let Subjects = SubjectList<[Function, ParmVar]>; let Args = [EnumArgument<"State", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [ReturnTypestateDocs]; } def SetTypestate : InheritableAttr { // This attribute does not have a C [[]] spelling because it only appertains // to C++ function (but doesn't require it to be a member function). // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"set_typestate", 0>]; let Subjects = SubjectList<[CXXMethod]>; let Args = [EnumArgument<"NewState", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [SetTypestateDocs]; } def TestTypestate : InheritableAttr { // This attribute does not have a C [[]] spelling because it only appertains // to C++ function (but doesn't require it to be a member function). // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"test_typestate", 0>]; let Subjects = SubjectList<[CXXMethod]>; let Args = [EnumArgument<"TestState", "ConsumedState", ["consumed", "unconsumed"], ["Consumed", "Unconsumed"]>]; let Documentation = [TestTypestateDocs]; } // Type safety attributes for `void *' pointers and type tags. def ArgumentWithTypeTag : InheritableAttr { let Spellings = [Clang<"argument_with_type_tag">, Clang<"pointer_with_type_tag">]; let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>; let Args = [IdentifierArgument<"ArgumentKind">, ParamIdxArgument<"ArgumentIdx">, ParamIdxArgument<"TypeTagIdx">, BoolArgument<"IsPointer", /*opt*/0, /*fake*/1>]; let Documentation = [ArgumentWithTypeTagDocs, PointerWithTypeTagDocs]; } def TypeTagForDatatype : InheritableAttr { let Spellings = [Clang<"type_tag_for_datatype">]; let Args = [IdentifierArgument<"ArgumentKind">, TypeArgument<"MatchingCType">, BoolArgument<"LayoutCompatible">, BoolArgument<"MustBeNull">]; // let Subjects = SubjectList<[Var], ErrorDiag>; let HasCustomParsing = 1; let Documentation = [TypeTagForDatatypeDocs]; } // Microsoft-related attributes def MSNoVTable : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [MSNoVTableDocs]; } def : IgnoredAttr { let Spellings = [Declspec<"property">]; } def MSStruct : InheritableAttr { let Spellings = [GCC<"ms_struct">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; } def DLLExport : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"dllexport">, GCC<"dllexport">]; let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; let Documentation = [DLLExportDocs]; } def DLLImport : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"dllimport">, GCC<"dllimport">]; let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; let Documentation = [DLLImportDocs]; let AdditionalMembers = [{ private: bool PropagatedToBaseTemplate = false; public: void setPropagatedToBaseTemplate() { PropagatedToBaseTemplate = true; } bool wasPropagatedToBaseTemplate() { return PropagatedToBaseTemplate; } }]; } def SelectAny : InheritableAttr { let Spellings = [Declspec<"selectany">, GCC<"selectany">]; let Documentation = [SelectAnyDocs]; } def Thread : Attr { let Spellings = [Declspec<"thread">]; let LangOpts = [MicrosoftExt]; let Documentation = [ThreadDocs]; let Subjects = SubjectList<[Var]>; } def Win64 : IgnoredAttr { let Spellings = [Keyword<"__w64">]; let LangOpts = [MicrosoftExt]; } def Ptr32 : TypeAttr { let Spellings = [Keyword<"__ptr32">]; let Documentation = [Undocumented]; } def Ptr64 : TypeAttr { let Spellings = [Keyword<"__ptr64">]; let Documentation = [Undocumented]; } def SPtr : TypeAttr { let Spellings = [Keyword<"__sptr">]; let Documentation = [Undocumented]; } def UPtr : TypeAttr { let Spellings = [Keyword<"__uptr">]; let Documentation = [Undocumented]; } def MSInheritance : InheritableAttr { let LangOpts = [MicrosoftExt]; let Args = [DefaultBoolArgument<"BestCase", /*default*/1, /*fake*/1>]; let Spellings = [Keyword<"__single_inheritance">, Keyword<"__multiple_inheritance">, Keyword<"__virtual_inheritance">, Keyword<"__unspecified_inheritance">]; let AdditionalMembers = [{ static bool hasVBPtrOffsetField(Spelling Inheritance) { return Inheritance == Keyword_unspecified_inheritance; } // Only member pointers to functions need a this adjustment, since it can be // combined with the field offset for data pointers. static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) { return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance; } static bool hasVBTableOffsetField(Spelling Inheritance) { return Inheritance >= Keyword_virtual_inheritance; } static bool hasOnlyOneField(bool IsMemberFunction, Spelling Inheritance) { if (IsMemberFunction) return Inheritance <= Keyword_single_inheritance; return Inheritance <= Keyword_multiple_inheritance; } }]; let Documentation = [MSInheritanceDocs]; } def MSVtorDisp : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let Args = [UnsignedArgument<"vdm">]; let SemaHandler = 0; let AdditionalMembers = [{ enum Mode { Never, ForVBaseOverride, ForVFTable }; Mode getVtorDispMode() const { return Mode(vdm); } }]; let Documentation = [Undocumented]; } def InitSeg : Attr { let Spellings = [Pragma<"", "init_seg">]; let Args = [StringArgument<"Section">]; let SemaHandler = 0; let Documentation = [InitSegDocs]; let AdditionalMembers = [{ void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { OS << " (" << getSection() << ')'; } }]; } def LoopHint : Attr { /// #pragma clang loop