2720 lines
96 KiB
TableGen
2720 lines
96 KiB
TableGen
//==--- 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> {
|
|
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<string replacement = ""> {
|
|
// 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 base, code check> : AttrSubject {
|
|
AttrSubject Base = base;
|
|
code CheckCode = check;
|
|
}
|
|
|
|
// This is the type of a variable which C++11 allows alignas(...) to appertain
|
|
// to.
|
|
def NormalVar : SubsetSubject<Var,
|
|
[{S->getStorageClass() != VarDecl::Register &&
|
|
S->getKind() != Decl::ImplicitParam &&
|
|
S->getKind() != Decl::ParmVar &&
|
|
S->getKind() != Decl::NonTypeTemplateParm}]>;
|
|
def NonParmVar : SubsetSubject<Var,
|
|
[{S->getKind() != Decl::ParmVar}]>;
|
|
def NonBitField : SubsetSubject<Field,
|
|
[{!S->isBitField()}]>;
|
|
|
|
def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
|
|
[{S->isInstanceMethod()}]>;
|
|
|
|
def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
|
|
[{S->getMethodFamily() == OMF_init &&
|
|
(isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
|
|
(isa<ObjCCategoryDecl>(S->getDeclContext()) &&
|
|
cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}]>;
|
|
|
|
def Struct : SubsetSubject<Record,
|
|
[{!S->isUnion()}]>;
|
|
|
|
def TLSVar : SubsetSubject<Var,
|
|
[{S->getTLSKind() != 0}]>;
|
|
|
|
def SharedVar : SubsetSubject<Var,
|
|
[{S->hasGlobalStorage() && !S->getTLSKind()}]>;
|
|
|
|
def GlobalVar : SubsetSubject<Var,
|
|
[{S->hasGlobalStorage()}]>;
|
|
|
|
// 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 : SubsetSubject<DeclBase,
|
|
[{S->getFunctionType(false) != nullptr}]>;
|
|
|
|
def OpenCLKernelFunction : SubsetSubject<Function, [{
|
|
S->hasAttr<OpenCLKernelAttr>()
|
|
}]>;
|
|
|
|
// 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 : SubsetSubject<DeclBase,
|
|
[{(S->getFunctionType(true) != nullptr &&
|
|
isa<FunctionProtoType>(S->getFunctionType())) ||
|
|
isa<ObjCMethodDecl>(S) ||
|
|
isa<BlockDecl>(S)}]>;
|
|
|
|
// A single argument to an attribute
|
|
class Argument<string name, bit optional, bit fake = 0> {
|
|
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<string name, bit opt = 0, bit fake = 0> : Argument<name, opt,
|
|
fake>;
|
|
class IdentifierArgument<string name, bit opt = 0> : Argument<name, opt>;
|
|
class IntArgument<string name, bit opt = 0> : Argument<name, opt>;
|
|
class StringArgument<string name, bit opt = 0> : Argument<name, opt>;
|
|
class ExprArgument<string name, bit opt = 0> : Argument<name, opt>;
|
|
class FunctionArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
|
|
opt,
|
|
fake>;
|
|
class NamedArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
|
|
opt,
|
|
fake>;
|
|
class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
|
|
class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
|
|
class VariadicUnsignedArgument<string name> : Argument<name, 1>;
|
|
class VariadicExprArgument<string name> : Argument<name, 1>;
|
|
class VariadicStringArgument<string name> : Argument<name, 1>;
|
|
|
|
// A version of the form major.minor[.subminor].
|
|
class VersionArgument<string name, bit opt = 0> : Argument<name, opt>;
|
|
|
|
// 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<string name, bit opt = 0> : Argument<name, opt>;
|
|
|
|
// A bool argument with a default value
|
|
class DefaultBoolArgument<string name, bit default> : BoolArgument<name, 1> {
|
|
bit Default = default;
|
|
}
|
|
|
|
// An integer argument with a default value
|
|
class DefaultIntArgument<string name, int default> : IntArgument<name, 1> {
|
|
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<string name, string type, list<string> values,
|
|
list<string> enums, bit opt = 0, bit fake = 0>
|
|
: Argument<name, opt, fake> {
|
|
string Type = type;
|
|
list<string> Values = values;
|
|
list<string> Enums = enums;
|
|
}
|
|
|
|
// FIXME: There should be a VariadicArgument type that takes any other type
|
|
// of argument and generates the appropriate type.
|
|
class VariadicEnumArgument<string name, string type, list<string> values,
|
|
list<string> enums> : Argument<name, 1> {
|
|
string Type = type;
|
|
list<string> Values = values;
|
|
list<string> Enums = enums;
|
|
}
|
|
|
|
// This handles one spelling of an attribute.
|
|
class Spelling<string name, string variety> {
|
|
string Name = name;
|
|
string Variety = variety;
|
|
bit KnownToGCC;
|
|
}
|
|
|
|
class GNU<string name> : Spelling<name, "GNU">;
|
|
class Declspec<string name> : Spelling<name, "Declspec">;
|
|
class Microsoft<string name> : Spelling<name, "Microsoft">;
|
|
class CXX11<string namespace, string name, int version = 1>
|
|
: Spelling<name, "CXX11"> {
|
|
string Namespace = namespace;
|
|
int Version = version;
|
|
}
|
|
class Keyword<string name> : Spelling<name, "Keyword">;
|
|
class Pragma<string namespace, string name> : Spelling<name, "Pragma"> {
|
|
string Namespace = namespace;
|
|
}
|
|
|
|
// The GCC spelling implies GNU<name, "GNU"> and CXX11<"gnu", name> and also
|
|
// sets KnownToGCC to 1. This spelling should be used for any GCC-compatible
|
|
// attributes.
|
|
class GCC<string name> : Spelling<name, "GCC"> {
|
|
let KnownToGCC = 1;
|
|
}
|
|
|
|
class Accessor<string name, list<Spelling> spellings> {
|
|
string Name = name;
|
|
list<Spelling> Spellings = spellings;
|
|
}
|
|
|
|
class SubjectDiag<bit warn> {
|
|
bit Warn = warn;
|
|
}
|
|
def WarnDiag : SubjectDiag<1>;
|
|
def ErrorDiag : SubjectDiag<0>;
|
|
|
|
class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag,
|
|
string customDiag = ""> {
|
|
list<AttrSubject> Subjects = subjects;
|
|
SubjectDiag Diag = diag;
|
|
string CustomDiag = customDiag;
|
|
}
|
|
|
|
class LangOpt<string name, bit negated = 0> {
|
|
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. The list of strings should
|
|
// specify architectures for which the target applies, based off the ArchType
|
|
// enumeration in Triple.h.
|
|
class TargetArch<list<string> arches> {
|
|
list<string> Arches = arches;
|
|
list<string> OSes;
|
|
list<string> CXXABIs;
|
|
}
|
|
def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
|
|
def TargetAVR : TargetArch<["avr"]>;
|
|
def TargetMips : TargetArch<["mips", "mipsel"]>;
|
|
def TargetMSP430 : TargetArch<["msp430"]>;
|
|
def TargetX86 : TargetArch<["x86"]>;
|
|
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
|
|
def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> {
|
|
let OSes = ["Win32"];
|
|
}
|
|
def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb"]> {
|
|
let CXXABIs = ["Microsoft"];
|
|
}
|
|
|
|
// 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<string name, list<AttrSubject> subjects,
|
|
bit negated = 0> {
|
|
string Name = name;
|
|
list<AttrSubject> 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<LangOpt> LangOpts = [];
|
|
}
|
|
class AttrSubjectMatcherRule<string name, list<AttrSubject> subjects,
|
|
list<AttrSubjectMatcherSubRule> subrules = []> {
|
|
string Name = name;
|
|
list<AttrSubject> Subjects = subjects;
|
|
list<AttrSubjectMatcherSubRule> 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<LangOpt> 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> {
|
|
AttrSubject Subject = subject;
|
|
}
|
|
|
|
def SubjectMatcherForNamed : AttrSubjectMatcherAggregateRule<Named>;
|
|
|
|
class Attr {
|
|
// The various ways in which an attribute can be spelled in source
|
|
list<Spelling> Spellings;
|
|
// The things to which an attribute can appertain
|
|
SubjectList Subjects;
|
|
// The arguments allowed on an attribute
|
|
list<Argument> Args = [];
|
|
// Accessors which should be generated for the attribute.
|
|
list<Accessor> 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;
|
|
// 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<LangOpt> 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> 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;
|
|
|
|
/// 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> {
|
|
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 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,
|
|
"ExpectedStructClassVariableFunctionOrInlineNamespace">;
|
|
let MeaningfulToClassTemplateDefinition = 1;
|
|
let Documentation = [AbiTagsDocs];
|
|
}
|
|
|
|
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 Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
|
|
"ExpectedFunctionOrGlobalVar">;
|
|
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 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.
|
|
GNU<"align_value">
|
|
// Intel's compiler on Windows also supports:
|
|
// , Declspec<"align_value">
|
|
];
|
|
let Args = [ExprArgument<"Alignment">];
|
|
let Subjects = SubjectList<[Var, TypedefName], WarnDiag,
|
|
"ExpectedVariableOrTypedef">;
|
|
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 XRayInstrument : InheritableAttr {
|
|
let Spellings = [GNU<"xray_always_instrument">,
|
|
CXX11<"clang", "xray_always_instrument">,
|
|
GNU<"xray_never_instrument">,
|
|
CXX11<"clang", "xray_never_instrument">];
|
|
let Subjects = SubjectList<[CXXMethod, ObjCMethod, Function], WarnDiag,
|
|
"ExpectedFunctionOrMethod">;
|
|
let Accessors = [Accessor<"alwaysXRayInstrument",
|
|
[GNU<"xray_always_instrument">,
|
|
CXX11<"clang", "xray_always_instrument">]>,
|
|
Accessor<"neverXRayInstrument",
|
|
[GNU<"xray_never_instrument">,
|
|
CXX11<"clang", "xray_never_instrument">]>];
|
|
let Documentation = [XRayDocs];
|
|
}
|
|
|
|
def XRayLogArgs : InheritableAttr {
|
|
let Spellings = [GNU<"xray_log_args">, CXX11<"clang", "xray_log_args">];
|
|
let Subjects = SubjectList<
|
|
[CXXMethod, ObjCMethod, Function], WarnDiag, "ExpectedFunctionOrMethod"
|
|
>;
|
|
let Args = [UnsignedArgument<"ArgumentCount">];
|
|
let Documentation = [XRayDocs];
|
|
}
|
|
|
|
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">];
|
|
// 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<TargetARM> {
|
|
// NOTE: If you add any additional spellings, MSP430Interrupt's,
|
|
// MipsInterrupt's and AnyX86Interrupt'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 AVRInterrupt : InheritableAttr, TargetSpecificAttr<TargetAVR> {
|
|
let Spellings = [GNU<"interrupt">];
|
|
let Subjects = SubjectList<[Function]>;
|
|
let ParseKind = "Interrupt";
|
|
let Documentation = [AVRInterruptDocs];
|
|
}
|
|
|
|
def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> {
|
|
let Spellings = [GNU<"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 = [GNU<"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<llvm::StringRef>(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<llvm::StringRef>(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<llvm::StringRef>(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 DuplicatesAllowedWhileMerging = 1;
|
|
let Subjects = SubjectList<[Named]>;
|
|
let Documentation = [AvailabilityDocs];
|
|
}
|
|
|
|
def ExternalSourceSymbol : InheritableAttr {
|
|
let Spellings = [GNU<"external_source_symbol">,
|
|
CXX11<"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 = [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", 200809>];
|
|
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];
|
|
}
|
|
|
|
// CUDA attributes are spelled __attribute__((attr)) or __declspec(__attr__).
|
|
|
|
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], 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">, 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];
|
|
}
|
|
|
|
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,
|
|
"ExpectedParameterOrTypedef">;
|
|
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>];
|
|
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<TargetMicrosoftCXXABI> {
|
|
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 = [IntArgument<"ElemSizeParam">, IntArgument<"NumElemsParam", 1>];
|
|
let TemplateDependent = 1;
|
|
let Documentation = [AllocSizeDocs];
|
|
}
|
|
|
|
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 : StmtAttr {
|
|
let Spellings = [CXX11<"", "fallthrough", 201603>,
|
|
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 = [FastCallDocs];
|
|
}
|
|
|
|
def RegCall : InheritableAttr {
|
|
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 = [GNU<"minsize">];
|
|
let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def FlagEnum : InheritableAttr {
|
|
let Spellings = [GNU<"flag_enum">];
|
|
let Subjects = SubjectList<[Enum]>;
|
|
let Documentation = [FlagEnumDocs];
|
|
}
|
|
|
|
def EnumExtensibility : InheritableAttr {
|
|
let Spellings = [GNU<"enum_extensibility">,
|
|
CXX11<"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], WarnDiag,
|
|
"ExpectedFunctionWithProtoType">;
|
|
let Documentation = [FormatDocs];
|
|
}
|
|
|
|
def FormatArg : InheritableAttr {
|
|
let Spellings = [GCC<"format_arg">];
|
|
let Args = [IntArgument<"FormatIdx">];
|
|
let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag,
|
|
"ExpectedFunctionWithProtoType">;
|
|
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 IFunc : Attr {
|
|
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<TargetMicrosoftCXXABI> {
|
|
let Spellings = [Declspec<"layout_version">];
|
|
let Args = [UnsignedArgument<"Version">];
|
|
let Subjects = SubjectList<[CXXRecord]>;
|
|
let Documentation = [LayoutVersionDocs];
|
|
}
|
|
|
|
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 = [MSABIDocs];
|
|
}
|
|
|
|
def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> {
|
|
// NOTE: If you add any additional spellings, ARMInterrupt's, MipsInterrupt's
|
|
// and AnyX86Interrupt'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<TargetMips> {
|
|
let Spellings = [GCC<"mips16">];
|
|
let Subjects = SubjectList<[Function], ErrorDiag>;
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> {
|
|
// NOTE: If you add any additional spellings, ARMInterrupt's,
|
|
// MSP430Interrupt's and AnyX86Interrupt's spellings must match.
|
|
let Spellings = [GNU<"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<TargetMips> {
|
|
let Spellings = [GCC<"micromips">];
|
|
let Subjects = SubjectList<[Function], ErrorDiag>;
|
|
let Documentation = [MicroMipsDocs];
|
|
}
|
|
|
|
def Mode : Attr {
|
|
let Spellings = [GCC<"mode">];
|
|
let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag,
|
|
"ExpectedVariableEnumFieldOrTypedef">;
|
|
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 DisableTailCalls : InheritableAttr {
|
|
let Spellings = [GNU<"disable_tail_calls">,
|
|
CXX11<"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], WarnDiag,
|
|
"ExpectedVariableOrFunction">;
|
|
let Documentation = [NoDebugDocs];
|
|
}
|
|
|
|
def NoDuplicate : InheritableAttr {
|
|
let Spellings = [GNU<"noduplicate">, CXX11<"clang", "noduplicate">];
|
|
let Subjects = SubjectList<[Function]>;
|
|
let Documentation = [NoDuplicateDocs];
|
|
}
|
|
|
|
def Convergent : InheritableAttr {
|
|
let Spellings = [GNU<"convergent">, CXX11<"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<TargetMips> {
|
|
let Spellings = [GCC<"nomips16">];
|
|
let Subjects = SubjectList<[Function], ErrorDiag>;
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips> {
|
|
let Spellings = [GCC<"nomicromips">];
|
|
let Subjects = SubjectList<[Function], ErrorDiag>;
|
|
let Documentation = [MicroMipsDocs];
|
|
}
|
|
|
|
// 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 = [GNU<"amdgpu_flat_work_group_size">];
|
|
let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">];
|
|
let Documentation = [AMDGPUFlatWorkGroupSizeDocs];
|
|
let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
|
|
}
|
|
|
|
def AMDGPUWavesPerEU : InheritableAttr {
|
|
let Spellings = [GNU<"amdgpu_waves_per_eu">];
|
|
let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>];
|
|
let Documentation = [AMDGPUWavesPerEUDocs];
|
|
let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
|
|
}
|
|
|
|
def AMDGPUNumSGPR : InheritableAttr {
|
|
let Spellings = [GNU<"amdgpu_num_sgpr">];
|
|
let Args = [UnsignedArgument<"NumSGPR">];
|
|
let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
|
|
let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
|
|
}
|
|
|
|
def AMDGPUNumVGPR : InheritableAttr {
|
|
let Spellings = [GNU<"amdgpu_num_vgpr">];
|
|
let Args = [UnsignedArgument<"NumVGPR">];
|
|
let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
|
|
let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
|
|
}
|
|
|
|
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,
|
|
"ExpectedFunctionMethodOrParameter">;
|
|
let Args = [VariadicUnsignedArgument<"Args">];
|
|
let AdditionalMembers =
|
|
[{bool isNonNull(unsigned idx) const {
|
|
if (!args_size())
|
|
return true;
|
|
for (const auto &V : args())
|
|
if (V == idx)
|
|
return true;
|
|
return false;
|
|
} }];
|
|
// FIXME: We should merge duplicates into a single nonnull attribute.
|
|
let DuplicatesAllowedWhileMerging = 1;
|
|
let Documentation = [NonNullDocs];
|
|
}
|
|
|
|
def ReturnsNonNull : InheritableAttr {
|
|
let Spellings = [GCC<"returns_nonnull">];
|
|
let Subjects = SubjectList<[ObjCMethod, Function], WarnDiag,
|
|
"ExpectedFunctionOrMethod">;
|
|
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 = [GNU<"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 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], WarnDiag,
|
|
"ExpectedFunctionWithProtoType">;
|
|
let Args = [IntArgument<"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 = [GNU<"not_tail_called">, CXX11<"clang", "not_tail_called">];
|
|
let Subjects = SubjectList<[Function]>;
|
|
let Documentation = [NotTailCalledDocs];
|
|
}
|
|
|
|
def NoThrow : InheritableAttr {
|
|
let Spellings = [GCC<"nothrow">, Declspec<"nothrow">];
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def NvWeak : IgnoredAttr {
|
|
// No Declspec spelling of this attribute; the CUDA headers use
|
|
// __attribute__((nv_weak)) unconditionally.
|
|
let Spellings = [GNU<"nv_weak">];
|
|
let LangOpts = [CUDA];
|
|
}
|
|
|
|
def ObjCBridge : InheritableAttr {
|
|
let Spellings = [GNU<"objc_bridge">];
|
|
let Subjects = SubjectList<[Record, TypedefName], ErrorDiag,
|
|
"ExpectedStructOrUnionOrTypedef">;
|
|
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", 1>,
|
|
IdentifierArgument<"InstanceMethod", 1>];
|
|
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 ObjCIndependentClass : InheritableAttr {
|
|
let Spellings = [GNU<"objc_independent_class">];
|
|
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 ObjCSubclassingRestricted : InheritableAttr {
|
|
let Spellings = [GNU<"objc_subclassing_restricted">];
|
|
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
|
|
let Documentation = [ObjCSubclassingRestrictedDocs];
|
|
}
|
|
|
|
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 ObjCRuntimeName : Attr {
|
|
let Spellings = [GNU<"objc_runtime_name">];
|
|
let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>;
|
|
let Args = [StringArgument<"MetadataName">];
|
|
let Documentation = [ObjCRuntimeNameDocs];
|
|
}
|
|
|
|
def ObjCRuntimeVisible : Attr {
|
|
let Spellings = [GNU<"objc_runtime_visible">];
|
|
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
|
|
let Documentation = [ObjCRuntimeVisibleDocs];
|
|
}
|
|
|
|
def ObjCBoxable : Attr {
|
|
let Spellings = [GNU<"objc_boxable">];
|
|
let Subjects = SubjectList<[Record], ErrorDiag, "ExpectedStructOrUnion">;
|
|
let Documentation = [ObjCBoxableDocs];
|
|
}
|
|
|
|
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,
|
|
"ExpectedFunctionWithProtoType">;
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def Packed : InheritableAttr {
|
|
let Spellings = [GCC<"packed">];
|
|
// let Subjects = [Tag, Field];
|
|
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 = [RegparmDocs];
|
|
}
|
|
|
|
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 RequireConstantInit : InheritableAttr {
|
|
let Spellings = [GNU<"require_constant_initialization">,
|
|
CXX11<"clang", "require_constant_initialization">];
|
|
let Subjects = SubjectList<[GlobalVar], ErrorDiag,
|
|
"ExpectedStaticOrTLSVar">;
|
|
let Documentation = [RequireConstantInitDocs];
|
|
let LangOpts = [CPlusPlus];
|
|
}
|
|
|
|
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 = [StdCallDocs];
|
|
}
|
|
|
|
def SwiftCall : InheritableAttr {
|
|
let Spellings = [GCC<"swiftcall">];
|
|
// let Subjects = SubjectList<[Function]>;
|
|
let Documentation = [SwiftCallDocs];
|
|
}
|
|
|
|
def SwiftContext : ParameterABIAttr {
|
|
let Spellings = [GCC<"swift_context">];
|
|
let Documentation = [SwiftContextDocs];
|
|
}
|
|
|
|
def SwiftErrorResult : ParameterABIAttr {
|
|
let Spellings = [GCC<"swift_error_result">];
|
|
let Documentation = [SwiftErrorResultDocs];
|
|
}
|
|
|
|
def SwiftIndirectResult : ParameterABIAttr {
|
|
let Spellings = [GCC<"swift_indirect_result">];
|
|
let Documentation = [SwiftIndirectResultDocs];
|
|
}
|
|
|
|
def Suppress : StmtAttr {
|
|
let Spellings = [CXX11<"gsl", "suppress">];
|
|
let Args = [VariadicStringArgument<"DiagnosticIdentifiers">];
|
|
let Documentation = [SuppressDocs];
|
|
}
|
|
|
|
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 = [ThisCallDocs];
|
|
}
|
|
|
|
def VectorCall : InheritableAttr {
|
|
let Spellings = [GNU<"vectorcall">, Keyword<"__vectorcall">,
|
|
Keyword<"_vectorcall">];
|
|
// let Subjects = [Function, ObjCMethod];
|
|
let Documentation = [VectorCallDocs];
|
|
}
|
|
|
|
def Pascal : InheritableAttr {
|
|
let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
|
|
// let Subjects = [Function, ObjCMethod];
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def PreserveMost : InheritableAttr {
|
|
let Spellings = [GNU<"preserve_most">];
|
|
let Documentation = [PreserveMostDocs];
|
|
}
|
|
|
|
def PreserveAll : InheritableAttr {
|
|
let Spellings = [GNU<"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 = [{
|
|
typedef std::pair<std::vector<std::string>, StringRef> ParsedTargetAttr;
|
|
ParsedTargetAttr parse() const {
|
|
ParsedTargetAttr Ret;
|
|
SmallVector<StringRef, 1> AttrFeatures;
|
|
getFeaturesStr().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="))
|
|
Ret.second = Feature.split("=").second.trim();
|
|
else if (Feature.startswith("no-"))
|
|
Ret.first.push_back("-" + Feature.split("-").second.str());
|
|
else
|
|
Ret.first.push_back("+" + Feature.str());
|
|
}
|
|
return Ret;
|
|
}
|
|
}];
|
|
}
|
|
|
|
def TransparentUnion : InheritableAttr {
|
|
let Spellings = [GCC<"transparent_union">];
|
|
// let Subjects = SubjectList<[Record, TypedefName]>;
|
|
let Documentation = [TransparentUnionDocs];
|
|
let LangOpts = [COnly];
|
|
}
|
|
|
|
def Unavailable : InheritableAttr {
|
|
let Spellings = [GNU<"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 {
|
|
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 DuplicatesAllowedWhileMerging = 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 = [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 = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">];
|
|
let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
|
|
Field, ObjCMethod, FunctionLike], WarnDiag,
|
|
"ExpectedForMaybeUnused">;
|
|
let Documentation = [WarnMaybeUnusedDocs];
|
|
}
|
|
|
|
def Used : InheritableAttr {
|
|
let Spellings = [GCC<"used">];
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def Uuid : InheritableAttr {
|
|
let Spellings = [Declspec<"uuid">, Microsoft<"uuid">];
|
|
let Args = [StringArgument<"Guid">];
|
|
let Subjects = SubjectList<[Record, Enum], WarnDiag, "ExpectedEnumOrClass">;
|
|
// 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 {
|
|
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 = [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 = [CXX11<"", "nodiscard", 201603>,
|
|
CXX11<"clang", "warn_unused_result">,
|
|
GCC<"warn_unused_result">];
|
|
let Subjects = SubjectList<[ObjCMethod, Enum, CXXRecord, FunctionLike],
|
|
WarnDiag, "ExpectedFunctionMethodEnumOrClass">;
|
|
let Documentation = [WarnUnusedResultsDocs];
|
|
}
|
|
|
|
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 LTOVisibilityPublic : InheritableAttr {
|
|
let Spellings = [CXX11<"clang", "lto_visibility_public">];
|
|
let Subjects = SubjectList<[Record]>;
|
|
let Documentation = [LTOVisibilityDocs];
|
|
}
|
|
|
|
def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
|
|
// NOTE: If you add any additional spellings, ARMInterrupt's,
|
|
// MSP430Interrupt's and MipsInterrupt's spellings must match.
|
|
let Spellings = [GNU<"interrupt">];
|
|
let Subjects = SubjectList<[HasFunctionProto]>;
|
|
let ParseKind = "Interrupt";
|
|
let HasCustomParsing = 1;
|
|
let Documentation = [AnyX86InterruptDocs];
|
|
}
|
|
|
|
def AnyX86NoCallerSavedRegisters : InheritableAttr,
|
|
TargetSpecificAttr<TargetAnyX86> {
|
|
let Spellings = [GCC<"no_caller_saved_registers">];
|
|
let Documentation = [AnyX86NoCallerSavedRegistersDocs];
|
|
}
|
|
|
|
def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> {
|
|
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];
|
|
}
|
|
|
|
def NoSanitize : InheritableAttr {
|
|
let Spellings = [GNU<"no_sanitize">, CXX11<"clang", "no_sanitize">];
|
|
let Args = [VariadicStringArgument<"Sanitizers">];
|
|
let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag,
|
|
"ExpectedFunctionMethodOrGlobalVar">;
|
|
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">,
|
|
GNU<"no_sanitize_memory">];
|
|
let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
|
|
"ExpectedFunctionOrGlobalVar">;
|
|
let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs,
|
|
NoSanitizeMemoryDocs];
|
|
let ASTNode = 0;
|
|
}
|
|
|
|
// 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<[Record, TypedefName], ErrorDiag,
|
|
"ExpectedStructOrUnionOrTypedef">;
|
|
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 MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
|
|
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<TargetWindows> {
|
|
let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
|
|
let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
|
|
let Documentation = [DLLExportDocs];
|
|
}
|
|
|
|
def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
|
|
let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
|
|
let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
|
|
let Documentation = [DLLImportDocs];
|
|
}
|
|
|
|
def SelectAny : InheritableAttr, TargetSpecificAttr<TargetWindows> {
|
|
let Spellings = [Declspec<"selectany">, GCC<"selectany">];
|
|
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 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 <option> directive
|
|
/// vectorize: vectorizes loop operations if State == Enable.
|
|
/// vectorize_width: vectorize loop operations with width 'Value'.
|
|
/// interleave: interleave multiple loop iterations if State == Enable.
|
|
/// interleave_count: interleaves 'Value' loop interations.
|
|
/// unroll: fully unroll loop if State == Enable.
|
|
/// unroll_count: unrolls loop 'Value' times.
|
|
/// distribute: attempt to distribute loop if State == Enable
|
|
|
|
/// #pragma unroll <argument> directive
|
|
/// <no arg>: fully unrolls loop.
|
|
/// boolean: fully unrolls loop if State == Enable.
|
|
/// expression: unrolls loop 'Value' times.
|
|
|
|
let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">,
|
|
Pragma<"", "nounroll">];
|
|
|
|
/// State of the loop optimization specified by the spelling.
|
|
let Args = [EnumArgument<"Option", "OptionType",
|
|
["vectorize", "vectorize_width", "interleave", "interleave_count",
|
|
"unroll", "unroll_count", "distribute"],
|
|
["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
|
|
"Unroll", "UnrollCount", "Distribute"]>,
|
|
EnumArgument<"State", "LoopHintState",
|
|
["enable", "disable", "numeric", "assume_safety", "full"],
|
|
["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>,
|
|
ExprArgument<"Value">];
|
|
|
|
let AdditionalMembers = [{
|
|
static const char *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";
|
|
case Distribute: return "distribute";
|
|
}
|
|
llvm_unreachable("Unhandled LoopHint option.");
|
|
}
|
|
|
|
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
|
|
unsigned SpellingIndex = getSpellingListIndex();
|
|
// For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
|
|
// "nounroll" is already emitted as the pragma name.
|
|
if (SpellingIndex == Pragma_nounroll)
|
|
return;
|
|
else if (SpellingIndex == Pragma_unroll) {
|
|
OS << getValueString(Policy);
|
|
return;
|
|
}
|
|
|
|
assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
|
|
OS << getOptionName(option) << getValueString(Policy);
|
|
}
|
|
|
|
// Return a string containing the loop hint argument including the
|
|
// enclosing parentheses.
|
|
std::string getValueString(const PrintingPolicy &Policy) const {
|
|
std::string ValueName;
|
|
llvm::raw_string_ostream OS(ValueName);
|
|
OS << "(";
|
|
if (state == Numeric)
|
|
value->printPretty(OS, nullptr, Policy);
|
|
else if (state == Enable)
|
|
OS << "enable";
|
|
else if (state == Full)
|
|
OS << "full";
|
|
else if (state == AssumeSafety)
|
|
OS << "assume_safety";
|
|
else
|
|
OS << "disable";
|
|
OS << ")";
|
|
return OS.str();
|
|
}
|
|
|
|
// Return a string suitable for identifying this attribute in diagnostics.
|
|
std::string getDiagnosticName(const PrintingPolicy &Policy) const {
|
|
unsigned SpellingIndex = getSpellingListIndex();
|
|
if (SpellingIndex == Pragma_nounroll)
|
|
return "#pragma nounroll";
|
|
else if (SpellingIndex == Pragma_unroll)
|
|
return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : "");
|
|
|
|
assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
|
|
return getOptionName(option) + getValueString(Policy);
|
|
}
|
|
}];
|
|
|
|
let Documentation = [LoopHintDocs, UnrollHintDocs];
|
|
}
|
|
|
|
def CapturedRecord : InheritableAttr {
|
|
// This attribute has no spellings as it is only ever created implicitly.
|
|
let Spellings = [];
|
|
let SemaHandler = 0;
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def OMPThreadPrivateDecl : InheritableAttr {
|
|
// This attribute has no spellings as it is only ever created implicitly.
|
|
let Spellings = [];
|
|
let SemaHandler = 0;
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def OMPCaptureNoInit : InheritableAttr {
|
|
// This attribute has no spellings as it is only ever created implicitly.
|
|
let Spellings = [];
|
|
let SemaHandler = 0;
|
|
let Documentation = [Undocumented];
|
|
}
|
|
|
|
def OMPDeclareSimdDecl : Attr {
|
|
let Spellings = [Pragma<"omp", "declare simd">];
|
|
let Subjects = SubjectList<[Function]>;
|
|
let SemaHandler = 0;
|
|
let HasCustomParsing = 1;
|
|
let Documentation = [OMPDeclareSimdDocs];
|
|
let Args = [
|
|
EnumArgument<"BranchState", "BranchStateTy",
|
|
[ "", "inbranch", "notinbranch" ],
|
|
[ "BS_Undefined", "BS_Inbranch", "BS_Notinbranch" ]>,
|
|
ExprArgument<"Simdlen">, VariadicExprArgument<"Uniforms">,
|
|
VariadicExprArgument<"Aligneds">, VariadicExprArgument<"Alignments">,
|
|
VariadicExprArgument<"Linears">, VariadicUnsignedArgument<"Modifiers">,
|
|
VariadicExprArgument<"Steps">
|
|
];
|
|
let AdditionalMembers = [{
|
|
void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
|
|
const {
|
|
if (getBranchState() != BS_Undefined)
|
|
OS << ConvertBranchStateTyToStr(getBranchState()) << " ";
|
|
if (auto *E = getSimdlen()) {
|
|
OS << "simdlen(";
|
|
E->printPretty(OS, nullptr, Policy);
|
|
OS << ") ";
|
|
}
|
|
if (uniforms_size() > 0) {
|
|
OS << "uniform";
|
|
StringRef Sep = "(";
|
|
for (auto *E : uniforms()) {
|
|
OS << Sep;
|
|
E->printPretty(OS, nullptr, Policy);
|
|
Sep = ", ";
|
|
}
|
|
OS << ") ";
|
|
}
|
|
alignments_iterator NI = alignments_begin();
|
|
for (auto *E : aligneds()) {
|
|
OS << "aligned(";
|
|
E->printPretty(OS, nullptr, Policy);
|
|
if (*NI) {
|
|
OS << ": ";
|
|
(*NI)->printPretty(OS, nullptr, Policy);
|
|
}
|
|
OS << ") ";
|
|
++NI;
|
|
}
|
|
steps_iterator I = steps_begin();
|
|
modifiers_iterator MI = modifiers_begin();
|
|
for (auto *E : linears()) {
|
|
OS << "linear(";
|
|
if (*MI != OMPC_LINEAR_unknown)
|
|
OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "(";
|
|
E->printPretty(OS, nullptr, Policy);
|
|
if (*MI != OMPC_LINEAR_unknown)
|
|
OS << ")";
|
|
if (*I) {
|
|
OS << ": ";
|
|
(*I)->printPretty(OS, nullptr, Policy);
|
|
}
|
|
OS << ") ";
|
|
++I;
|
|
++MI;
|
|
}
|
|
}
|
|
}];
|
|
}
|
|
|
|
def OMPDeclareTargetDecl : Attr {
|
|
let Spellings = [Pragma<"omp", "declare target">];
|
|
let SemaHandler = 0;
|
|
let Documentation = [OMPDeclareTargetDocs];
|
|
let Args = [
|
|
EnumArgument<"MapType", "MapTypeTy",
|
|
[ "to", "link" ],
|
|
[ "MT_To", "MT_Link" ]>
|
|
];
|
|
let AdditionalMembers = [{
|
|
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
|
|
// Use fake syntax because it is for testing and debugging purpose only.
|
|
if (getMapType() != MT_To)
|
|
OS << ConvertMapTypeTyToStr(getMapType()) << " ";
|
|
}
|
|
}];
|
|
}
|
|
|
|
def InternalLinkage : InheritableAttr {
|
|
let Spellings = [GNU<"internal_linkage">, CXX11<"clang", "internal_linkage">];
|
|
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
|
|
let Documentation = [InternalLinkageDocs];
|
|
}
|