aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Basic/Attr.td
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Basic/Attr.td')
-rw-r--r--include/clang/Basic/Attr.td204
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];
+}