//==--- 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. class SubsetSubject : AttrSubject { AttrSubject Base = base; code CheckCode = check; } // This is the type of a variable which C++11 allows alignas(...) to appertain // to. def NormalVar : SubsetSubjectgetStorageClass() != VarDecl::Register && S->getKind() != Decl::ImplicitParam && S->getKind() != Decl::ParmVar && S->getKind() != Decl::NonTypeTemplateParm}]>; def NonBitField : SubsetSubjectisBitField()}]>; def ObjCInstanceMethod : SubsetSubjectisInstanceMethod()}]>; def ObjCInterfaceDeclInitMethod : SubsetSubjectgetMethodFamily() == OMF_init && (isa(S->getDeclContext()) || (isa(S->getDeclContext()) && cast(S->getDeclContext())->IsClassExtension()))}]>; def Struct : SubsetSubjectisUnion()}]>; def TLSVar : SubsetSubjectgetTLSKind() != 0}]>; def SharedVar : SubsetSubjecthasGlobalStorage() && !S->getTLSKind()}]>; def GlobalVar : SubsetSubjecthasGlobalStorage()}]>; // 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) != NULL}]>; // 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) != NULL && isa(S->getFunctionType())) || isa(S) || isa(S)}]>; // A single argument to an attribute class Argument { string Name = name; bit Optional = optional; } class BoolArgument : Argument; class IdentifierArgument : Argument; class IntArgument : Argument; class StringArgument : Argument; class ExprArgument : Argument; class FunctionArgument : Argument; class TypeArgument : Argument; class UnsignedArgument : Argument; class VariadicUnsignedArgument : Argument; class VariadicExprArgument : 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> : 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 CXX11 : 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; } 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; } def MicrosoftExt : LangOpt<"MicrosoftExt">; def Borland : LangOpt<"Borland">; def CUDA : LangOpt<"CUDA">; // Defines targets for target-specific attributes. The list of strings should // specify architectures for which the target applies, based off the ArchType // enumeration in Triple.h. class TargetArch arches> { list Arches = arches; list OSes; } def TargetARM : TargetArch<["arm", "thumb"]>; def TargetMSP430 : TargetArch<["msp430"]>; def TargetX86 : TargetArch<["x86"]>; def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> { let OSes = ["Win32"]; } def TargetMips : TargetArch<["mips", "mipsel"]>; 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 can be duplicated on a subject when merging // attributes. By default, attributes are not merged. bit DuplicatesAllowedWhileMerging = 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. 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; } /// An inheritable attribute is inherited by later redeclarations. class InheritableAttr : Attr; /// 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 { TargetArch 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 AttributeList::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 betweeen 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 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 AddressSpace : TypeAttr { let Spellings = [GNU<"address_space">]; let Args = [IntArgument<"AddressSpace">]; let Documentation = [Undocumented]; } def Alias : Attr { let Spellings = [GCC<"alias">]; let Args = [StringArgument<"Aliasee">]; let Documentation = [Undocumented]; } def Aligned : InheritableAttr { let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">, Keyword<"_Alignas">]; // let Subjects = SubjectList<[NonBitField, NormalVar, Tag]>; 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 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 TLSModel : InheritableAttr { let Spellings = [GCC<"tls_model">]; let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">; let Args = [StringArgument<"Model">]; let Documentation = [TLSModelDocs]; } def AnalyzerNoReturn : InheritableAttr { let Spellings = [GNU<"analyzer_noreturn">]; let Documentation = [Undocumented]; } def Annotate : InheritableParamAttr { let Spellings = [GNU<"annotate">]; let Args = [StringArgument<"Annotation">]; let Documentation = [Undocumented]; } def ARMInterrupt : InheritableAttr, TargetSpecificAttr { // NOTE: If you add any additional spellings, MSP430Interrupt's spellings // must match. let Spellings = [GNU<"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 AsmLabel : InheritableAttr { let Spellings = [Keyword<"asm">, Keyword<"__asm__">]; let Args = [StringArgument<"Label">]; let SemaHandler = 0; let Documentation = [Undocumented]; } def Availability : InheritableAttr { let Spellings = [GNU<"availability">]; let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">, VersionArgument<"deprecated">, VersionArgument<"obsoleted">, BoolArgument<"unavailable">, StringArgument<"message">]; let AdditionalMembers = [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch(Platform) .Case("ios", "iOS") .Case("macosx", "OS X") .Default(llvm::StringRef()); } }]; let HasCustomParsing = 1; let DuplicatesAllowedWhileMerging = 1; // let Subjects = SubjectList<[Named]>; let Documentation = [AvailabilityDocs]; } def Blocks : InheritableAttr { let Spellings = [GNU<"blocks">]; let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>]; let Documentation = [Undocumented]; } def Bounded : IgnoredAttr { let Spellings = [GNU<"bounded">]; } def CarriesDependency : InheritableParamAttr { let Spellings = [GNU<"carries_dependency">, CXX11<"","carries_dependency">]; let Subjects = SubjectList<[ParmVar, ObjCMethod, Function], ErrorDiag>; let Documentation = [CarriesDependencyDocs]; } def CDecl : InheritableAttr { 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 = [GNU<"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 = [GNU<"cf_unknown_transfer">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def CFReturnsRetained : InheritableAttr { let Spellings = [GNU<"cf_returns_retained">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def CFReturnsNotRetained : InheritableAttr { let Spellings = [GNU<"cf_returns_not_retained">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def CFConsumed : InheritableParamAttr { let Spellings = [GNU<"cf_consumed">]; let Subjects = SubjectList<[ParmVar]>; let Documentation = [Undocumented]; } def Cleanup : InheritableAttr { let Spellings = [GCC<"cleanup">]; let Args = [FunctionArgument<"FunctionDecl">]; let Subjects = SubjectList<[Var]>; 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 CUDAConstant : InheritableAttr { let Spellings = [GNU<"constant">]; let Subjects = SubjectList<[Var]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def CUDADevice : InheritableAttr { let Spellings = [GNU<"device">]; let Subjects = SubjectList<[Function, Var]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def CUDAGlobal : InheritableAttr { let Spellings = [GNU<"global">]; let Subjects = SubjectList<[Function]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def CUDAHost : InheritableAttr { let Spellings = [GNU<"host">]; let Subjects = SubjectList<[Function]>; let LangOpts = [CUDA]; let Documentation = [Undocumented]; } def CUDALaunchBounds : InheritableAttr { let Spellings = [GNU<"launch_bounds">]; let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>]; let LangOpts = [CUDA]; let Subjects = SubjectList<[ObjCMethod, FunctionLike], WarnDiag, "ExpectedFunctionOrMethod">; // 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">]; 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">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [CXX11NoReturnDocs]; } def OpenCLKernel : InheritableAttr { let Spellings = [Keyword<"__kernel">, Keyword<"kernel">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } // This attribute is both a type attribute, and a declaration attribute (for // parameter variables). def OpenCLImageAccess : 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], 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 = [Undocumented]; } def OpenCLPrivateAddressSpace : TypeAttr { let Spellings = [Keyword<"__private">, Keyword<"private">]; let Documentation = [Undocumented]; } def OpenCLGlobalAddressSpace : TypeAttr { let Spellings = [Keyword<"__global">, Keyword<"global">]; let Documentation = [Undocumented]; } def OpenCLLocalAddressSpace : TypeAttr { let Spellings = [Keyword<"__local">, Keyword<"local">]; let Documentation = [Undocumented]; } def OpenCLConstantAddressSpace : TypeAttr { let Spellings = [Keyword<"__constant">, Keyword<"constant">]; let Documentation = [Undocumented]; } def Deprecated : InheritableAttr { let Spellings = [GCC<"deprecated">, Declspec<"deprecated">, CXX11<"","deprecated">]; let Args = [StringArgument<"Message", 1>]; let Documentation = [Undocumented]; } def Destructor : InheritableAttr { let Spellings = [GCC<"destructor">]; let Args = [DefaultIntArgument<"Priority", 65535>]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } def EnableIf : InheritableAttr { let Spellings = [GNU<"enable_if">]; let Subjects = SubjectList<[Function]>; let Args = [ExprArgument<"Cond">, StringArgument<"Message">]; let TemplateDependent = 1; let Documentation = [EnableIfDocs]; } def ExtVectorType : Attr { let Spellings = [GNU<"ext_vector_type">]; let Subjects = SubjectList<[TypedefName], ErrorDiag>; let Args = [ExprArgument<"NumElements">]; let ASTNode = 0; let Documentation = [Undocumented]; } def FallThrough : Attr { let Spellings = [CXX11<"clang", "fallthrough">]; // let Subjects = [NullStmt]; let Documentation = [FallthroughDocs]; } def FastCall : InheritableAttr { let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">, Keyword<"_fastcall">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } 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 = [GNU<"minsize">]; let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>; let Documentation = [Undocumented]; } 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], WarnDiag, "ExpectedFunction">; let Documentation = [FormatDocs]; } def FormatArg : InheritableAttr { let Spellings = [GCC<"format_arg">]; let Args = [IntArgument<"FormatIdx">]; let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag, "ExpectedFunction">; 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 = [GNU<"ibaction">]; let Subjects = SubjectList<[ObjCInstanceMethod], WarnDiag, "ExpectedObjCInstanceMethod">; // 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 = [GNU<"iboutlet">]; // let Subjects = [ObjCIvar, ObjCProperty]; let Documentation = [Undocumented]; } def IBOutletCollection : InheritableAttr { let Spellings = [GNU<"iboutletcollection">]; let Args = [TypeArgument<"Interface", 1>]; // let Subjects = [ObjCIvar, ObjCProperty]; let Documentation = [Undocumented]; } def Malloc : InheritableAttr { let Spellings = [GCC<"malloc">]; // let Subjects = [Function]; let Documentation = [Undocumented]; } 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 : InheritableAttr { let Spellings = [GCC<"ms_abi">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def MSP430Interrupt : InheritableAttr, TargetSpecificAttr { // NOTE: If you add any additional spellings, ARMInterrupt's spellings must // match. let Spellings = [GNU<"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 Mode : Attr { let Spellings = [GCC<"mode">]; 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 = [GNU<"neon_polyvector_type">]; let Args = [IntArgument<"NumElements">]; let Documentation = [Undocumented]; } def NeonVectorType : TypeAttr { let Spellings = [GNU<"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 NoCommon : InheritableAttr { let Spellings = [GCC<"nocommon">]; let Subjects = SubjectList<[Var]>; let Documentation = [Undocumented]; } def NoDebug : InheritableAttr { let Spellings = [GNU<"nodebug">]; let Documentation = [Undocumented]; } def NoDuplicate : InheritableAttr { let Spellings = [GNU<"noduplicate">, CXX11<"clang", "noduplicate">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoDuplicateDocs]; } 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 NoSplitStack : InheritableAttr { let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [NoSplitStackDocs]; } def NonNull : InheritableAttr { let Spellings = [GCC<"nonnull">]; let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag, "ExpectedFunctionMethodOrParameter">; let Args = [VariadicUnsignedArgument<"Args">]; let AdditionalMembers = [{bool isNonNull(unsigned idx) const { for (const auto &V : args()) if (V == idx) return true; return false; } }]; let Documentation = [Undocumented]; } def ReturnsNonNull : InheritableAttr { let Spellings = [GCC<"returns_nonnull">]; let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag, "ExpectedFunctionOrMethod">; let Documentation = [Undocumented]; } 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 NoThrow : InheritableAttr { let Spellings = [GCC<"nothrow">, Declspec<"nothrow">]; let Documentation = [Undocumented]; } def ObjCBridge : InheritableAttr { let Spellings = [GNU<"objc_bridge">]; let Subjects = SubjectList<[Record], ErrorDiag>; let Args = [IdentifierArgument<"BridgedType">]; let Documentation = [Undocumented]; } def ObjCBridgeMutable : InheritableAttr { let Spellings = [GNU<"objc_bridge_mutable">]; let Subjects = SubjectList<[Record], ErrorDiag>; let Args = [IdentifierArgument<"BridgedType">]; let Documentation = [Undocumented]; } def ObjCBridgeRelated : InheritableAttr { let Spellings = [GNU<"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 = [GNU<"ns_returns_retained">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def NSReturnsNotRetained : InheritableAttr { let Spellings = [GNU<"ns_returns_not_retained">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def NSReturnsAutoreleased : InheritableAttr { let Spellings = [GNU<"ns_returns_autoreleased">]; // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; let Documentation = [Undocumented]; } def NSConsumesSelf : InheritableAttr { let Spellings = [GNU<"ns_consumes_self">]; let Subjects = SubjectList<[ObjCMethod]>; let Documentation = [Undocumented]; } def NSConsumed : InheritableParamAttr { let Spellings = [GNU<"ns_consumed">]; let Subjects = SubjectList<[ParmVar]>; let Documentation = [Undocumented]; } def ObjCException : InheritableAttr { let Spellings = [GNU<"objc_exception">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCMethodFamily : InheritableAttr { let Spellings = [GNU<"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 = [GNU<"NSObject">]; let Documentation = [Undocumented]; } def ObjCPreciseLifetime : InheritableAttr { let Spellings = [GNU<"objc_precise_lifetime">]; let Subjects = SubjectList<[Var], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCReturnsInnerPointer : InheritableAttr { let Spellings = [GNU<"objc_returns_inner_pointer">]; let Subjects = SubjectList<[ObjCMethod, ObjCProperty], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCRequiresSuper : InheritableAttr { let Spellings = [GNU<"objc_requires_super">]; let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; let Documentation = [ObjCRequiresSuperDocs]; } def ObjCRootClass : InheritableAttr { let Spellings = [GNU<"objc_root_class">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCExplicitProtocolImpl : InheritableAttr { let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">]; let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCDesignatedInitializer : Attr { let Spellings = [GNU<"objc_designated_initializer">]; let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag, "ExpectedObjCInterfaceDeclInitMethod">; let Documentation = [Undocumented]; } def OptimizeNone : InheritableAttr { let Spellings = [GNU<"optnone">, CXX11<"clang", "optnone">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let Documentation = [OptnoneDocs]; } def Overloadable : Attr { let Spellings = [GNU<"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 = [GNU<"ownership_holds">, GNU<"ownership_returns">, GNU<"ownership_takes">]; let Accessors = [Accessor<"isHolds", [GNU<"ownership_holds">]>, Accessor<"isReturns", [GNU<"ownership_returns">]>, Accessor<"isTakes", [GNU<"ownership_takes">]>]; let AdditionalMembers = [{ enum OwnershipKind { Holds, Returns, Takes }; OwnershipKind getOwnKind() const { return isHolds() ? Holds : isTakes() ? Takes : Returns; } }]; let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">]; let Subjects = SubjectList<[HasFunctionProto], WarnDiag, "ExpectedFunction">; let Documentation = [Undocumented]; } def Packed : InheritableAttr { let Spellings = [GCC<"packed">]; // let Subjects = [Tag, Field]; let Documentation = [Undocumented]; } def PnaclCall : InheritableAttr { let Spellings = [GNU<"pnaclcall">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def IntelOclBicc : InheritableAttr { let Spellings = [GNU<"intel_ocl_bicc">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def Pcs : InheritableAttr { 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 = [Undocumented]; } def ReqdWorkGroupSize : InheritableAttr { let Spellings = [GNU<"reqd_work_group_size">]; let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">, UnsignedArgument<"ZDim">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; } def WorkGroupSizeHint : InheritableAttr { 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 = [GNU<"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, "ExpectedFunctionGlobalVarMethodOrProperty">; let Documentation = [SectionDocs]; } 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 : InheritableAttr { let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def SysVABI : InheritableAttr { let Spellings = [GCC<"sysv_abi">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def ThisCall : InheritableAttr { let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">, Keyword<"_thiscall">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def Pascal : InheritableAttr { let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">]; // let Subjects = [Function, ObjCMethod]; let Documentation = [Undocumented]; } def TransparentUnion : InheritableAttr { let Spellings = [GCC<"transparent_union">]; // let Subjects = SubjectList<[Record, TypedefName]>; let Documentation = [Undocumented]; } def Unavailable : InheritableAttr { let Spellings = [GNU<"unavailable">]; let Args = [StringArgument<"Message", 1>]; let Documentation = [Undocumented]; } def ArcWeakrefUnavailable : InheritableAttr { let Spellings = [GNU<"objc_arc_weak_reference_unavailable">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; } def ObjCGC : TypeAttr { let Spellings = [GNU<"objc_gc">]; let Args = [IdentifierArgument<"Kind">]; let Documentation = [Undocumented]; } def ObjCOwnership : InheritableAttr { let Spellings = [GNU<"objc_ownership">]; let Args = [IdentifierArgument<"Kind">]; let ASTNode = 0; let Documentation = [Undocumented]; } def ObjCRequiresPropertyDefs : InheritableAttr { let Spellings = [GNU<"objc_requires_property_definitions">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; } def Unused : InheritableAttr { let Spellings = [GCC<"unused">]; let Subjects = SubjectList<[Var, ObjCIvar, Type, Label, Field, ObjCMethod, FunctionLike], WarnDiag, "ExpectedVariableFunctionOrLabel">; let Documentation = [Undocumented]; } def Used : InheritableAttr { let Spellings = [GCC<"used">]; let Documentation = [Undocumented]; } def Uuid : InheritableAttr { let Spellings = [Declspec<"uuid">]; let Args = [StringArgument<"Guid">]; // let Subjects = SubjectList<[CXXRecord]>; 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 { 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 Documentation = [Undocumented]; } def TypeVisibility : InheritableAttr { let Clone = 0; let Spellings = [GNU<"type_visibility">, CXX11<"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 { let Spellings = [GNU<"vecreturn">]; let Subjects = SubjectList<[CXXRecord], ErrorDiag>; let Documentation = [Undocumented]; } def WarnUnused : InheritableAttr { let Spellings = [GNU<"warn_unused">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; } def WarnUnusedResult : InheritableAttr { let Spellings = [GCC<"warn_unused_result">, CXX11<"clang", "warn_unused_result">]; let Subjects = SubjectList<[ObjCMethod, CXXRecord, FunctionLike], WarnDiag, "ExpectedFunctionMethodOrClass">; let Documentation = [Undocumented]; } def Weak : InheritableAttr { let Spellings = [GCC<"weak">]; let Subjects = SubjectList<[Var, Function, CXXRecord]>; let Documentation = [Undocumented]; } def WeakImport : InheritableAttr { let Spellings = [GNU<"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 X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr { let Spellings = [GNU<"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 = [Undocumented]; } // Attribute to disable AddressSanitizer (or equivalent) checks. def NoSanitizeAddress : InheritableAttr { let Spellings = [GCC<"no_address_safety_analysis">, GCC<"no_sanitize_address">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [NoSanitizeAddressDocs]; } // Attribute to disable ThreadSanitizer checks. def NoSanitizeThread : InheritableAttr { let Spellings = [GNU<"no_sanitize_thread">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [NoSanitizeThreadDocs]; } // Attribute to disable MemorySanitizer checks. def NoSanitizeMemory : InheritableAttr { let Spellings = [GNU<"no_sanitize_memory">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [NoSanitizeMemoryDocs]; } // C/C++ Thread safety attributes (e.g. for deadlock, data race checking) def GuardedVar : InheritableAttr { let Spellings = [GNU<"guarded_var">]; let Subjects = SubjectList<[Field, SharedVar], WarnDiag, "ExpectedFieldOrGlobalVar">; let Documentation = [Undocumented]; } def PtGuardedVar : InheritableAttr { let Spellings = [GNU<"pt_guarded_var">]; let Subjects = SubjectList<[Field, SharedVar], WarnDiag, "ExpectedFieldOrGlobalVar">; 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 = [GNU<"scoped_lockable">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; } def Capability : InheritableAttr { let Spellings = [GNU<"capability">, CXX11<"clang", "capability">, GNU<"shared_capability">, CXX11<"clang", "shared_capability">]; let Subjects = SubjectList<[Struct, TypedefName], ErrorDiag, "ExpectedStructOrTypedef">; let Args = [StringArgument<"Name">]; let Accessors = [Accessor<"isShared", [GNU<"shared_capability">, CXX11<"clang","shared_capability">]>]; 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 = [GNU<"assert_capability">, CXX11<"clang", "assert_capability">, GNU<"assert_shared_capability">, CXX11<"clang", "assert_shared_capability">]; let Subjects = SubjectList<[Function]>; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let DuplicatesAllowedWhileMerging = 1; let Args = [ExprArgument<"Expr">]; let Accessors = [Accessor<"isShared", [GNU<"assert_shared_capability">, CXX11<"clang", "assert_shared_capability">]>]; let Documentation = [AssertCapabilityDocs]; } def AcquireCapability : InheritableAttr { let Spellings = [GNU<"acquire_capability">, CXX11<"clang", "acquire_capability">, GNU<"acquire_shared_capability">, CXX11<"clang", "acquire_shared_capability">, GNU<"exclusive_lock_function">, GNU<"shared_lock_function">]; let Subjects = SubjectList<[Function]>; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let DuplicatesAllowedWhileMerging = 1; let Args = [VariadicExprArgument<"Args">]; let Accessors = [Accessor<"isShared", [GNU<"acquire_shared_capability">, CXX11<"clang", "acquire_shared_capability">, GNU<"shared_lock_function">]>]; let Documentation = [AcquireCapabilityDocs]; } def TryAcquireCapability : InheritableAttr { let Spellings = [GNU<"try_acquire_capability">, CXX11<"clang", "try_acquire_capability">, GNU<"try_acquire_shared_capability">, CXX11<"clang", "try_acquire_shared_capability">]; let Subjects = SubjectList<[Function], ErrorDiag>; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let DuplicatesAllowedWhileMerging = 1; let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; let Accessors = [Accessor<"isShared", [GNU<"try_acquire_shared_capability">, CXX11<"clang", "try_acquire_shared_capability">]>]; let Documentation = [TryAcquireCapabilityDocs]; } def ReleaseCapability : InheritableAttr { let Spellings = [GNU<"release_capability">, CXX11<"clang", "release_capability">, GNU<"release_shared_capability">, CXX11<"clang", "release_shared_capability">, GNU<"release_generic_capability">, CXX11<"clang", "release_generic_capability">, GNU<"unlock_function">]; let Subjects = SubjectList<[Function]>; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let DuplicatesAllowedWhileMerging = 1; let Args = [VariadicExprArgument<"Args">]; let Accessors = [Accessor<"isShared", [GNU<"release_shared_capability">, CXX11<"clang", "release_shared_capability">]>, Accessor<"isGeneric", [GNU<"release_generic_capability">, CXX11<"clang", "release_generic_capability">, GNU<"unlock_function">]>]; let Documentation = [ReleaseCapabilityDocs]; } def RequiresCapability : InheritableAttr { let Spellings = [GNU<"requires_capability">, CXX11<"clang", "requires_capability">, GNU<"exclusive_locks_required">, GNU<"requires_shared_capability">, CXX11<"clang", "requires_shared_capability">, GNU<"shared_locks_required">]; let Args = [VariadicExprArgument<"Args">]; let LateParsed = 1; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let DuplicatesAllowedWhileMerging = 1; let Subjects = SubjectList<[Function]>; let Accessors = [Accessor<"isShared", [GNU<"requires_shared_capability">, GNU<"shared_locks_required">, CXX11<"clang","requires_shared_capability">]>]; let Documentation = [Undocumented]; } def NoThreadSafetyAnalysis : InheritableAttr { let Spellings = [GNU<"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 DuplicatesAllowedWhileMerging = 1; let Subjects = SubjectList<[Field, SharedVar], WarnDiag, "ExpectedFieldOrGlobalVar">; 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 DuplicatesAllowedWhileMerging = 1; let Subjects = SubjectList<[Field, SharedVar], WarnDiag, "ExpectedFieldOrGlobalVar">; 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 DuplicatesAllowedWhileMerging = 1; let Subjects = SubjectList<[Field, SharedVar], WarnDiag, "ExpectedFieldOrGlobalVar">; 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 DuplicatesAllowedWhileMerging = 1; let Subjects = SubjectList<[Field, SharedVar], WarnDiag, "ExpectedFieldOrGlobalVar">; 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 DuplicatesAllowedWhileMerging = 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 DuplicatesAllowedWhileMerging = 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 DuplicatesAllowedWhileMerging = 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 DuplicatesAllowedWhileMerging = 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 DuplicatesAllowedWhileMerging = 1; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } // C/C++ consumed attributes. def Consumable : InheritableAttr { let Spellings = [GNU<"consumable">]; let Subjects = SubjectList<[CXXRecord]>; let Args = [EnumArgument<"DefaultState", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [ConsumableDocs]; } def ConsumableAutoCast : InheritableAttr { let Spellings = [GNU<"consumable_auto_cast_state">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [Undocumented]; } def ConsumableSetOnRead : InheritableAttr { let Spellings = [GNU<"consumable_set_state_on_read">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [Undocumented]; } def CallableWhen : InheritableAttr { let Spellings = [GNU<"callable_when">]; let Subjects = SubjectList<[CXXMethod]>; let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [CallableWhenDocs]; } def ParamTypestate : InheritableAttr { let Spellings = [GNU<"param_typestate">]; let Subjects = SubjectList<[ParmVar]>; let Args = [EnumArgument<"ParamState", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [ParamTypestateDocs]; } def ReturnTypestate : InheritableAttr { let Spellings = [GNU<"return_typestate">]; let Subjects = SubjectList<[Function, ParmVar]>; let Args = [EnumArgument<"State", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [ReturnTypestateDocs]; } def SetTypestate : InheritableAttr { let Spellings = [GNU<"set_typestate">]; let Subjects = SubjectList<[CXXMethod]>; let Args = [EnumArgument<"NewState", "ConsumedState", ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [SetTypestateDocs]; } def TestTypestate : InheritableAttr { let Spellings = [GNU<"test_typestate">]; 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 = [GNU<"argument_with_type_tag">, GNU<"pointer_with_type_tag">]; let Args = [IdentifierArgument<"ArgumentKind">, UnsignedArgument<"ArgumentIdx">, UnsignedArgument<"TypeTagIdx">, BoolArgument<"IsPointer">]; let HasCustomParsing = 1; let Documentation = [ArgumentWithTypeTagDocs, PointerWithTypeTagDocs]; } def TypeTagForDatatype : InheritableAttr { let Spellings = [GNU<"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 MsProperty : 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]>; let Documentation = [Undocumented]; } def DLLImport : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"dllimport">, GCC<"dllimport">]; let Subjects = SubjectList<[Function, Var, CXXRecord]>; let Documentation = [Undocumented]; } def SelectAny : InheritableAttr { let Spellings = [Declspec<"selectany">]; let LangOpts = [MicrosoftExt]; let Documentation = [Undocumented]; } 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", 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 Unaligned : IgnoredAttr { let Spellings = [Keyword<"__unaligned">]; } def LoopHint : Attr { /// vectorize: vectorizes loop operations if 'value != 0'. /// vectorize_width: vectorize loop operations with width 'value'. /// interleave: interleave multiple loop iterations if 'value != 0'. /// interleave_count: interleaves 'value' loop interations. /// unroll: unroll loop if 'value != 0'. /// unroll_count: unrolls loop 'value' times. let Spellings = [Pragma<"clang", "loop">]; /// State of the loop optimization specified by the spelling. let Args = [EnumArgument<"Option", "OptionType", ["vectorize", "vectorize_width", "interleave", "interleave_count", "unroll", "unroll_count"], ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount", "Unroll", "UnrollCount"]>, DefaultIntArgument<"Value", 1>]; let AdditionalMembers = [{ static StringRef getOptionName(int Option) { switch(Option) { case Vectorize: return "vectorize"; case VectorizeWidth: return "vectorize_width"; case Interleave: return "interleave"; case InterleaveCount: return "interleave_count"; case Unroll: return "unroll"; case UnrollCount: return "unroll_count"; } llvm_unreachable("Unhandled LoopHint option."); } static StringRef getValueName(int Value) { if (Value) return "enable"; return "disable"; } void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { OS << getOptionName(option) << "("; if (option == VectorizeWidth || option == InterleaveCount || option == UnrollCount) OS << value; else OS << getValueName(value); OS << ")\n"; } }]; let Documentation = [LoopHintDocs]; }