diff options
Diffstat (limited to 'include/clang/Basic/Attr.td')
-rw-r--r-- | include/clang/Basic/Attr.td | 204 |
1 files changed, 160 insertions, 44 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 6187bcb2c4bf..d5ba72261644 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -113,7 +113,7 @@ def GlobalVar : SubsetSubject<Var, // 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) != NULL}]>; + [{S->getFunctionType(false) != nullptr}]>; def OpenCLKernelFunction : SubsetSubject<Function, [{ S->hasAttr<OpenCLKernelAttr>() @@ -123,15 +123,19 @@ def OpenCLKernelFunction : SubsetSubject<Function, [{ // 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) != NULL && + [{(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> { +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> : Argument<name, opt>; @@ -167,7 +171,8 @@ class DefaultIntArgument<string name, int default> : IntArgument<name, 1> { // 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> : Argument<name, opt> { + list<string> enums, bit opt = 0, bit fake = 0> + : Argument<name, opt, fake> { string Type = type; list<string> Values = values; list<string> Enums = enums; @@ -241,14 +246,18 @@ def COnly : LangOpt<"CPlusPlus", 1>; class TargetArch<list<string> arches> { list<string> Arches = arches; list<string> OSes; + list<string> CXXABIs; } def TargetARM : TargetArch<["arm", "thumb"]>; +def TargetMips : TargetArch<["mips", "mipsel"]>; def TargetMSP430 : TargetArch<["msp430"]>; def TargetX86 : TargetArch<["x86"]>; def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> { let OSes = ["Win32"]; } -def TargetMips : TargetArch<["mips", "mipsel"]>; +def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb"]> { + let CXXABIs = ["Microsoft"]; +} class Attr { // The various ways in which an attribute can be spelled in source @@ -286,6 +295,8 @@ class Attr { // 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 @@ -415,8 +426,8 @@ def Annotate : InheritableParamAttr { } def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> { - // NOTE: If you add any additional spellings, MSP430Interrupt's spellings - // must match. + // NOTE: If you add any additional spellings, MSP430Interrupt's and + // MipsInterrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Args = [EnumArgument<"Interrupt", "InterruptType", ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], @@ -445,8 +456,12 @@ def Availability : InheritableAttr { .Case("android", "Android") .Case("ios", "iOS") .Case("macosx", "OS X") + .Case("tvos", "tvOS") + .Case("watchos", "watchOS") .Case("ios_app_extension", "iOS (App Extension)") .Case("macosx_app_extension", "OS X (App Extension)") + .Case("tvos_app_extension", "tvOS (App Extension)") + .Case("watchos_app_extension", "watchOS (App Extension)") .Default(llvm::StringRef()); } }]; let HasCustomParsing = 1; @@ -553,6 +568,11 @@ def CUDAConstant : InheritableAttr { let Documentation = [Undocumented]; } +def CUDACudartBuiltin : IgnoredAttr { + let Spellings = [GNU<"cudart_builtin">]; + let LangOpts = [CUDA]; +} + def CUDADevice : InheritableAttr { let Spellings = [GNU<"device">]; let Subjects = SubjectList<[Function, Var]>; @@ -560,6 +580,21 @@ def CUDADevice : InheritableAttr { let Documentation = [Undocumented]; } +def CUDADeviceBuiltin : IgnoredAttr { + let Spellings = [GNU<"device_builtin">]; + let LangOpts = [CUDA]; +} + +def CUDADeviceBuiltinSurfaceType : IgnoredAttr { + let Spellings = [GNU<"device_builtin_surface_type">]; + let LangOpts = [CUDA]; +} + +def CUDADeviceBuiltinTextureType : IgnoredAttr { + let Spellings = [GNU<"device_builtin_texture_type">]; + let LangOpts = [CUDA]; +} + def CUDAGlobal : InheritableAttr { let Spellings = [GNU<"global">]; let Subjects = SubjectList<[Function]>; @@ -721,18 +756,6 @@ def FlagEnum : InheritableAttr { let Subjects = SubjectList<[Enum]>; let Documentation = [FlagEnumDocs]; let LangOpts = [COnly]; - let AdditionalMembers = [{ -private: - llvm::APInt FlagBits; -public: - llvm::APInt &getFlagBits() { - return FlagBits; - } - - const llvm::APInt &getFlagBits() const { - return FlagBits; - } -}]; } def Flatten : InheritableAttr { @@ -746,7 +769,7 @@ def Format : InheritableAttr { let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">, IntArgument<"FirstArg">]; let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto], WarnDiag, - "ExpectedFunction">; + "ExpectedFunctionWithProtoType">; let Documentation = [FormatDocs]; } @@ -754,7 +777,7 @@ def FormatArg : InheritableAttr { let Spellings = [GCC<"format_arg">]; let Args = [IntArgument<"FormatIdx">]; let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag, - "ExpectedFunction">; + "ExpectedFunctionWithProtoType">; let Documentation = [Undocumented]; } @@ -822,8 +845,8 @@ def MSABI : InheritableAttr { } def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> { - // NOTE: If you add any additional spellings, ARMInterrupt's spellings must - // match. + // NOTE: If you add any additional spellings, ARMInterrupt's and + // MipsInterrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Args = [UnsignedArgument<"Number">]; let ParseKind = "Interrupt"; @@ -837,6 +860,22 @@ def Mips16 : InheritableAttr, TargetSpecificAttr<TargetMips> { let Documentation = [Undocumented]; } +def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> { + // NOTE: If you add any additional spellings, ARMInterrupt's and + // MSP430Interrupt'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 Mode : Attr { let Spellings = [GCC<"mode">]; let Args = [IdentifierArgument<"Mode">]; @@ -867,6 +906,19 @@ def ReturnsTwice : InheritableAttr { 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]>; @@ -960,6 +1012,15 @@ def ReturnsNonNull : InheritableAttr { 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">]; @@ -1000,11 +1061,22 @@ def NoInstrumentFunction : InheritableAttr { 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 { + let Spellings = [GNU<"nv_weak">]; + let LangOpts = [CUDA]; +} + def ObjCBridge : InheritableAttr { let Spellings = [GNU<"objc_bridge">]; let Subjects = SubjectList<[Record, TypedefName], ErrorDiag, @@ -1024,8 +1096,8 @@ def ObjCBridgeRelated : InheritableAttr { let Spellings = [GNU<"objc_bridge_related">]; let Subjects = SubjectList<[Record], ErrorDiag>; let Args = [IdentifierArgument<"RelatedClass">, - IdentifierArgument<"ClassMethod">, - IdentifierArgument<"InstanceMethod">]; + IdentifierArgument<"ClassMethod", 1>, + IdentifierArgument<"InstanceMethod", 1>]; let HasCustomParsing = 1; let Documentation = [Undocumented]; } @@ -1169,7 +1241,8 @@ def Ownership : InheritableAttr { } }]; let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">]; - let Subjects = SubjectList<[HasFunctionProto], WarnDiag, "ExpectedFunction">; + let Subjects = SubjectList<[HasFunctionProto], WarnDiag, + "ExpectedFunctionWithProtoType">; let Documentation = [Undocumented]; } @@ -1280,9 +1353,41 @@ def Pascal : InheritableAttr { def Target : InheritableAttr { let Spellings = [GCC<"target">]; - let Args = [StringArgument<"features">]; + 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 { @@ -1293,7 +1398,15 @@ def TransparentUnion : InheritableAttr { def Unavailable : InheritableAttr { let Spellings = [GNU<"unavailable">]; - let Args = [StringArgument<"Message", 1>]; + 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]; } @@ -1486,8 +1599,8 @@ def Capability : InheritableAttr { let Spellings = [GNU<"capability">, CXX11<"clang", "capability">, GNU<"shared_capability">, CXX11<"clang", "shared_capability">]; - let Subjects = SubjectList<[Struct, TypedefName], ErrorDiag, - "ExpectedStructOrTypedef">; + let Subjects = SubjectList<[Record, TypedefName], ErrorDiag, + "ExpectedStructOrUnionOrTypedef">; let Args = [StringArgument<"Name">]; let Accessors = [Accessor<"isShared", [GNU<"shared_capability">, @@ -1814,7 +1927,7 @@ def TypeTagForDatatype : InheritableAttr { // Microsoft-related attributes -def MSNoVTable : InheritableAttr { +def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [MSNoVTableDocs]; @@ -1970,8 +2083,8 @@ def LoopHint : Attr { ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount", "Unroll", "UnrollCount"]>, EnumArgument<"State", "LoopHintState", - ["default", "enable", "disable", "assume_safety"], - ["Default", "Enable", "Disable", "AssumeSafety"]>, + ["enable", "disable", "numeric", "assume_safety", "full"], + ["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>, ExprArgument<"Value">]; let AdditionalMembers = [{ @@ -1991,17 +2104,15 @@ def LoopHint : Attr { 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) { - OS << "\n"; + if (SpellingIndex == Pragma_nounroll) return; - } else if (SpellingIndex == Pragma_unroll) { - OS << getValueString(Policy) << "\n"; + OS << getValueString(Policy); return; } assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); - OS << getOptionName(option) << getValueString(Policy) << "\n"; + OS << getOptionName(option) << getValueString(Policy); } // Return a string containing the loop hint argument including the @@ -2010,13 +2121,12 @@ def LoopHint : Attr { std::string ValueName; llvm::raw_string_ostream OS(ValueName); OS << "("; - if (option == VectorizeWidth || option == InterleaveCount || - option == UnrollCount) + if (state == Numeric) value->printPretty(OS, nullptr, Policy); - else if (state == Default) - return ""; else if (state == Enable) - OS << (option == Unroll ? "full" : "enable"); + OS << "enable"; + else if (state == Full) + OS << "full"; else if (state == AssumeSafety) OS << "assume_safety"; else @@ -2031,7 +2141,7 @@ def LoopHint : Attr { if (SpellingIndex == Pragma_nounroll) return "#pragma nounroll"; else if (SpellingIndex == Pragma_unroll) - return "#pragma unroll" + getValueString(Policy); + return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : ""); assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); return getOptionName(option) + getValueString(Policy); @@ -2054,3 +2164,9 @@ def OMPThreadPrivateDecl : InheritableAttr { let SemaHandler = 0; let Documentation = [Undocumented]; } + +def InternalLinkage : InheritableAttr { + let Spellings = [GNU<"internal_linkage">, CXX11<"clang", "internal_linkage">]; + let Subjects = SubjectList<[Var, Function, CXXRecord]>; + let Documentation = [InternalLinkageDocs]; +} |