diff options
Diffstat (limited to 'include/clang/Basic/Attr.td')
-rw-r--r-- | include/clang/Basic/Attr.td | 246 |
1 files changed, 186 insertions, 60 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 704a375ba291..843746111463 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -115,6 +115,10 @@ def DeclBase : AttrSubject; def FunctionLike : SubsetSubject<DeclBase, [{S->getFunctionType(false) != NULL}]>; +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). @@ -186,10 +190,11 @@ class Spelling<string name, string variety> { class GNU<string name> : Spelling<name, "GNU">; class Declspec<string name> : Spelling<name, "Declspec">; -class CXX11<string namespace, string name> : Spelling<name, "CXX11"> { +class CXX11<string namespace, string name, int version = 1> + : Spelling<name, "CXX11"> { string Namespace = namespace; -} -class Keyword<string name> : Spelling<name, "Keyword">; + int Version = version; +} class Keyword<string name> : Spelling<name, "Keyword">; class Pragma<string namespace, string name> : Spelling<name, "Pragma"> { string Namespace = namespace; } @@ -219,12 +224,14 @@ class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag, string CustomDiag = customDiag; } -class LangOpt<string name> { +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>; // Defines targets for target-specific attributes. The list of strings should // specify architectures for which the target applies, based off the ArchType @@ -354,6 +361,24 @@ def Aligned : InheritableAttr { 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 = []; @@ -434,7 +459,8 @@ def Bounded : IgnoredAttr { } def CarriesDependency : InheritableParamAttr { - let Spellings = [GNU<"carries_dependency">, CXX11<"","carries_dependency">]; + let Spellings = [GNU<"carries_dependency">, + CXX11<"","carries_dependency", 200809>]; let Subjects = SubjectList<[ParmVar, ObjCMethod, Function], ErrorDiag>; let Documentation = [CarriesDependencyDocs]; } @@ -541,6 +567,13 @@ def CUDAHost : InheritableAttr { 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">]; let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>]; @@ -568,7 +601,7 @@ def C11NoReturn : InheritableAttr { } def CXX11NoReturn : InheritableAttr { - let Spellings = [CXX11<"","noreturn">]; + let Spellings = [CXX11<"","noreturn", 200809>]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [CXX11NoReturnDocs]; } @@ -597,27 +630,32 @@ def OpenCLImageAccess : Attr { def OpenCLPrivateAddressSpace : TypeAttr { let Spellings = [Keyword<"__private">, Keyword<"private">]; - let Documentation = [Undocumented]; + let Documentation = [OpenCLAddressSpacePrivateDocs]; } def OpenCLGlobalAddressSpace : TypeAttr { let Spellings = [Keyword<"__global">, Keyword<"global">]; - let Documentation = [Undocumented]; + let Documentation = [OpenCLAddressSpaceGlobalDocs]; } def OpenCLLocalAddressSpace : TypeAttr { let Spellings = [Keyword<"__local">, Keyword<"local">]; - let Documentation = [Undocumented]; + let Documentation = [OpenCLAddressSpaceLocalDocs]; } def OpenCLConstantAddressSpace : TypeAttr { let Spellings = [Keyword<"__constant">, Keyword<"constant">]; - let Documentation = [Undocumented]; + let Documentation = [OpenCLAddressSpaceConstantDocs]; +} + +def OpenCLGenericAddressSpace : TypeAttr { + let Spellings = [Keyword<"__generic">, Keyword<"generic">]; + let Documentation = [OpenCLAddressSpaceGenericDocs]; } def Deprecated : InheritableAttr { let Spellings = [GCC<"deprecated">, Declspec<"deprecated">, - CXX11<"","deprecated">]; + CXX11<"","deprecated", 201309>]; let Args = [StringArgument<"Message", 1>]; let Documentation = [Undocumented]; } @@ -655,7 +693,7 @@ def FastCall : InheritableAttr { let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">, Keyword<"_fastcall">]; // let Subjects = [Function, ObjCMethod]; - let Documentation = [Undocumented]; + let Documentation = [FastCallDocs]; } def Final : InheritableAttr { @@ -671,6 +709,25 @@ def MinSize : InheritableAttr { let Documentation = [Undocumented]; } +def FlagEnum : InheritableAttr { + let Spellings = [GNU<"flag_enum">]; + 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 { let Spellings = [GCC<"flatten">]; let Subjects = SubjectList<[Function], ErrorDiag>; @@ -754,7 +811,7 @@ def MayAlias : InheritableAttr { def MSABI : InheritableAttr { let Spellings = [GCC<"ms_abi">]; // let Subjects = [Function, ObjCMethod]; - let Documentation = [Undocumented]; + let Documentation = [MSABIDocs]; } def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> { @@ -810,7 +867,7 @@ def NoCommon : InheritableAttr { } def NoDebug : InheritableAttr { - let Spellings = [GNU<"nodebug">]; + let Spellings = [GCC<"nodebug">]; let Documentation = [Undocumented]; } @@ -832,6 +889,38 @@ def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips> { let Documentation = [Undocumented]; } +// 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. +def AMDGPUNumVGPR : InheritableAttr { + let Spellings = [GNU<"amdgpu_num_vgpr">]; + let Args = [UnsignedArgument<"NumVGPR">]; + let Documentation = [AMDGPUNumVGPRDocs]; + +// FIXME: This 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. + let Subjects = SubjectList<[Function], ErrorDiag, + "ExpectedKernelFunction">; +} + +def AMDGPUNumSGPR : InheritableAttr { + let Spellings = [GNU<"amdgpu_num_sgpr">]; + let Args = [UnsignedArgument<"NumSGPR">]; + let Documentation = [AMDGPUNumSGPRDocs]; + let Subjects = SubjectList<[Function], ErrorDiag, + "ExpectedKernelFunction">; +} + def NoSplitStack : InheritableAttr { let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; @@ -845,11 +934,15 @@ def NonNull : InheritableAttr { 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 = [Undocumented]; } @@ -860,6 +953,13 @@ def ReturnsNonNull : InheritableAttr { 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 NoReturn : InheritableAttr { let Spellings = [GCC<"noreturn">, Declspec<"noreturn">]; // FIXME: Does GCC allow this on the function instead? @@ -1068,7 +1168,7 @@ def Pure : InheritableAttr { def Regparm : TypeAttr { let Spellings = [GCC<"regparm">]; let Args = [UnsignedArgument<"NumParams">]; - let Documentation = [Undocumented]; + let Documentation = [RegparmDocs]; } def ReqdWorkGroupSize : InheritableAttr { @@ -1115,7 +1215,7 @@ def Sentinel : InheritableAttr { def StdCall : InheritableAttr { let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">]; // let Subjects = [Function, ObjCMethod]; - let Documentation = [Undocumented]; + let Documentation = [StdCallDocs]; } def SysVABI : InheritableAttr { @@ -1128,7 +1228,14 @@ def ThisCall : InheritableAttr { let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">, Keyword<"_thiscall">]; // let Subjects = [Function, ObjCMethod]; - let Documentation = [Undocumented]; + let Documentation = [ThisCallDocs]; +} + +def VectorCall : InheritableAttr { + let Spellings = [GNU<"vectorcall">, Keyword<"__vectorcall">, + Keyword<"_vectorcall">]; +// let Subjects = [Function, ObjCMethod]; + let Documentation = [VectorCallDocs]; } def Pascal : InheritableAttr { @@ -1784,14 +1891,21 @@ def Unaligned : IgnoredAttr { } def LoopHint : Attr { - /// vectorize: vectorizes loop operations if 'value != 0'. - /// vectorize_width: vectorize loop operations with width 'value'. - /// interleave: interleave multiple loop iterations if 'value != 0'. - /// interleave_count: interleaves 'value' loop interations. - /// unroll: unroll loop if 'value != 0'. - /// unroll_count: unrolls loop 'value' times. - - let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">]; + /// #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. + + /// #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", @@ -1799,10 +1913,13 @@ def LoopHint : Attr { "unroll", "unroll_count"], ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount", "Unroll", "UnrollCount"]>, - DefaultIntArgument<"Value", 1>]; + EnumArgument<"State", "LoopHintState", + ["default", "enable", "disable"], + ["Default", "Enable", "Disable"]>, + ExprArgument<"Value">]; let AdditionalMembers = [{ - static StringRef getOptionName(int Option) { + static const char *getOptionName(int Option) { switch(Option) { case Vectorize: return "vectorize"; case VectorizeWidth: return "vectorize_width"; @@ -1814,59 +1931,68 @@ def LoopHint : Attr { llvm_unreachable("Unhandled LoopHint option."); } - static StringRef getValueName(int Value) { - if (Value) - return "enable"; - return "disable"; - } - void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { unsigned SpellingIndex = getSpellingListIndex(); - if (SpellingIndex == Pragma_unroll) { - // String "unroll" of "#pragma unroll" is already emitted as the - // pragma name. - if (option == UnrollCount) - printArgument(OS); + // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or + // "nounroll" is already emitted as the pragma name. + if (SpellingIndex == Pragma_nounroll) { OS << "\n"; return; } + else if (SpellingIndex == Pragma_unroll) { + OS << getValueString(Policy) << "\n"; + return; + } + assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); - OS << getOptionName(option); - printArgument(OS); - OS << "\n"; + OS << getOptionName(option) << getValueString(Policy) << "\n"; } - // Prints the loop hint argument including the enclosing parentheses to OS. - void printArgument(raw_ostream &OS) const { + // 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 (option == VectorizeWidth || option == InterleaveCount || option == UnrollCount) - OS << value; - else if (value) - OS << "enable"; + value->printPretty(OS, nullptr, Policy); + else if (state == Default) + return ""; + else if (state == Enable) + OS << (option == Unroll ? "full" : "enable"); else OS << "disable"; OS << ")"; + return OS.str(); } // Return a string suitable for identifying this attribute in diagnostics. - std::string getDiagnosticName() const { - std::string DiagnosticName; - llvm::raw_string_ostream OS(DiagnosticName); + std::string getDiagnosticName(const PrintingPolicy &Policy) const { unsigned SpellingIndex = getSpellingListIndex(); - if (SpellingIndex == Pragma_unroll && option == Unroll) - OS << "#pragma unroll"; - else if (SpellingIndex == Pragma_unroll && option == UnrollCount) { - OS << "#pragma unroll"; - printArgument(OS); - } else { - assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); - OS << getOptionName(option); - printArgument(OS); - } - return OS.str(); + if (SpellingIndex == Pragma_nounroll) + return "#pragma nounroll"; + else if (SpellingIndex == Pragma_unroll) + return "#pragma unroll" + 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]; +} |