| 1 | //==--- Attr.td - attribute definitions -----------------------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | // The documentation is organized by category. Attributes can have category- |
| 10 | // specific documentation that is collated within the larger document. |
| 11 | class DocumentationCategory<string name> { |
| 12 | string Name = name; |
| 13 | code Content = [{}]; |
| 14 | } |
| 15 | def DocCatFunction : DocumentationCategory<"Function Attributes">; |
| 16 | def DocCatVariable : DocumentationCategory<"Variable Attributes">; |
| 17 | def DocCatType : DocumentationCategory<"Type Attributes">; |
| 18 | def DocCatStmt : DocumentationCategory<"Statement Attributes">; |
| 19 | // Attributes listed under the Undocumented category do not generate any public |
| 20 | // documentation. Ideally, this category should be used for internal-only |
| 21 | // attributes which contain no spellings. |
| 22 | def DocCatUndocumented : DocumentationCategory<"Undocumented">; |
| 23 | |
| 24 | class DocDeprecated<string replacement = ""> { |
| 25 | // If the Replacement field is empty, no replacement will be listed with the |
| 26 | // documentation. Otherwise, the documentation will specify the attribute has |
| 27 | // been superseded by this replacement. |
| 28 | string Replacement = replacement; |
| 29 | } |
| 30 | |
| 31 | // Specifies the documentation to be associated with the given category. |
| 32 | class Documentation { |
| 33 | DocumentationCategory Category; |
| 34 | code Content; |
| 35 | |
| 36 | // If the heading is empty, one may be picked automatically. If the attribute |
| 37 | // only has one spelling, no heading is required as the attribute's sole |
| 38 | // spelling is sufficient. If all spellings are semantically common, the |
| 39 | // heading will be the semantic spelling. If the spellings are not |
| 40 | // semantically common and no heading is provided, an error will be emitted. |
| 41 | string Heading = ""; |
| 42 | |
| 43 | // When set, specifies that the attribute is deprecated and can optionally |
| 44 | // specify a replacement attribute. |
| 45 | DocDeprecated Deprecated; |
| 46 | } |
| 47 | |
| 48 | // Specifies that the attribute is explicitly undocumented. This can be a |
| 49 | // helpful placeholder for the attribute while working on the implementation, |
| 50 | // but should not be used once feature work has been completed. |
| 51 | def Undocumented : Documentation { |
| 52 | let Category = DocCatUndocumented; |
| 53 | } |
| 54 | |
| 55 | include "clang/Basic/AttrDocs.td" |
| 56 | |
| 57 | // An attribute's subject is whatever it appertains to. In this file, it is |
| 58 | // more accurately a list of things that an attribute can appertain to. All |
| 59 | // Decls and Stmts are possibly AttrSubjects (even though the syntax may not |
| 60 | // allow attributes on a given Decl or Stmt). |
| 61 | class AttrSubject; |
| 62 | |
| 63 | include "clang/Basic/DeclNodes.td" |
| 64 | include "clang/Basic/StmtNodes.td" |
| 65 | |
| 66 | // A subset-subject is an AttrSubject constrained to operate only on some subset |
| 67 | // of that subject. |
| 68 | // |
| 69 | // The code fragment is a boolean expression that will confirm that the subject |
| 70 | // meets the requirements; the subject will have the name S, and will have the |
| 71 | // type specified by the base. It should be a simple boolean expression. The |
| 72 | // diagnostic string should be a comma-separated list of subject names. |
| 73 | class SubsetSubject<AttrSubject base, code check, string diag> : AttrSubject { |
| 74 | AttrSubject Base = base; |
| 75 | code CheckCode = check; |
| 76 | string DiagSpelling = diag; |
| 77 | } |
| 78 | |
| 79 | def LocalVar : SubsetSubject<Var, |
| 80 | [{S->hasLocalStorage() && !isa<ParmVarDecl>(S)}], |
| 81 | "local variables">; |
| 82 | def NonParmVar : SubsetSubject<Var, |
| 83 | [{S->getKind() != Decl::ParmVar}], |
| 84 | "variables">; |
| 85 | def NonLocalVar : SubsetSubject<Var, |
| 86 | [{!S->hasLocalStorage()}], |
| 87 | "variables with non-local storage">; |
| 88 | def NonBitField : SubsetSubject<Field, |
| 89 | [{!S->isBitField()}], |
| 90 | "non-bit-field non-static data members">; |
| 91 | |
| 92 | def NonStaticCXXMethod : SubsetSubject<CXXMethod, |
| 93 | [{!S->isStatic()}], |
| 94 | "non-static member functions">; |
| 95 | |
| 96 | def NonStaticNonConstCXXMethod |
| 97 | : SubsetSubject<CXXMethod, |
| 98 | [{!S->isStatic() && !S->isConst()}], |
| 99 | "non-static non-const member functions">; |
| 100 | |
| 101 | def ObjCInstanceMethod : SubsetSubject<ObjCMethod, |
| 102 | [{S->isInstanceMethod()}], |
| 103 | "Objective-C instance methods">; |
| 104 | |
| 105 | def Struct : SubsetSubject<Record, |
| 106 | [{!S->isUnion()}], "structs">; |
| 107 | |
| 108 | def TLSVar : SubsetSubject<Var, |
| 109 | [{S->getTLSKind() != 0}], "thread-local variables">; |
| 110 | |
| 111 | def SharedVar : SubsetSubject<Var, |
| 112 | [{S->hasGlobalStorage() && !S->getTLSKind()}], |
| 113 | "global variables">; |
| 114 | |
| 115 | def GlobalVar : SubsetSubject<Var, |
| 116 | [{S->hasGlobalStorage()}], "global variables">; |
| 117 | |
| 118 | def InlineFunction : SubsetSubject<Function, |
| 119 | [{S->isInlineSpecified()}], "inline functions">; |
| 120 | |
| 121 | // FIXME: this hack is needed because DeclNodes.td defines the base Decl node |
| 122 | // type to be a class, not a definition. This makes it impossible to create an |
| 123 | // attribute subject which accepts a Decl. Normally, this is not a problem, |
| 124 | // because the attribute can have no Subjects clause to accomplish this. But in |
| 125 | // the case of a SubsetSubject, there's no way to express it without this hack. |
| 126 | def DeclBase : AttrSubject; |
| 127 | def FunctionLike : SubsetSubject<DeclBase, |
| 128 | [{S->getFunctionType(false) != nullptr}], |
| 129 | "functions, function pointers">; |
| 130 | |
| 131 | def OpenCLKernelFunction |
| 132 | : SubsetSubject<Function, [{S->hasAttr<OpenCLKernelAttr>()}], |
| 133 | "kernel functions">; |
| 134 | |
| 135 | // HasFunctionProto is a more strict version of FunctionLike, so it should |
| 136 | // never be specified in a Subjects list along with FunctionLike (due to the |
| 137 | // inclusive nature of subject testing). |
| 138 | def HasFunctionProto : SubsetSubject<DeclBase, |
| 139 | [{(S->getFunctionType(true) != nullptr && |
| 140 | isa<FunctionProtoType>(S->getFunctionType())) || |
| 141 | isa<ObjCMethodDecl>(S) || |
| 142 | isa<BlockDecl>(S)}], |
| 143 | "non-K&R-style functions">; |
| 144 | |
| 145 | // A subject that matches the implicit object parameter of a non-static member |
| 146 | // function. Accepted as a function type attribute on the type of such a |
| 147 | // member function. |
| 148 | // FIXME: This does not actually ever match currently. |
| 149 | def ImplicitObjectParameter |
| 150 | : SubsetSubject<Function, [{static_cast<void>(S), false}], |
| 151 | "implicit object parameters">; |
| 152 | |
| 153 | // A single argument to an attribute |
| 154 | class Argument<string name, bit optional, bit fake = 0> { |
| 155 | string Name = name; |
| 156 | bit Optional = optional; |
| 157 | |
| 158 | /// A fake argument is used to store and serialize additional information |
| 159 | /// in an attribute without actually changing its parsing or pretty-printing. |
| 160 | bit Fake = fake; |
| 161 | } |
| 162 | |
| 163 | class BoolArgument<string name, bit opt = 0, bit fake = 0> : Argument<name, opt, |
| 164 | fake>; |
| 165 | class IdentifierArgument<string name, bit opt = 0> : Argument<name, opt>; |
| 166 | class IntArgument<string name, bit opt = 0> : Argument<name, opt>; |
| 167 | class StringArgument<string name, bit opt = 0> : Argument<name, opt>; |
| 168 | class ExprArgument<string name, bit opt = 0> : Argument<name, opt>; |
| 169 | class FunctionArgument<string name, bit opt = 0, bit fake = 0> : Argument<name, |
| 170 | opt, |
| 171 | fake>; |
| 172 | class NamedArgument<string name, bit opt = 0, bit fake = 0> : Argument<name, |
| 173 | opt, |
| 174 | fake>; |
| 175 | class TypeArgument<string name, bit opt = 0> : Argument<name, opt>; |
| 176 | class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>; |
| 177 | class VariadicUnsignedArgument<string name> : Argument<name, 1>; |
| 178 | class VariadicExprArgument<string name> : Argument<name, 1>; |
| 179 | class VariadicStringArgument<string name> : Argument<name, 1>; |
| 180 | class VariadicIdentifierArgument<string name> : Argument<name, 1>; |
| 181 | |
| 182 | // Like VariadicUnsignedArgument except values are ParamIdx. |
| 183 | class VariadicParamIdxArgument<string name> : Argument<name, 1>; |
| 184 | |
| 185 | // A list of identifiers matching parameters or ParamIdx indices. |
| 186 | class VariadicParamOrParamIdxArgument<string name> : Argument<name, 1>; |
| 187 | |
| 188 | // Like VariadicParamIdxArgument but for a single function parameter index. |
| 189 | class ParamIdxArgument<string name, bit opt = 0> : Argument<name, opt>; |
| 190 | |
| 191 | // A version of the form major.minor[.subminor]. |
| 192 | class VersionArgument<string name, bit opt = 0> : Argument<name, opt>; |
| 193 | |
| 194 | // This one's a doozy, so it gets its own special type |
| 195 | // It can be an unsigned integer, or a type. Either can |
| 196 | // be dependent. |
| 197 | class AlignedArgument<string name, bit opt = 0> : Argument<name, opt>; |
| 198 | |
| 199 | // A bool argument with a default value |
| 200 | class DefaultBoolArgument<string name, bit default, bit fake = 0> |
| 201 | : BoolArgument<name, 1, fake> { |
| 202 | bit Default = default; |
| 203 | } |
| 204 | |
| 205 | // An integer argument with a default value |
| 206 | class DefaultIntArgument<string name, int default> : IntArgument<name, 1> { |
| 207 | int Default = default; |
| 208 | } |
| 209 | |
| 210 | // This argument is more complex, it includes the enumerator type name, |
| 211 | // a list of strings to accept, and a list of enumerators to map them to. |
| 212 | class EnumArgument<string name, string type, list<string> values, |
| 213 | list<string> enums, bit opt = 0, bit fake = 0> |
| 214 | : Argument<name, opt, fake> { |
| 215 | string Type = type; |
| 216 | list<string> Values = values; |
| 217 | list<string> Enums = enums; |
| 218 | } |
| 219 | |
| 220 | // FIXME: There should be a VariadicArgument type that takes any other type |
| 221 | // of argument and generates the appropriate type. |
| 222 | class VariadicEnumArgument<string name, string type, list<string> values, |
| 223 | list<string> enums> : Argument<name, 1> { |
| 224 | string Type = type; |
| 225 | list<string> Values = values; |
| 226 | list<string> Enums = enums; |
| 227 | } |
| 228 | |
| 229 | // This handles one spelling of an attribute. |
| 230 | class Spelling<string name, string variety> { |
| 231 | string Name = name; |
| 232 | string Variety = variety; |
| 233 | bit KnownToGCC; |
| 234 | } |
| 235 | |
| 236 | class GNU<string name> : Spelling<name, "GNU">; |
| 237 | class Declspec<string name> : Spelling<name, "Declspec">; |
| 238 | class Microsoft<string name> : Spelling<name, "Microsoft">; |
| 239 | class CXX11<string namespace, string name, int version = 1> |
| 240 | : Spelling<name, "CXX11"> { |
| 241 | string Namespace = namespace; |
| 242 | int Version = version; |
| 243 | } |
| 244 | class C2x<string namespace, string name> : Spelling<name, "C2x"> { |
| 245 | string Namespace = namespace; |
| 246 | } |
| 247 | |
| 248 | class Keyword<string name> : Spelling<name, "Keyword">; |
| 249 | class Pragma<string namespace, string name> : Spelling<name, "Pragma"> { |
| 250 | string Namespace = namespace; |
| 251 | } |
| 252 | |
| 253 | // The GCC spelling implies GNU<name> and CXX11<"gnu", name> and also sets |
| 254 | // KnownToGCC to 1. This spelling should be used for any GCC-compatible |
| 255 | // attributes. |
| 256 | class GCC<string name> : Spelling<name, "GCC"> { |
| 257 | let KnownToGCC = 1; |
| 258 | } |
| 259 | |
| 260 | // The Clang spelling implies GNU<name>, CXX11<"clang", name>, and optionally, |
| 261 | // C2x<"clang", name>. This spelling should be used for any Clang-specific |
| 262 | // attributes. |
| 263 | class Clang<string name, bit allowInC = 1> : Spelling<name, "Clang"> { |
| 264 | bit AllowInC = allowInC; |
| 265 | } |
| 266 | |
| 267 | class Accessor<string name, list<Spelling> spellings> { |
| 268 | string Name = name; |
| 269 | list<Spelling> Spellings = spellings; |
| 270 | } |
| 271 | |
| 272 | class SubjectDiag<bit warn> { |
| 273 | bit Warn = warn; |
| 274 | } |
| 275 | def WarnDiag : SubjectDiag<1>; |
| 276 | def ErrorDiag : SubjectDiag<0>; |
| 277 | |
| 278 | class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag, |
| 279 | string customDiag = ""> { |
| 280 | list<AttrSubject> Subjects = subjects; |
| 281 | SubjectDiag Diag = diag; |
| 282 | string CustomDiag = customDiag; |
| 283 | } |
| 284 | |
| 285 | class LangOpt<string name, bit negated = 0> { |
| 286 | string Name = name; |
| 287 | bit Negated = negated; |
| 288 | } |
| 289 | def MicrosoftExt : LangOpt<"MicrosoftExt">; |
| 290 | def Borland : LangOpt<"Borland">; |
| 291 | def CUDA : LangOpt<"CUDA">; |
| 292 | def COnly : LangOpt<"CPlusPlus", 1>; |
| 293 | def CPlusPlus : LangOpt<"CPlusPlus">; |
| 294 | def OpenCL : LangOpt<"OpenCL">; |
| 295 | def RenderScript : LangOpt<"RenderScript">; |
| 296 | def ObjC : LangOpt<"ObjC">; |
| 297 | def BlocksSupported : LangOpt<"Blocks">; |
| 298 | def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">; |
| 299 | |
| 300 | // Defines targets for target-specific attributes. Empty lists are unchecked. |
| 301 | class TargetSpec { |
| 302 | // Specifies Architectures for which the target applies, based off the |
| 303 | // ArchType enumeration in Triple.h. |
| 304 | list<string> Arches = []; |
| 305 | // Specifies Operating Systems for which the target applies, based off the |
| 306 | // OSType enumeration in Triple.h |
| 307 | list<string> OSes; |
| 308 | // Specifies the C++ ABIs for which the target applies, based off the |
| 309 | // TargetCXXABI::Kind in TargetCXXABI.h. |
| 310 | list<string> CXXABIs; |
| 311 | // Specifies Object Formats for which the target applies, based off the |
| 312 | // ObjectFormatType enumeration in Triple.h |
| 313 | list<string> ObjectFormats; |
| 314 | } |
| 315 | |
| 316 | class TargetArch<list<string> arches> : TargetSpec { |
| 317 | let Arches = arches; |
| 318 | } |
| 319 | def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; |
| 320 | def TargetAVR : TargetArch<["avr"]>; |
| 321 | def TargetMips32 : TargetArch<["mips", "mipsel"]>; |
| 322 | def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>; |
| 323 | def TargetMSP430 : TargetArch<["msp430"]>; |
| 324 | def TargetRISCV : TargetArch<["riscv32", "riscv64"]>; |
| 325 | def TargetX86 : TargetArch<["x86"]>; |
| 326 | def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; |
| 327 | def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>; |
| 328 | def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { |
| 329 | let OSes = ["Win32"]; |
| 330 | } |
| 331 | def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { |
| 332 | let CXXABIs = ["Microsoft"]; |
| 333 | } |
| 334 | def TargetELF : TargetSpec { |
| 335 | let ObjectFormats = ["ELF"]; |
| 336 | } |
| 337 | |
| 338 | // Attribute subject match rules that are used for #pragma clang attribute. |
| 339 | // |
| 340 | // A instance of AttrSubjectMatcherRule represents an individual match rule. |
| 341 | // An individual match rule can correspond to a number of different attribute |
| 342 | // subjects, e.g. "record" matching rule corresponds to the Record and |
| 343 | // CXXRecord attribute subjects. |
| 344 | // |
| 345 | // Match rules are used in the subject list of the #pragma clang attribute. |
| 346 | // Match rules can have sub-match rules that are instances of |
| 347 | // AttrSubjectMatcherSubRule. A sub-match rule can correspond to a number |
| 348 | // of different attribute subjects, and it can have a negated spelling as well. |
| 349 | // For example, "variable(unless(is_parameter))" matching rule corresponds to |
| 350 | // the NonParmVar attribute subject. |
| 351 | class AttrSubjectMatcherSubRule<string name, list<AttrSubject> subjects, |
| 352 | bit negated = 0> { |
| 353 | string Name = name; |
| 354 | list<AttrSubject> Subjects = subjects; |
| 355 | bit Negated = negated; |
| 356 | // Lists language options, one of which is required to be true for the |
| 357 | // attribute to be applicable. If empty, the language options are taken |
| 358 | // from the parent matcher rule. |
| 359 | list<LangOpt> LangOpts = []; |
| 360 | } |
| 361 | class AttrSubjectMatcherRule<string name, list<AttrSubject> subjects, |
| 362 | list<AttrSubjectMatcherSubRule> subrules = []> { |
| 363 | string Name = name; |
| 364 | list<AttrSubject> Subjects = subjects; |
| 365 | list<AttrSubjectMatcherSubRule> Constraints = subrules; |
| 366 | // Lists language options, one of which is required to be true for the |
| 367 | // attribute to be applicable. If empty, no language options are required. |
| 368 | list<LangOpt> LangOpts = []; |
| 369 | } |
| 370 | |
| 371 | // function(is_member) |
| 372 | def SubRuleForCXXMethod : AttrSubjectMatcherSubRule<"is_member", [CXXMethod]> { |
| 373 | let LangOpts = [CPlusPlus]; |
| 374 | } |
| 375 | def SubjectMatcherForFunction : AttrSubjectMatcherRule<"function", [Function], [ |
| 376 | SubRuleForCXXMethod |
| 377 | ]>; |
| 378 | // hasType is abstract, it should be used with one of the sub-rules. |
| 379 | def SubjectMatcherForType : AttrSubjectMatcherRule<"hasType", [], [ |
| 380 | AttrSubjectMatcherSubRule<"functionType", [FunctionLike]> |
| 381 | |
| 382 | // FIXME: There's a matcher ambiguity with objc methods and blocks since |
| 383 | // functionType excludes them but functionProtoType includes them. |
| 384 | // AttrSubjectMatcherSubRule<"functionProtoType", [HasFunctionProto]> |
| 385 | ]>; |
| 386 | def SubjectMatcherForTypedef : AttrSubjectMatcherRule<"type_alias", |
| 387 | [TypedefName]>; |
| 388 | def SubjectMatcherForRecord : AttrSubjectMatcherRule<"record", [Record, |
| 389 | CXXRecord], [ |
| 390 | // unless(is_union) |
| 391 | AttrSubjectMatcherSubRule<"is_union", [Struct], 1> |
| 392 | ]>; |
| 393 | def SubjectMatcherForEnum : AttrSubjectMatcherRule<"enum", [Enum]>; |
| 394 | def SubjectMatcherForEnumConstant : AttrSubjectMatcherRule<"enum_constant", |
| 395 | [EnumConstant]>; |
| 396 | def SubjectMatcherForVar : AttrSubjectMatcherRule<"variable", [Var], [ |
| 397 | AttrSubjectMatcherSubRule<"is_thread_local", [TLSVar]>, |
| 398 | AttrSubjectMatcherSubRule<"is_global", [GlobalVar]>, |
| 399 | AttrSubjectMatcherSubRule<"is_parameter", [ParmVar]>, |
| 400 | // unless(is_parameter) |
| 401 | AttrSubjectMatcherSubRule<"is_parameter", [NonParmVar], 1> |
| 402 | ]>; |
| 403 | def SubjectMatcherForField : AttrSubjectMatcherRule<"field", [Field]>; |
| 404 | def SubjectMatcherForNamespace : AttrSubjectMatcherRule<"namespace", |
| 405 | [Namespace]> { |
| 406 | let LangOpts = [CPlusPlus]; |
| 407 | } |
| 408 | def SubjectMatcherForObjCInterface : AttrSubjectMatcherRule<"objc_interface", |
| 409 | [ObjCInterface]> { |
| 410 | let LangOpts = [ObjC]; |
| 411 | } |
| 412 | def SubjectMatcherForObjCProtocol : AttrSubjectMatcherRule<"objc_protocol", |
| 413 | [ObjCProtocol]> { |
| 414 | let LangOpts = [ObjC]; |
| 415 | } |
| 416 | def SubjectMatcherForObjCCategory : AttrSubjectMatcherRule<"objc_category", |
| 417 | [ObjCCategory]> { |
| 418 | let LangOpts = [ObjC]; |
| 419 | } |
| 420 | def SubjectMatcherForObjCMethod : AttrSubjectMatcherRule<"objc_method", |
| 421 | [ObjCMethod], [ |
| 422 | AttrSubjectMatcherSubRule<"is_instance", [ObjCInstanceMethod]> |
| 423 | ]> { |
| 424 | let LangOpts = [ObjC]; |
| 425 | } |
| 426 | def SubjectMatcherForObjCProperty : AttrSubjectMatcherRule<"objc_property", |
| 427 | [ObjCProperty]> { |
| 428 | let LangOpts = [ObjC]; |
| 429 | } |
| 430 | def SubjectMatcherForBlock : AttrSubjectMatcherRule<"block", [Block]> { |
| 431 | let LangOpts = [BlocksSupported]; |
| 432 | } |
| 433 | |
| 434 | // Aggregate attribute subject match rules are abstract match rules that can't |
| 435 | // be used directly in #pragma clang attribute. Instead, users have to use |
| 436 | // subject match rules that correspond to attribute subjects that derive from |
| 437 | // the specified subject. |
| 438 | class AttrSubjectMatcherAggregateRule<AttrSubject subject> { |
| 439 | AttrSubject Subject = subject; |
| 440 | } |
| 441 | |
| 442 | def SubjectMatcherForNamed : AttrSubjectMatcherAggregateRule<Named>; |
| 443 | |
| 444 | class Attr { |
| 445 | // The various ways in which an attribute can be spelled in source |
| 446 | list<Spelling> Spellings; |
| 447 | // The things to which an attribute can appertain |
| 448 | SubjectList Subjects; |
| 449 | // The arguments allowed on an attribute |
| 450 | list<Argument> Args = []; |
| 451 | // Accessors which should be generated for the attribute. |
| 452 | list<Accessor> Accessors = []; |
| 453 | // Set to true for attributes with arguments which require delayed parsing. |
| 454 | bit LateParsed = 0; |
| 455 | // Set to false to prevent an attribute from being propagated from a template |
| 456 | // to the instantiation. |
| 457 | bit Clone = 1; |
| 458 | // Set to true for attributes which must be instantiated within templates |
| 459 | bit TemplateDependent = 0; |
| 460 | // Set to true for attributes that have a corresponding AST node. |
| 461 | bit ASTNode = 1; |
| 462 | // Set to true for attributes which have handler in Sema. |
| 463 | bit SemaHandler = 1; |
| 464 | // Set to true for attributes that are completely ignored. |
| 465 | bit Ignored = 0; |
| 466 | // Set to true if the attribute's parsing does not match its semantic |
| 467 | // content. Eg) It parses 3 args, but semantically takes 4 args. Opts out of |
| 468 | // common attribute error checking. |
| 469 | bit HasCustomParsing = 0; |
| 470 | // Set to true if all of the attribute's arguments should be parsed in an |
| 471 | // unevaluated context. |
| 472 | bit ParseArgumentsAsUnevaluated = 0; |
| 473 | // Set to true if this attribute meaningful when applied to or inherited |
| 474 | // in a class template definition. |
| 475 | bit MeaningfulToClassTemplateDefinition = 0; |
| 476 | // Set to true if this attribute can be used with '#pragma clang attribute'. |
| 477 | // By default, an attribute is supported by the '#pragma clang attribute' |
| 478 | // only when: |
| 479 | // - It has a subject list whose subjects can be represented using subject |
| 480 | // match rules. |
| 481 | // - It has GNU/CXX11 spelling and doesn't require delayed parsing. |
| 482 | bit PragmaAttributeSupport; |
| 483 | // Lists language options, one of which is required to be true for the |
| 484 | // attribute to be applicable. If empty, no language options are required. |
| 485 | list<LangOpt> LangOpts = []; |
| 486 | // Any additional text that should be included verbatim in the class. |
| 487 | // Note: Any additional data members will leak and should be constructed |
| 488 | // externally on the ASTContext. |
| 489 | code AdditionalMembers = [{}]; |
| 490 | // Any documentation that should be associated with the attribute. Since an |
| 491 | // attribute may be documented under multiple categories, more than one |
| 492 | // Documentation entry may be listed. |
| 493 | list<Documentation> Documentation; |
| 494 | } |
| 495 | |
| 496 | /// A type attribute is not processed on a declaration or a statement. |
| 497 | class TypeAttr : Attr; |
| 498 | |
| 499 | /// A stmt attribute is not processed on a declaration or a type. |
| 500 | class StmtAttr : Attr; |
| 501 | |
| 502 | /// An inheritable attribute is inherited by later redeclarations. |
| 503 | class InheritableAttr : Attr { |
| 504 | // Set to true if this attribute can be duplicated on a subject when inheriting |
| 505 | // attributes from prior declarations. |
| 506 | bit InheritEvenIfAlreadyPresent = 0; |
| 507 | } |
| 508 | |
| 509 | /// Some attributes, like calling conventions, can appear in either the |
| 510 | /// declaration or the type position. These attributes are morally type |
| 511 | /// attributes, but have historically been written on declarations. |
| 512 | class DeclOrTypeAttr : InheritableAttr; |
| 513 | |
| 514 | /// A target-specific attribute. This class is meant to be used as a mixin |
| 515 | /// with InheritableAttr or Attr depending on the attribute's needs. |
| 516 | class TargetSpecificAttr<TargetSpec target> { |
| 517 | TargetSpec Target = target; |
| 518 | // Attributes are generally required to have unique spellings for their names |
| 519 | // so that the parser can determine what kind of attribute it has parsed. |
| 520 | // However, target-specific attributes are special in that the attribute only |
| 521 | // "exists" for a given target. So two target-specific attributes can share |
| 522 | // the same name when they exist in different targets. To support this, a |
| 523 | // Kind can be explicitly specified for a target-specific attribute. This |
| 524 | // corresponds to the ParsedAttr::AT_* enum that is generated and it |
| 525 | // should contain a shared value between the attributes. |
| 526 | // |
| 527 | // Target-specific attributes which use this feature should ensure that the |
| 528 | // spellings match exactly between the attributes, and if the arguments or |
| 529 | // subjects differ, should specify HasCustomParsing = 1 and implement their |
| 530 | // own parsing and semantic handling requirements as-needed. |
| 531 | string ParseKind; |
| 532 | } |
| 533 | |
| 534 | /// An inheritable parameter attribute is inherited by later |
| 535 | /// redeclarations, even when it's written on a parameter. |
| 536 | class InheritableParamAttr : InheritableAttr; |
| 537 | |
| 538 | /// An attribute which changes the ABI rules for a specific parameter. |
| 539 | class ParameterABIAttr : InheritableParamAttr { |
| 540 | let Subjects = SubjectList<[ParmVar]>; |
| 541 | } |
| 542 | |
| 543 | /// An ignored attribute, which we parse but discard with no checking. |
| 544 | class IgnoredAttr : Attr { |
| 545 | let Ignored = 1; |
| 546 | let ASTNode = 0; |
| 547 | let SemaHandler = 0; |
| 548 | let Documentation = [Undocumented]; |
| 549 | } |
| 550 | |
| 551 | // |
| 552 | // Attributes begin here |
| 553 | // |
| 554 | |
| 555 | def AbiTag : Attr { |
| 556 | let Spellings = [GCC<"abi_tag">]; |
| 557 | let Args = [VariadicStringArgument<"Tags">]; |
| 558 | let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag>; |
| 559 | let MeaningfulToClassTemplateDefinition = 1; |
| 560 | let Documentation = [AbiTagsDocs]; |
| 561 | } |
| 562 | |
| 563 | def AddressSpace : TypeAttr { |
| 564 | let Spellings = [Clang<"address_space">]; |
| 565 | let Args = [IntArgument<"AddressSpace">]; |
| 566 | let Documentation = [Undocumented]; |
| 567 | } |
| 568 | |
| 569 | def Alias : Attr { |
| 570 | let Spellings = [GCC<"alias">]; |
| 571 | let Args = [StringArgument<"Aliasee">]; |
| 572 | let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>; |
| 573 | let Documentation = [Undocumented]; |
| 574 | } |
| 575 | |
| 576 | def Aligned : InheritableAttr { |
| 577 | let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">, |
| 578 | Keyword<"_Alignas">]; |
| 579 | let Args = [AlignedArgument<"Alignment", 1>]; |
| 580 | let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>, |
| 581 | Accessor<"isC11", [Keyword<"_Alignas">]>, |
| 582 | Accessor<"isAlignas", [Keyword<"alignas">, |
| 583 | Keyword<"_Alignas">]>, |
| 584 | Accessor<"isDeclspec",[Declspec<"align">]>]; |
| 585 | let Documentation = [Undocumented]; |
| 586 | } |
| 587 | |
| 588 | def AlignValue : Attr { |
| 589 | let Spellings = [ |
| 590 | // Unfortunately, this is semantically an assertion, not a directive |
| 591 | // (something else must ensure the alignment), so aligned_value is a |
| 592 | // probably a better name. We might want to add an aligned_value spelling in |
| 593 | // the future (and a corresponding C++ attribute), but this can be done |
| 594 | // later once we decide if we also want them to have slightly-different |
| 595 | // semantics than Intel's align_value. |
| 596 | // |
| 597 | // Does not get a [[]] spelling because the attribute is not exposed as such |
| 598 | // by Intel. |
| 599 | GNU<"align_value"> |
| 600 | // Intel's compiler on Windows also supports: |
| 601 | // , Declspec<"align_value"> |
| 602 | ]; |
| 603 | let Args = [ExprArgument<"Alignment">]; |
| 604 | let Subjects = SubjectList<[Var, TypedefName]>; |
| 605 | let Documentation = [AlignValueDocs]; |
| 606 | } |
| 607 | |
| 608 | def AlignMac68k : InheritableAttr { |
| 609 | // This attribute has no spellings as it is only ever created implicitly. |
| 610 | let Spellings = []; |
| 611 | let SemaHandler = 0; |
| 612 | let Documentation = [Undocumented]; |
| 613 | } |
| 614 | |
| 615 | def AlwaysInline : InheritableAttr { |
| 616 | let Spellings = [GCC<"always_inline">, Keyword<"__forceinline">]; |
| 617 | let Subjects = SubjectList<[Function]>; |
| 618 | let Documentation = [Undocumented]; |
| 619 | } |
| 620 | |
| 621 | def Artificial : InheritableAttr { |
| 622 | let Spellings = [GCC<"artificial">]; |
| 623 | let Subjects = SubjectList<[InlineFunction], WarnDiag>; |
| 624 | let Documentation = [ArtificialDocs]; |
| 625 | } |
| 626 | |
| 627 | def XRayInstrument : InheritableAttr { |
| 628 | let Spellings = [Clang<"xray_always_instrument">, |
| 629 | Clang<"xray_never_instrument">]; |
| 630 | let Subjects = SubjectList<[Function, ObjCMethod]>; |
| 631 | let Accessors = [Accessor<"alwaysXRayInstrument", |
| 632 | [Clang<"xray_always_instrument">]>, |
| 633 | Accessor<"neverXRayInstrument", |
| 634 | [Clang<"xray_never_instrument">]>]; |
| 635 | let Documentation = [XRayDocs]; |
| 636 | } |
| 637 | |
| 638 | def XRayLogArgs : InheritableAttr { |
| 639 | let Spellings = [Clang<"xray_log_args">]; |
| 640 | let Subjects = SubjectList<[Function, ObjCMethod]>; |
| 641 | // This argument is a count not an index, so it has the same encoding (base |
| 642 | // 1 including C++ implicit this parameter) at the source and LLVM levels of |
| 643 | // representation, so ParamIdxArgument is inappropriate. It is never used |
| 644 | // at the AST level of representation, so it never needs to be adjusted not |
| 645 | // to include any C++ implicit this parameter. Thus, we just store it and |
| 646 | // use it as an unsigned that never needs adjustment. |
| 647 | let Args = [UnsignedArgument<"ArgumentCount">]; |
| 648 | let Documentation = [XRayDocs]; |
| 649 | } |
| 650 | |
| 651 | def TLSModel : InheritableAttr { |
| 652 | let Spellings = [GCC<"tls_model">]; |
| 653 | let Subjects = SubjectList<[TLSVar], ErrorDiag>; |
| 654 | let Args = [StringArgument<"Model">]; |
| 655 | let Documentation = [TLSModelDocs]; |
| 656 | } |
| 657 | |
| 658 | def AnalyzerNoReturn : InheritableAttr { |
| 659 | // TODO: should this attribute be exposed with a [[]] spelling under the clang |
| 660 | // vendor namespace, or should it use a vendor namespace specific to the |
| 661 | // analyzer? |
| 662 | let Spellings = [GNU<"analyzer_noreturn">]; |
| 663 | // TODO: Add subject list. |
| 664 | let Documentation = [Undocumented]; |
| 665 | } |
| 666 | |
| 667 | def Annotate : InheritableParamAttr { |
| 668 | let Spellings = [Clang<"annotate">]; |
| 669 | let Args = [StringArgument<"Annotation">]; |
| 670 | // Ensure that the annotate attribute can be used with |
| 671 | // '#pragma clang attribute' even though it has no subject list. |
| 672 | let PragmaAttributeSupport = 1; |
| 673 | let Documentation = [Undocumented]; |
| 674 | } |
| 675 | |
| 676 | def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> { |
| 677 | // NOTE: If you add any additional spellings, MSP430Interrupt's, |
| 678 | // MipsInterrupt's and AnyX86Interrupt's spellings must match. |
| 679 | let Spellings = [GCC<"interrupt">]; |
| 680 | let Args = [EnumArgument<"Interrupt", "InterruptType", |
| 681 | ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], |
| 682 | ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"], |
| 683 | 1>]; |
| 684 | let ParseKind = "Interrupt"; |
| 685 | let HasCustomParsing = 1; |
| 686 | let Documentation = [ARMInterruptDocs]; |
| 687 | } |
| 688 | |
| 689 | def AVRInterrupt : InheritableAttr, TargetSpecificAttr<TargetAVR> { |
| 690 | let Spellings = [GCC<"interrupt">]; |
| 691 | let Subjects = SubjectList<[Function]>; |
| 692 | let ParseKind = "Interrupt"; |
| 693 | let Documentation = [AVRInterruptDocs]; |
| 694 | } |
| 695 | |
| 696 | def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> { |
| 697 | let Spellings = [GCC<"signal">]; |
| 698 | let Subjects = SubjectList<[Function]>; |
| 699 | let Documentation = [AVRSignalDocs]; |
| 700 | } |
| 701 | |
| 702 | def AsmLabel : InheritableAttr { |
| 703 | let Spellings = [Keyword<"asm">, Keyword<"__asm__">]; |
| 704 | let Args = [StringArgument<"Label">]; |
| 705 | let SemaHandler = 0; |
| 706 | let Documentation = [Undocumented]; |
| 707 | } |
| 708 | |
| 709 | def Availability : InheritableAttr { |
| 710 | let Spellings = [Clang<"availability">]; |
| 711 | let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">, |
| 712 | VersionArgument<"deprecated">, VersionArgument<"obsoleted">, |
| 713 | BoolArgument<"unavailable">, StringArgument<"message">, |
| 714 | BoolArgument<"strict">, StringArgument<"replacement">, |
| 715 | IntArgument<"priority">]; |
| 716 | let AdditionalMembers = |
| 717 | [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { |
| 718 | return llvm::StringSwitch<llvm::StringRef>(Platform) |
| 719 | .Case("android", "Android") |
| 720 | .Case("ios", "iOS") |
| 721 | .Case("macos", "macOS") |
| 722 | .Case("tvos", "tvOS") |
| 723 | .Case("watchos", "watchOS") |
| 724 | .Case("ios_app_extension", "iOS (App Extension)") |
| 725 | .Case("macos_app_extension", "macOS (App Extension)") |
| 726 | .Case("tvos_app_extension", "tvOS (App Extension)") |
| 727 | .Case("watchos_app_extension", "watchOS (App Extension)") |
| 728 | .Case("swift", "Swift") |
| 729 | .Default(llvm::StringRef()); |
| 730 | } |
| 731 | static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) { |
| 732 | return llvm::StringSwitch<llvm::StringRef>(Platform) |
| 733 | .Case("ios", "iOS") |
| 734 | .Case("macos", "macOS") |
| 735 | .Case("tvos", "tvOS") |
| 736 | .Case("watchos", "watchOS") |
| 737 | .Case("ios_app_extension", "iOSApplicationExtension") |
| 738 | .Case("macos_app_extension", "macOSApplicationExtension") |
| 739 | .Case("tvos_app_extension", "tvOSApplicationExtension") |
| 740 | .Case("watchos_app_extension", "watchOSApplicationExtension") |
| 741 | .Default(Platform); |
| 742 | } |
| 743 | static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) { |
| 744 | return llvm::StringSwitch<llvm::StringRef>(Platform) |
| 745 | .Case("iOS", "ios") |
| 746 | .Case("macOS", "macos") |
| 747 | .Case("tvOS", "tvos") |
| 748 | .Case("watchOS", "watchos") |
| 749 | .Case("iOSApplicationExtension", "ios_app_extension") |
| 750 | .Case("macOSApplicationExtension", "macos_app_extension") |
| 751 | .Case("tvOSApplicationExtension", "tvos_app_extension") |
| 752 | .Case("watchOSApplicationExtension", "watchos_app_extension") |
| 753 | .Default(Platform); |
| 754 | } }]; |
| 755 | let HasCustomParsing = 1; |
| 756 | let InheritEvenIfAlreadyPresent = 1; |
| 757 | let Subjects = SubjectList<[Named]>; |
| 758 | let Documentation = [AvailabilityDocs]; |
| 759 | } |
| 760 | |
| 761 | def ExternalSourceSymbol : InheritableAttr { |
| 762 | let Spellings = [Clang<"external_source_symbol">]; |
| 763 | let Args = [StringArgument<"language", 1>, |
| 764 | StringArgument<"definedIn", 1>, |
| 765 | BoolArgument<"generatedDeclaration", 1>]; |
| 766 | let HasCustomParsing = 1; |
| 767 | let Subjects = SubjectList<[Named]>; |
| 768 | let Documentation = [ExternalSourceSymbolDocs]; |
| 769 | } |
| 770 | |
| 771 | def Blocks : InheritableAttr { |
| 772 | let Spellings = [Clang<"blocks">]; |
| 773 | let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>]; |
| 774 | let Documentation = [Undocumented]; |
| 775 | } |
| 776 | |
| 777 | def Bounded : IgnoredAttr { |
| 778 | // Does not have a [[]] spelling because the attribute is ignored. |
| 779 | let Spellings = [GNU<"bounded">]; |
| 780 | } |
| 781 | |
| 782 | def CarriesDependency : InheritableParamAttr { |
| 783 | let Spellings = [GNU<"carries_dependency">, |
| 784 | CXX11<"","carries_dependency", 200809>]; |
| 785 | let Subjects = SubjectList<[ParmVar, ObjCMethod, Function], ErrorDiag>; |
| 786 | let Documentation = [CarriesDependencyDocs]; |
| 787 | } |
| 788 | |
| 789 | def CDecl : DeclOrTypeAttr { |
| 790 | let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">]; |
| 791 | // let Subjects = [Function, ObjCMethod]; |
| 792 | let Documentation = [Undocumented]; |
| 793 | } |
| 794 | |
| 795 | // cf_audited_transfer indicates that the given function has been |
| 796 | // audited and has been marked with the appropriate cf_consumed and |
| 797 | // cf_returns_retained attributes. It is generally applied by |
| 798 | // '#pragma clang arc_cf_code_audited' rather than explicitly. |
| 799 | def CFAuditedTransfer : InheritableAttr { |
| 800 | let Spellings = [Clang<"cf_audited_transfer">]; |
| 801 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 802 | let Documentation = [Undocumented]; |
| 803 | } |
| 804 | |
| 805 | // cf_unknown_transfer is an explicit opt-out of cf_audited_transfer. |
| 806 | // It indicates that the function has unknown or unautomatable |
| 807 | // transfer semantics. |
| 808 | def CFUnknownTransfer : InheritableAttr { |
| 809 | let Spellings = [Clang<"cf_unknown_transfer">]; |
| 810 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 811 | let Documentation = [Undocumented]; |
| 812 | } |
| 813 | |
| 814 | def CFReturnsRetained : InheritableAttr { |
| 815 | let Spellings = [Clang<"cf_returns_retained">]; |
| 816 | // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; |
| 817 | let Documentation = [RetainBehaviorDocs]; |
| 818 | } |
| 819 | |
| 820 | def CFReturnsNotRetained : InheritableAttr { |
| 821 | let Spellings = [Clang<"cf_returns_not_retained">]; |
| 822 | // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; |
| 823 | let Documentation = [RetainBehaviorDocs]; |
| 824 | } |
| 825 | |
| 826 | def CFConsumed : InheritableParamAttr { |
| 827 | let Spellings = [Clang<"cf_consumed">]; |
| 828 | let Subjects = SubjectList<[ParmVar]>; |
| 829 | let Documentation = [RetainBehaviorDocs]; |
| 830 | } |
| 831 | |
| 832 | // OSObject-based attributes. |
| 833 | def OSConsumed : InheritableParamAttr { |
| 834 | let Spellings = [Clang<"os_consumed">]; |
| 835 | let Subjects = SubjectList<[ParmVar]>; |
| 836 | let Documentation = [RetainBehaviorDocs]; |
| 837 | } |
| 838 | |
| 839 | def OSReturnsRetained : InheritableAttr { |
| 840 | let Spellings = [Clang<"os_returns_retained">]; |
| 841 | let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty, ParmVar]>; |
| 842 | let Documentation = [RetainBehaviorDocs]; |
| 843 | } |
| 844 | |
| 845 | def OSReturnsNotRetained : InheritableAttr { |
| 846 | let Spellings = [Clang<"os_returns_not_retained">]; |
| 847 | let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty, ParmVar]>; |
| 848 | let Documentation = [RetainBehaviorDocs]; |
| 849 | } |
| 850 | |
| 851 | def OSReturnsRetainedOnZero : InheritableAttr { |
| 852 | let Spellings = [Clang<"os_returns_retained_on_zero">]; |
| 853 | let Subjects = SubjectList<[ParmVar]>; |
| 854 | let Documentation = [RetainBehaviorDocs]; |
| 855 | } |
| 856 | |
| 857 | def OSReturnsRetainedOnNonZero : InheritableAttr { |
| 858 | let Spellings = [Clang<"os_returns_retained_on_non_zero">]; |
| 859 | let Subjects = SubjectList<[ParmVar]>; |
| 860 | let Documentation = [RetainBehaviorDocs]; |
| 861 | } |
| 862 | |
| 863 | def OSConsumesThis : InheritableAttr { |
| 864 | let Spellings = [Clang<"os_consumes_this">]; |
| 865 | let Subjects = SubjectList<[NonStaticCXXMethod]>; |
| 866 | let Documentation = [RetainBehaviorDocs]; |
| 867 | } |
| 868 | |
| 869 | def Cleanup : InheritableAttr { |
| 870 | let Spellings = [GCC<"cleanup">]; |
| 871 | let Args = [FunctionArgument<"FunctionDecl">]; |
| 872 | let Subjects = SubjectList<[LocalVar]>; |
| 873 | let Documentation = [Undocumented]; |
| 874 | } |
| 875 | |
| 876 | def Cold : InheritableAttr { |
| 877 | let Spellings = [GCC<"cold">]; |
| 878 | let Subjects = SubjectList<[Function]>; |
| 879 | let Documentation = [Undocumented]; |
| 880 | } |
| 881 | |
| 882 | def Common : InheritableAttr { |
| 883 | let Spellings = [GCC<"common">]; |
| 884 | let Subjects = SubjectList<[Var]>; |
| 885 | let Documentation = [Undocumented]; |
| 886 | } |
| 887 | |
| 888 | def Const : InheritableAttr { |
| 889 | let Spellings = [GCC<"const">, GCC<"__const">]; |
| 890 | let Documentation = [Undocumented]; |
| 891 | } |
| 892 | |
| 893 | def Constructor : InheritableAttr { |
| 894 | let Spellings = [GCC<"constructor">]; |
| 895 | let Args = [DefaultIntArgument<"Priority", 65535>]; |
| 896 | let Subjects = SubjectList<[Function]>; |
| 897 | let Documentation = [Undocumented]; |
| 898 | } |
| 899 | |
| 900 | def CPUSpecific : InheritableAttr { |
| 901 | let Spellings = [Clang<"cpu_specific">, Declspec<"cpu_specific">]; |
| 902 | let Args = [VariadicIdentifierArgument<"Cpus">]; |
| 903 | let Subjects = SubjectList<[Function]>; |
| 904 | let Documentation = [CPUSpecificCPUDispatchDocs]; |
| 905 | let AdditionalMembers = [{ |
| 906 | IdentifierInfo *getCPUName(unsigned Index) const { |
| 907 | return *(cpus_begin() + Index); |
| 908 | } |
| 909 | }]; |
| 910 | } |
| 911 | |
| 912 | def CPUDispatch : InheritableAttr { |
| 913 | let Spellings = [Clang<"cpu_dispatch">, Declspec<"cpu_dispatch">]; |
| 914 | let Args = [VariadicIdentifierArgument<"Cpus">]; |
| 915 | let Subjects = SubjectList<[Function]>; |
| 916 | let Documentation = [CPUSpecificCPUDispatchDocs]; |
| 917 | } |
| 918 | |
| 919 | // CUDA attributes are spelled __attribute__((attr)) or __declspec(__attr__), |
| 920 | // and they do not receive a [[]] spelling. |
| 921 | def CUDAConstant : InheritableAttr { |
| 922 | let Spellings = [GNU<"constant">, Declspec<"__constant__">]; |
| 923 | let Subjects = SubjectList<[Var]>; |
| 924 | let LangOpts = [CUDA]; |
| 925 | let Documentation = [Undocumented]; |
| 926 | } |
| 927 | |
| 928 | def CUDACudartBuiltin : IgnoredAttr { |
| 929 | let Spellings = [GNU<"cudart_builtin">, Declspec<"__cudart_builtin__">]; |
| 930 | let LangOpts = [CUDA]; |
| 931 | } |
| 932 | |
| 933 | def CUDADevice : InheritableAttr { |
| 934 | let Spellings = [GNU<"device">, Declspec<"__device__">]; |
| 935 | let Subjects = SubjectList<[Function, Var]>; |
| 936 | let LangOpts = [CUDA]; |
| 937 | let Documentation = [Undocumented]; |
| 938 | } |
| 939 | |
| 940 | def CUDADeviceBuiltin : IgnoredAttr { |
| 941 | let Spellings = [GNU<"device_builtin">, Declspec<"__device_builtin__">]; |
| 942 | let LangOpts = [CUDA]; |
| 943 | } |
| 944 | |
| 945 | def CUDADeviceBuiltinSurfaceType : IgnoredAttr { |
| 946 | let Spellings = [GNU<"device_builtin_surface_type">, |
| 947 | Declspec<"__device_builtin_surface_type__">]; |
| 948 | let LangOpts = [CUDA]; |
| 949 | } |
| 950 | |
| 951 | def CUDADeviceBuiltinTextureType : IgnoredAttr { |
| 952 | let Spellings = [GNU<"device_builtin_texture_type">, |
| 953 | Declspec<"__device_builtin_texture_type__">]; |
| 954 | let LangOpts = [CUDA]; |
| 955 | } |
| 956 | |
| 957 | def CUDAGlobal : InheritableAttr { |
| 958 | let Spellings = [GNU<"global">, Declspec<"__global__">]; |
| 959 | let Subjects = SubjectList<[Function]>; |
| 960 | let LangOpts = [CUDA]; |
| 961 | let Documentation = [Undocumented]; |
| 962 | } |
| 963 | |
| 964 | def CUDAHost : InheritableAttr { |
| 965 | let Spellings = [GNU<"host">, Declspec<"__host__">]; |
| 966 | let Subjects = SubjectList<[Function]>; |
| 967 | let LangOpts = [CUDA]; |
| 968 | let Documentation = [Undocumented]; |
| 969 | } |
| 970 | |
| 971 | def CUDAInvalidTarget : InheritableAttr { |
| 972 | let Spellings = []; |
| 973 | let Subjects = SubjectList<[Function]>; |
| 974 | let LangOpts = [CUDA]; |
| 975 | let Documentation = [Undocumented]; |
| 976 | } |
| 977 | |
| 978 | def CUDALaunchBounds : InheritableAttr { |
| 979 | let Spellings = [GNU<"launch_bounds">, Declspec<"__launch_bounds__">]; |
| 980 | let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>]; |
| 981 | let LangOpts = [CUDA]; |
| 982 | let Subjects = SubjectList<[ObjCMethod, FunctionLike]>; |
| 983 | // An AST node is created for this attribute, but is not used by other parts |
| 984 | // of the compiler. However, this node needs to exist in the AST because |
| 985 | // non-LLVM backends may be relying on the attribute's presence. |
| 986 | let Documentation = [Undocumented]; |
| 987 | } |
| 988 | |
| 989 | def CUDAShared : InheritableAttr { |
| 990 | let Spellings = [GNU<"shared">, Declspec<"__shared__">]; |
| 991 | let Subjects = SubjectList<[Var]>; |
| 992 | let LangOpts = [CUDA]; |
| 993 | let Documentation = [Undocumented]; |
| 994 | } |
| 995 | |
| 996 | def C11NoReturn : InheritableAttr { |
| 997 | let Spellings = [Keyword<"_Noreturn">]; |
| 998 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 999 | let SemaHandler = 0; |
| 1000 | let Documentation = [C11NoReturnDocs]; |
| 1001 | } |
| 1002 | |
| 1003 | def CXX11NoReturn : InheritableAttr { |
| 1004 | let Spellings = [CXX11<"", "noreturn", 200809>]; |
| 1005 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1006 | let Documentation = [CXX11NoReturnDocs]; |
| 1007 | } |
| 1008 | |
| 1009 | // Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because |
| 1010 | // the specification does not expose them with one currently. |
| 1011 | def OpenCLKernel : InheritableAttr { |
| 1012 | let Spellings = [Keyword<"__kernel">, Keyword<"kernel">]; |
| 1013 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1014 | let Documentation = [Undocumented]; |
| 1015 | } |
| 1016 | |
| 1017 | def OpenCLUnrollHint : InheritableAttr { |
| 1018 | let Spellings = [GNU<"opencl_unroll_hint">]; |
| 1019 | let Args = [UnsignedArgument<"UnrollHint">]; |
| 1020 | let Documentation = [OpenCLUnrollHintDocs]; |
| 1021 | } |
| 1022 | |
| 1023 | def OpenCLIntelReqdSubGroupSize: InheritableAttr { |
| 1024 | let Spellings = [GNU<"intel_reqd_sub_group_size">]; |
| 1025 | let Args = [UnsignedArgument<"SubGroupSize">]; |
| 1026 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1027 | let Documentation = [OpenCLIntelReqdSubGroupSizeDocs]; |
| 1028 | } |
| 1029 | |
| 1030 | // This attribute is both a type attribute, and a declaration attribute (for |
| 1031 | // parameter variables). |
| 1032 | def OpenCLAccess : Attr { |
| 1033 | let Spellings = [Keyword<"__read_only">, Keyword<"read_only">, |
| 1034 | Keyword<"__write_only">, Keyword<"write_only">, |
| 1035 | Keyword<"__read_write">, Keyword<"read_write">]; |
| 1036 | let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag>; |
| 1037 | let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">, |
| 1038 | Keyword<"read_only">]>, |
| 1039 | Accessor<"isReadWrite", [Keyword<"__read_write">, |
| 1040 | Keyword<"read_write">]>, |
| 1041 | Accessor<"isWriteOnly", [Keyword<"__write_only">, |
| 1042 | Keyword<"write_only">]>]; |
| 1043 | let Documentation = [OpenCLAccessDocs]; |
| 1044 | } |
| 1045 | |
| 1046 | def OpenCLPrivateAddressSpace : TypeAttr { |
| 1047 | let Spellings = [Keyword<"__private">, Keyword<"private">]; |
| 1048 | let Documentation = [OpenCLAddressSpacePrivateDocs]; |
| 1049 | } |
| 1050 | |
| 1051 | def OpenCLGlobalAddressSpace : TypeAttr { |
| 1052 | let Spellings = [Keyword<"__global">, Keyword<"global">]; |
| 1053 | let Documentation = [OpenCLAddressSpaceGlobalDocs]; |
| 1054 | } |
| 1055 | |
| 1056 | def OpenCLLocalAddressSpace : TypeAttr { |
| 1057 | let Spellings = [Keyword<"__local">, Keyword<"local">]; |
| 1058 | let Documentation = [OpenCLAddressSpaceLocalDocs]; |
| 1059 | } |
| 1060 | |
| 1061 | def OpenCLConstantAddressSpace : TypeAttr { |
| 1062 | let Spellings = [Keyword<"__constant">, Keyword<"constant">]; |
| 1063 | let Documentation = [OpenCLAddressSpaceConstantDocs]; |
| 1064 | } |
| 1065 | |
| 1066 | def OpenCLGenericAddressSpace : TypeAttr { |
| 1067 | let Spellings = [Keyword<"__generic">, Keyword<"generic">]; |
| 1068 | let Documentation = [OpenCLAddressSpaceGenericDocs]; |
| 1069 | } |
| 1070 | |
| 1071 | def OpenCLNoSVM : Attr { |
| 1072 | let Spellings = [GNU<"nosvm">]; |
| 1073 | let Subjects = SubjectList<[Var]>; |
| 1074 | let Documentation = [OpenCLNoSVMDocs]; |
| 1075 | let LangOpts = [OpenCL]; |
| 1076 | let ASTNode = 0; |
| 1077 | } |
| 1078 | |
| 1079 | def RenderScriptKernel : Attr { |
| 1080 | let Spellings = [GNU<"kernel">]; |
| 1081 | let Subjects = SubjectList<[Function]>; |
| 1082 | let Documentation = [RenderScriptKernelAttributeDocs]; |
| 1083 | let LangOpts = [RenderScript]; |
| 1084 | } |
| 1085 | |
| 1086 | def Deprecated : InheritableAttr { |
| 1087 | let Spellings = [GCC<"deprecated">, Declspec<"deprecated">, |
| 1088 | CXX11<"","deprecated", 201309>, C2x<"", "deprecated">]; |
| 1089 | let Args = [StringArgument<"Message", 1>, |
| 1090 | // An optional string argument that enables us to provide a |
| 1091 | // Fix-It. |
| 1092 | StringArgument<"Replacement", 1>]; |
| 1093 | let MeaningfulToClassTemplateDefinition = 1; |
| 1094 | let Documentation = [DeprecatedDocs]; |
| 1095 | } |
| 1096 | |
| 1097 | def Destructor : InheritableAttr { |
| 1098 | let Spellings = [GCC<"destructor">]; |
| 1099 | let Args = [DefaultIntArgument<"Priority", 65535>]; |
| 1100 | let Subjects = SubjectList<[Function]>; |
| 1101 | let Documentation = [Undocumented]; |
| 1102 | } |
| 1103 | |
| 1104 | def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> { |
| 1105 | let Spellings = [Declspec<"empty_bases">]; |
| 1106 | let Subjects = SubjectList<[CXXRecord]>; |
| 1107 | let Documentation = [EmptyBasesDocs]; |
| 1108 | } |
| 1109 | |
| 1110 | def AllocSize : InheritableAttr { |
| 1111 | let Spellings = [GCC<"alloc_size">]; |
| 1112 | let Subjects = SubjectList<[Function]>; |
| 1113 | let Args = [ParamIdxArgument<"ElemSizeParam">, |
| 1114 | ParamIdxArgument<"NumElemsParam", /*opt*/ 1>]; |
| 1115 | let TemplateDependent = 1; |
| 1116 | let Documentation = [AllocSizeDocs]; |
| 1117 | } |
| 1118 | |
| 1119 | def EnableIf : InheritableAttr { |
| 1120 | // Does not have a [[]] spelling because this attribute requires the ability |
| 1121 | // to parse function arguments but the attribute is not written in the type |
| 1122 | // position. |
| 1123 | let Spellings = [GNU<"enable_if">]; |
| 1124 | let Subjects = SubjectList<[Function]>; |
| 1125 | let Args = [ExprArgument<"Cond">, StringArgument<"Message">]; |
| 1126 | let TemplateDependent = 1; |
| 1127 | let Documentation = [EnableIfDocs]; |
| 1128 | } |
| 1129 | |
| 1130 | def ExtVectorType : Attr { |
| 1131 | // This is an OpenCL-related attribute and does not receive a [[]] spelling. |
| 1132 | let Spellings = [GNU<"ext_vector_type">]; |
| 1133 | // FIXME: This subject list is wrong; this is a type attribute. |
| 1134 | let Subjects = SubjectList<[TypedefName], ErrorDiag>; |
| 1135 | let Args = [ExprArgument<"NumElements">]; |
| 1136 | let ASTNode = 0; |
| 1137 | let Documentation = [Undocumented]; |
| 1138 | // This is a type attribute with an incorrect subject list, so should not be |
| 1139 | // permitted by #pragma clang attribute. |
| 1140 | let PragmaAttributeSupport = 0; |
| 1141 | } |
| 1142 | |
| 1143 | def FallThrough : StmtAttr { |
| 1144 | let Spellings = [CXX11<"", "fallthrough", 201603>, C2x<"", "fallthrough">, |
| 1145 | CXX11<"clang", "fallthrough">]; |
| 1146 | // let Subjects = [NullStmt]; |
| 1147 | let Documentation = [FallthroughDocs]; |
| 1148 | } |
| 1149 | |
| 1150 | def FastCall : DeclOrTypeAttr { |
| 1151 | let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">, |
| 1152 | Keyword<"_fastcall">]; |
| 1153 | // let Subjects = [Function, ObjCMethod]; |
| 1154 | let Documentation = [FastCallDocs]; |
| 1155 | } |
| 1156 | |
| 1157 | def RegCall : DeclOrTypeAttr { |
| 1158 | let Spellings = [GCC<"regcall">, Keyword<"__regcall">]; |
| 1159 | let Documentation = [RegCallDocs]; |
| 1160 | } |
| 1161 | |
| 1162 | def Final : InheritableAttr { |
| 1163 | let Spellings = [Keyword<"final">, Keyword<"sealed">]; |
| 1164 | let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>]; |
| 1165 | let SemaHandler = 0; |
| 1166 | let Documentation = [Undocumented]; |
| 1167 | } |
| 1168 | |
| 1169 | def MinSize : InheritableAttr { |
| 1170 | let Spellings = [Clang<"minsize">]; |
| 1171 | let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>; |
| 1172 | let Documentation = [Undocumented]; |
| 1173 | } |
| 1174 | |
| 1175 | def FlagEnum : InheritableAttr { |
| 1176 | let Spellings = [Clang<"flag_enum">]; |
| 1177 | let Subjects = SubjectList<[Enum]>; |
| 1178 | let Documentation = [FlagEnumDocs]; |
| 1179 | } |
| 1180 | |
| 1181 | def EnumExtensibility : InheritableAttr { |
| 1182 | let Spellings = [Clang<"enum_extensibility">]; |
| 1183 | let Subjects = SubjectList<[Enum]>; |
| 1184 | let Args = [EnumArgument<"Extensibility", "Kind", |
| 1185 | ["closed", "open"], ["Closed", "Open"]>]; |
| 1186 | let Documentation = [EnumExtensibilityDocs]; |
| 1187 | } |
| 1188 | |
| 1189 | def Flatten : InheritableAttr { |
| 1190 | let Spellings = [GCC<"flatten">]; |
| 1191 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1192 | let Documentation = [FlattenDocs]; |
| 1193 | } |
| 1194 | |
| 1195 | def Format : InheritableAttr { |
| 1196 | let Spellings = [GCC<"format">]; |
| 1197 | let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">, |
| 1198 | IntArgument<"FirstArg">]; |
| 1199 | let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto]>; |
| 1200 | let Documentation = [FormatDocs]; |
| 1201 | } |
| 1202 | |
| 1203 | def FormatArg : InheritableAttr { |
| 1204 | let Spellings = [GCC<"format_arg">]; |
| 1205 | let Args = [ParamIdxArgument<"FormatIdx">]; |
| 1206 | let Subjects = SubjectList<[ObjCMethod, HasFunctionProto]>; |
| 1207 | let Documentation = [Undocumented]; |
| 1208 | } |
| 1209 | |
| 1210 | def Callback : InheritableAttr { |
| 1211 | let Spellings = [Clang<"callback">]; |
| 1212 | let Args = [VariadicParamOrParamIdxArgument<"Encoding">]; |
| 1213 | let Subjects = SubjectList<[Function]>; |
| 1214 | let Documentation = [CallbackDocs]; |
| 1215 | } |
| 1216 | |
| 1217 | def GNUInline : InheritableAttr { |
| 1218 | let Spellings = [GCC<"gnu_inline">]; |
| 1219 | let Subjects = SubjectList<[Function]>; |
| 1220 | let Documentation = [GnuInlineDocs]; |
| 1221 | } |
| 1222 | |
| 1223 | def Hot : InheritableAttr { |
| 1224 | let Spellings = [GCC<"hot">]; |
| 1225 | let Subjects = SubjectList<[Function]>; |
| 1226 | // An AST node is created for this attribute, but not actually used beyond |
| 1227 | // semantic checking for mutual exclusion with the Cold attribute. |
| 1228 | let Documentation = [Undocumented]; |
| 1229 | } |
| 1230 | |
| 1231 | def IBAction : InheritableAttr { |
| 1232 | let Spellings = [Clang<"ibaction">]; |
| 1233 | let Subjects = SubjectList<[ObjCInstanceMethod]>; |
| 1234 | // An AST node is created for this attribute, but is not used by other parts |
| 1235 | // of the compiler. However, this node needs to exist in the AST because |
| 1236 | // external tools rely on it. |
| 1237 | let Documentation = [Undocumented]; |
| 1238 | } |
| 1239 | |
| 1240 | def IBOutlet : InheritableAttr { |
| 1241 | let Spellings = [Clang<"iboutlet">]; |
| 1242 | // let Subjects = [ObjCIvar, ObjCProperty]; |
| 1243 | let Documentation = [Undocumented]; |
| 1244 | } |
| 1245 | |
| 1246 | def IBOutletCollection : InheritableAttr { |
| 1247 | let Spellings = [Clang<"iboutletcollection">]; |
| 1248 | let Args = [TypeArgument<"Interface", 1>]; |
| 1249 | // let Subjects = [ObjCIvar, ObjCProperty]; |
| 1250 | let Documentation = [Undocumented]; |
| 1251 | } |
| 1252 | |
| 1253 | def IFunc : Attr, TargetSpecificAttr<TargetELF> { |
| 1254 | let Spellings = [GCC<"ifunc">]; |
| 1255 | let Args = [StringArgument<"Resolver">]; |
| 1256 | let Subjects = SubjectList<[Function]>; |
| 1257 | let Documentation = [IFuncDocs]; |
| 1258 | } |
| 1259 | |
| 1260 | def Restrict : InheritableAttr { |
| 1261 | let Spellings = [Declspec<"restrict">, GCC<"malloc">]; |
| 1262 | let Subjects = SubjectList<[Function]>; |
| 1263 | let Documentation = [Undocumented]; |
| 1264 | } |
| 1265 | |
| 1266 | def LayoutVersion : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> { |
| 1267 | let Spellings = [Declspec<"layout_version">]; |
| 1268 | let Args = [UnsignedArgument<"Version">]; |
| 1269 | let Subjects = SubjectList<[CXXRecord]>; |
| 1270 | let Documentation = [LayoutVersionDocs]; |
| 1271 | } |
| 1272 | |
| 1273 | def LifetimeBound : DeclOrTypeAttr { |
| 1274 | let Spellings = [Clang<"lifetimebound", 0>]; |
| 1275 | let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>; |
| 1276 | let Documentation = [LifetimeBoundDocs]; |
| 1277 | let LangOpts = [CPlusPlus]; |
| 1278 | } |
| 1279 | |
| 1280 | def TrivialABI : InheritableAttr { |
| 1281 | // This attribute does not have a C [[]] spelling because it requires the |
| 1282 | // CPlusPlus language option. |
| 1283 | let Spellings = [Clang<"trivial_abi", 0>]; |
| 1284 | let Subjects = SubjectList<[CXXRecord]>; |
| 1285 | let Documentation = [TrivialABIDocs]; |
| 1286 | let LangOpts = [CPlusPlus]; |
| 1287 | } |
| 1288 | |
| 1289 | def MaxFieldAlignment : InheritableAttr { |
| 1290 | // This attribute has no spellings as it is only ever created implicitly. |
| 1291 | let Spellings = []; |
| 1292 | let Args = [UnsignedArgument<"Alignment">]; |
| 1293 | let SemaHandler = 0; |
| 1294 | let Documentation = [Undocumented]; |
| 1295 | } |
| 1296 | |
| 1297 | def MayAlias : InheritableAttr { |
| 1298 | // FIXME: this is a type attribute in GCC, but a declaration attribute here. |
| 1299 | let Spellings = [GCC<"may_alias">]; |
| 1300 | let Documentation = [Undocumented]; |
| 1301 | } |
| 1302 | |
| 1303 | def MIGServerRoutine : InheritableAttr { |
| 1304 | let Spellings = [Clang<"mig_server_routine">]; |
| 1305 | let Subjects = SubjectList<[Function, ObjCMethod, Block]>; |
| 1306 | let Documentation = [MIGConventionDocs]; |
| 1307 | } |
| 1308 | |
| 1309 | def MSABI : DeclOrTypeAttr { |
| 1310 | let Spellings = [GCC<"ms_abi">]; |
| 1311 | // let Subjects = [Function, ObjCMethod]; |
| 1312 | let Documentation = [MSABIDocs]; |
| 1313 | } |
| 1314 | |
| 1315 | def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> { |
| 1316 | // NOTE: If you add any additional spellings, ARMInterrupt's, MipsInterrupt's |
| 1317 | // and AnyX86Interrupt's spellings must match. |
| 1318 | let Spellings = [GCC<"interrupt">]; |
| 1319 | let Args = [UnsignedArgument<"Number">]; |
| 1320 | let ParseKind = "Interrupt"; |
| 1321 | let HasCustomParsing = 1; |
| 1322 | let Documentation = [Undocumented]; |
| 1323 | } |
| 1324 | |
| 1325 | def Mips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> { |
| 1326 | let Spellings = [GCC<"mips16">]; |
| 1327 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1328 | let Documentation = [Undocumented]; |
| 1329 | } |
| 1330 | |
| 1331 | def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips32> { |
| 1332 | // NOTE: If you add any additional spellings, ARMInterrupt's, |
| 1333 | // MSP430Interrupt's and AnyX86Interrupt's spellings must match. |
| 1334 | let Spellings = [GCC<"interrupt">]; |
| 1335 | let Subjects = SubjectList<[Function]>; |
| 1336 | let Args = [EnumArgument<"Interrupt", "InterruptType", |
| 1337 | ["vector=sw0", "vector=sw1", "vector=hw0", |
| 1338 | "vector=hw1", "vector=hw2", "vector=hw3", |
| 1339 | "vector=hw4", "vector=hw5", "eic", ""], |
| 1340 | ["sw0", "sw1", "hw0", "hw1", "hw2", "hw3", |
| 1341 | "hw4", "hw5", "eic", "eic"] |
| 1342 | >]; |
| 1343 | let ParseKind = "Interrupt"; |
| 1344 | let Documentation = [MipsInterruptDocs]; |
| 1345 | } |
| 1346 | |
| 1347 | def MicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> { |
| 1348 | let Spellings = [GCC<"micromips">]; |
| 1349 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1350 | let Documentation = [MicroMipsDocs]; |
| 1351 | } |
| 1352 | |
| 1353 | def MipsLongCall : InheritableAttr, TargetSpecificAttr<TargetAnyMips> { |
| 1354 | let Spellings = [GCC<"long_call">, GCC<"far">]; |
| 1355 | let Subjects = SubjectList<[Function]>; |
| 1356 | let Documentation = [MipsLongCallStyleDocs]; |
| 1357 | } |
| 1358 | |
| 1359 | def MipsShortCall : InheritableAttr, TargetSpecificAttr<TargetAnyMips> { |
| 1360 | let Spellings = [GCC<"short_call">, GCC<"near">]; |
| 1361 | let Subjects = SubjectList<[Function]>; |
| 1362 | let Documentation = [MipsShortCallStyleDocs]; |
| 1363 | } |
| 1364 | |
| 1365 | def Mode : Attr { |
| 1366 | let Spellings = [GCC<"mode">]; |
| 1367 | let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag>; |
| 1368 | let Args = [IdentifierArgument<"Mode">]; |
| 1369 | let Documentation = [Undocumented]; |
| 1370 | // This is notionally a type attribute, which #pragma clang attribute |
| 1371 | // generally does not support. |
| 1372 | let PragmaAttributeSupport = 0; |
| 1373 | } |
| 1374 | |
| 1375 | def Naked : InheritableAttr { |
| 1376 | let Spellings = [GCC<"naked">, Declspec<"naked">]; |
| 1377 | let Subjects = SubjectList<[Function]>; |
| 1378 | let Documentation = [Undocumented]; |
| 1379 | } |
| 1380 | |
| 1381 | def NeonPolyVectorType : TypeAttr { |
| 1382 | let Spellings = [Clang<"neon_polyvector_type">]; |
| 1383 | let Args = [IntArgument<"NumElements">]; |
| 1384 | let Documentation = [Undocumented]; |
| 1385 | // Represented as VectorType instead. |
| 1386 | let ASTNode = 0; |
| 1387 | } |
| 1388 | |
| 1389 | def NeonVectorType : TypeAttr { |
| 1390 | let Spellings = [Clang<"neon_vector_type">]; |
| 1391 | let Args = [IntArgument<"NumElements">]; |
| 1392 | let Documentation = [Undocumented]; |
| 1393 | // Represented as VectorType instead. |
| 1394 | let ASTNode = 0; |
| 1395 | } |
| 1396 | |
| 1397 | def ReturnsTwice : InheritableAttr { |
| 1398 | let Spellings = [GCC<"returns_twice">]; |
| 1399 | let Subjects = SubjectList<[Function]>; |
| 1400 | let Documentation = [Undocumented]; |
| 1401 | } |
| 1402 | |
| 1403 | def DisableTailCalls : InheritableAttr { |
| 1404 | let Spellings = [Clang<"disable_tail_calls">]; |
| 1405 | let Subjects = SubjectList<[Function, ObjCMethod]>; |
| 1406 | let Documentation = [DisableTailCallsDocs]; |
| 1407 | } |
| 1408 | |
| 1409 | def NoAlias : InheritableAttr { |
| 1410 | let Spellings = [Declspec<"noalias">]; |
| 1411 | let Subjects = SubjectList<[Function]>; |
| 1412 | let Documentation = [NoAliasDocs]; |
| 1413 | } |
| 1414 | |
| 1415 | def NoCommon : InheritableAttr { |
| 1416 | let Spellings = [GCC<"nocommon">]; |
| 1417 | let Subjects = SubjectList<[Var]>; |
| 1418 | let Documentation = [Undocumented]; |
| 1419 | } |
| 1420 | |
| 1421 | def NoDebug : InheritableAttr { |
| 1422 | let Spellings = [GCC<"nodebug">]; |
| 1423 | let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar]>; |
| 1424 | let Documentation = [NoDebugDocs]; |
| 1425 | } |
| 1426 | |
| 1427 | def NoDuplicate : InheritableAttr { |
| 1428 | let Spellings = [Clang<"noduplicate">]; |
| 1429 | let Subjects = SubjectList<[Function]>; |
| 1430 | let Documentation = [NoDuplicateDocs]; |
| 1431 | } |
| 1432 | |
| 1433 | def Convergent : InheritableAttr { |
| 1434 | let Spellings = [Clang<"convergent">]; |
| 1435 | let Subjects = SubjectList<[Function]>; |
| 1436 | let Documentation = [ConvergentDocs]; |
| 1437 | } |
| 1438 | |
| 1439 | def NoInline : InheritableAttr { |
| 1440 | let Spellings = [GCC<"noinline">, Declspec<"noinline">]; |
| 1441 | let Subjects = SubjectList<[Function]>; |
| 1442 | let Documentation = [Undocumented]; |
| 1443 | } |
| 1444 | |
| 1445 | def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> { |
| 1446 | let Spellings = [GCC<"nomips16">]; |
| 1447 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1448 | let Documentation = [Undocumented]; |
| 1449 | } |
| 1450 | |
| 1451 | def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> { |
| 1452 | let Spellings = [GCC<"nomicromips">]; |
| 1453 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1454 | let Documentation = [MicroMipsDocs]; |
| 1455 | } |
| 1456 | |
| 1457 | def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> { |
| 1458 | let Spellings = [GCC<"interrupt">]; |
| 1459 | let Subjects = SubjectList<[Function]>; |
| 1460 | let Args = [EnumArgument<"Interrupt", "InterruptType", |
| 1461 | ["user", "supervisor", "machine"], |
| 1462 | ["user", "supervisor", "machine"], |
| 1463 | 1>]; |
| 1464 | let ParseKind = "Interrupt"; |
| 1465 | let Documentation = [RISCVInterruptDocs]; |
| 1466 | } |
| 1467 | |
| 1468 | // This is not a TargetSpecificAttr so that is silently accepted and |
| 1469 | // ignored on other targets as encouraged by the OpenCL spec. |
| 1470 | // |
| 1471 | // See OpenCL 1.2 6.11.5: "It is our intention that a particular |
| 1472 | // implementation of OpenCL be free to ignore all attributes and the |
| 1473 | // resulting executable binary will produce the same result." |
| 1474 | // |
| 1475 | // However, only AMD GPU targets will emit the corresponding IR |
| 1476 | // attribute. |
| 1477 | // |
| 1478 | // FIXME: This provides a sub-optimal error message if you attempt to |
| 1479 | // use this in CUDA, since CUDA does not use the same terminology. |
| 1480 | // |
| 1481 | // FIXME: SubjectList should be for OpenCLKernelFunction, but is not to |
| 1482 | // workaround needing to see kernel attribute before others to know if |
| 1483 | // this should be rejected on non-kernels. |
| 1484 | |
| 1485 | def AMDGPUFlatWorkGroupSize : InheritableAttr { |
| 1486 | let Spellings = [Clang<"amdgpu_flat_work_group_size", 0>]; |
| 1487 | let Args = [ExprArgument<"Min">, ExprArgument<"Max">]; |
| 1488 | let Documentation = [AMDGPUFlatWorkGroupSizeDocs]; |
| 1489 | let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; |
| 1490 | } |
| 1491 | |
| 1492 | def AMDGPUWavesPerEU : InheritableAttr { |
| 1493 | let Spellings = [Clang<"amdgpu_waves_per_eu", 0>]; |
| 1494 | let Args = [ExprArgument<"Min">, ExprArgument<"Max", 1>]; |
| 1495 | let Documentation = [AMDGPUWavesPerEUDocs]; |
| 1496 | let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; |
| 1497 | } |
| 1498 | |
| 1499 | def AMDGPUNumSGPR : InheritableAttr { |
| 1500 | let Spellings = [Clang<"amdgpu_num_sgpr", 0>]; |
| 1501 | let Args = [UnsignedArgument<"NumSGPR">]; |
| 1502 | let Documentation = [AMDGPUNumSGPRNumVGPRDocs]; |
| 1503 | let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; |
| 1504 | } |
| 1505 | |
| 1506 | def AMDGPUNumVGPR : InheritableAttr { |
| 1507 | let Spellings = [Clang<"amdgpu_num_vgpr", 0>]; |
| 1508 | let Args = [UnsignedArgument<"NumVGPR">]; |
| 1509 | let Documentation = [AMDGPUNumSGPRNumVGPRDocs]; |
| 1510 | let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; |
| 1511 | } |
| 1512 | |
| 1513 | def WebAssemblyImportModule : InheritableAttr, |
| 1514 | TargetSpecificAttr<TargetWebAssembly> { |
| 1515 | let Spellings = [Clang<"import_module">]; |
| 1516 | let Args = [StringArgument<"ImportModule">]; |
| 1517 | let Documentation = [WebAssemblyImportModuleDocs]; |
| 1518 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1519 | } |
| 1520 | |
| 1521 | def WebAssemblyImportName : InheritableAttr, |
| 1522 | TargetSpecificAttr<TargetWebAssembly> { |
| 1523 | let Spellings = [Clang<"import_name">]; |
| 1524 | let Args = [StringArgument<"ImportName">]; |
| 1525 | let Documentation = [WebAssemblyImportNameDocs]; |
| 1526 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1527 | } |
| 1528 | |
| 1529 | def NoSplitStack : InheritableAttr { |
| 1530 | let Spellings = [GCC<"no_split_stack">]; |
| 1531 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1532 | let Documentation = [NoSplitStackDocs]; |
| 1533 | } |
| 1534 | |
| 1535 | def NonNull : InheritableParamAttr { |
| 1536 | let Spellings = [GCC<"nonnull">]; |
| 1537 | let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag, |
| 1538 | "functions, methods, and parameters">; |
| 1539 | let Args = [VariadicParamIdxArgument<"Args">]; |
| 1540 | let AdditionalMembers = [{ |
| 1541 | bool isNonNull(unsigned IdxAST) const { |
| 1542 | if (!args_size()) |
| 1543 | return true; |
| 1544 | return args_end() != std::find_if( |
| 1545 | args_begin(), args_end(), |
| 1546 | [=](const ParamIdx &Idx) { return Idx.getASTIndex() == IdxAST; }); |
| 1547 | } |
| 1548 | }]; |
| 1549 | // FIXME: We should merge duplicates into a single nonnull attribute. |
| 1550 | let InheritEvenIfAlreadyPresent = 1; |
| 1551 | let Documentation = [NonNullDocs]; |
| 1552 | } |
| 1553 | |
| 1554 | def ReturnsNonNull : InheritableAttr { |
| 1555 | let Spellings = [GCC<"returns_nonnull">]; |
| 1556 | let Subjects = SubjectList<[ObjCMethod, Function]>; |
| 1557 | let Documentation = [ReturnsNonNullDocs]; |
| 1558 | } |
| 1559 | |
| 1560 | // pass_object_size(N) indicates that the parameter should have |
| 1561 | // __builtin_object_size with Type=N evaluated on the parameter at the callsite. |
| 1562 | def PassObjectSize : InheritableParamAttr { |
| 1563 | let Spellings = [Clang<"pass_object_size">, |
| 1564 | Clang<"pass_dynamic_object_size">]; |
| 1565 | let Accessors = [Accessor<"isDynamic", [Clang<"pass_dynamic_object_size">]>]; |
| 1566 | let Args = [IntArgument<"Type">]; |
| 1567 | let Subjects = SubjectList<[ParmVar]>; |
| 1568 | let Documentation = [PassObjectSizeDocs]; |
| 1569 | } |
| 1570 | |
| 1571 | // Nullability type attributes. |
| 1572 | def TypeNonNull : TypeAttr { |
| 1573 | let Spellings = [Keyword<"_Nonnull">]; |
| 1574 | let Documentation = [TypeNonNullDocs]; |
| 1575 | } |
| 1576 | |
| 1577 | def TypeNullable : TypeAttr { |
| 1578 | let Spellings = [Keyword<"_Nullable">]; |
| 1579 | let Documentation = [TypeNullableDocs]; |
| 1580 | } |
| 1581 | |
| 1582 | def TypeNullUnspecified : TypeAttr { |
| 1583 | let Spellings = [Keyword<"_Null_unspecified">]; |
| 1584 | let Documentation = [TypeNullUnspecifiedDocs]; |
| 1585 | } |
| 1586 | |
| 1587 | // This is a marker used to indicate that an __unsafe_unretained qualifier was |
| 1588 | // ignored because ARC is not enabled. The usual representation for this |
| 1589 | // qualifier is as an ObjCOwnership attribute with Kind == "none". |
| 1590 | def ObjCInertUnsafeUnretained : TypeAttr { |
| 1591 | let Spellings = [Keyword<"__unsafe_unretained">]; |
| 1592 | let Documentation = [Undocumented]; |
| 1593 | } |
| 1594 | |
| 1595 | def ObjCKindOf : TypeAttr { |
| 1596 | let Spellings = [Keyword<"__kindof">]; |
| 1597 | let Documentation = [Undocumented]; |
| 1598 | } |
| 1599 | |
| 1600 | def NoEscape : Attr { |
| 1601 | let Spellings = [Clang<"noescape">]; |
| 1602 | let Subjects = SubjectList<[ParmVar]>; |
| 1603 | let Documentation = [NoEscapeDocs]; |
| 1604 | } |
| 1605 | |
| 1606 | def AssumeAligned : InheritableAttr { |
| 1607 | let Spellings = [GCC<"assume_aligned">]; |
| 1608 | let Subjects = SubjectList<[ObjCMethod, Function]>; |
| 1609 | let Args = [ExprArgument<"Alignment">, ExprArgument<"Offset", 1>]; |
| 1610 | let Documentation = [AssumeAlignedDocs]; |
| 1611 | } |
| 1612 | |
| 1613 | def AllocAlign : InheritableAttr { |
| 1614 | let Spellings = [GCC<"alloc_align">]; |
| 1615 | let Subjects = SubjectList<[HasFunctionProto]>; |
| 1616 | let Args = [ParamIdxArgument<"ParamIndex">]; |
| 1617 | let Documentation = [AllocAlignDocs]; |
| 1618 | } |
| 1619 | |
| 1620 | def NoReturn : InheritableAttr { |
| 1621 | let Spellings = [GCC<"noreturn">, Declspec<"noreturn">]; |
| 1622 | // FIXME: Does GCC allow this on the function instead? |
| 1623 | let Documentation = [Undocumented]; |
| 1624 | } |
| 1625 | |
| 1626 | def NoInstrumentFunction : InheritableAttr { |
| 1627 | let Spellings = [GCC<"no_instrument_function">]; |
| 1628 | let Subjects = SubjectList<[Function]>; |
| 1629 | let Documentation = [Undocumented]; |
| 1630 | } |
| 1631 | |
| 1632 | def NotTailCalled : InheritableAttr { |
| 1633 | let Spellings = [Clang<"not_tail_called">]; |
| 1634 | let Subjects = SubjectList<[Function]>; |
| 1635 | let Documentation = [NotTailCalledDocs]; |
| 1636 | } |
| 1637 | |
| 1638 | def NoStackProtector : InheritableAttr { |
| 1639 | let Spellings = [Clang<"no_stack_protector">]; |
| 1640 | let Subjects = SubjectList<[Function]>; |
| 1641 | let Documentation = [NoStackProtectorDocs]; |
| 1642 | } |
| 1643 | |
| 1644 | def NoThrow : InheritableAttr { |
| 1645 | let Spellings = [GCC<"nothrow">, Declspec<"nothrow">]; |
| 1646 | let Subjects = SubjectList<[Function]>; |
| 1647 | let Documentation = [NoThrowDocs]; |
| 1648 | } |
| 1649 | |
| 1650 | def NvWeak : IgnoredAttr { |
| 1651 | // No Declspec spelling of this attribute; the CUDA headers use |
| 1652 | // __attribute__((nv_weak)) unconditionally. Does not receive an [[]] |
| 1653 | // spelling because it is a CUDA attribute. |
| 1654 | let Spellings = [GNU<"nv_weak">]; |
| 1655 | let LangOpts = [CUDA]; |
| 1656 | } |
| 1657 | |
| 1658 | def ObjCBridge : InheritableAttr { |
| 1659 | let Spellings = [Clang<"objc_bridge">]; |
| 1660 | let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>; |
| 1661 | let Args = [IdentifierArgument<"BridgedType">]; |
| 1662 | let Documentation = [Undocumented]; |
| 1663 | } |
| 1664 | |
| 1665 | def ObjCBridgeMutable : InheritableAttr { |
| 1666 | let Spellings = [Clang<"objc_bridge_mutable">]; |
| 1667 | let Subjects = SubjectList<[Record], ErrorDiag>; |
| 1668 | let Args = [IdentifierArgument<"BridgedType">]; |
| 1669 | let Documentation = [Undocumented]; |
| 1670 | } |
| 1671 | |
| 1672 | def ObjCBridgeRelated : InheritableAttr { |
| 1673 | let Spellings = [Clang<"objc_bridge_related">]; |
| 1674 | let Subjects = SubjectList<[Record], ErrorDiag>; |
| 1675 | let Args = [IdentifierArgument<"RelatedClass">, |
| 1676 | IdentifierArgument<"ClassMethod">, |
| 1677 | IdentifierArgument<"InstanceMethod">]; |
| 1678 | let HasCustomParsing = 1; |
| 1679 | let Documentation = [Undocumented]; |
| 1680 | } |
| 1681 | |
| 1682 | def NSReturnsRetained : DeclOrTypeAttr { |
| 1683 | let Spellings = [Clang<"ns_returns_retained">]; |
| 1684 | // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; |
| 1685 | let Documentation = [RetainBehaviorDocs]; |
| 1686 | } |
| 1687 | |
| 1688 | def NSReturnsNotRetained : InheritableAttr { |
| 1689 | let Spellings = [Clang<"ns_returns_not_retained">]; |
| 1690 | // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; |
| 1691 | let Documentation = [RetainBehaviorDocs]; |
| 1692 | } |
| 1693 | |
| 1694 | def NSReturnsAutoreleased : InheritableAttr { |
| 1695 | let Spellings = [Clang<"ns_returns_autoreleased">]; |
| 1696 | // let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>; |
| 1697 | let Documentation = [RetainBehaviorDocs]; |
| 1698 | } |
| 1699 | |
| 1700 | def NSConsumesSelf : InheritableAttr { |
| 1701 | let Spellings = [Clang<"ns_consumes_self">]; |
| 1702 | let Subjects = SubjectList<[ObjCMethod]>; |
| 1703 | let Documentation = [RetainBehaviorDocs]; |
| 1704 | } |
| 1705 | |
| 1706 | def NSConsumed : InheritableParamAttr { |
| 1707 | let Spellings = [Clang<"ns_consumed">]; |
| 1708 | let Subjects = SubjectList<[ParmVar]>; |
| 1709 | let Documentation = [RetainBehaviorDocs]; |
| 1710 | } |
| 1711 | |
| 1712 | def ObjCException : InheritableAttr { |
| 1713 | let Spellings = [Clang<"objc_exception">]; |
| 1714 | let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; |
| 1715 | let Documentation = [Undocumented]; |
| 1716 | } |
| 1717 | |
| 1718 | def ObjCMethodFamily : InheritableAttr { |
| 1719 | let Spellings = [Clang<"objc_method_family">]; |
| 1720 | let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; |
| 1721 | let Args = [EnumArgument<"Family", "FamilyKind", |
| 1722 | ["none", "alloc", "copy", "init", "mutableCopy", "new"], |
| 1723 | ["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init", |
| 1724 | "OMF_mutableCopy", "OMF_new"]>]; |
| 1725 | let Documentation = [ObjCMethodFamilyDocs]; |
| 1726 | } |
| 1727 | |
| 1728 | def ObjCNSObject : InheritableAttr { |
| 1729 | let Spellings = [Clang<"NSObject">]; |
| 1730 | let Documentation = [Undocumented]; |
| 1731 | } |
| 1732 | |
| 1733 | def ObjCIndependentClass : InheritableAttr { |
| 1734 | let Spellings = [Clang<"objc_independent_class">]; |
| 1735 | let Documentation = [Undocumented]; |
| 1736 | } |
| 1737 | |
| 1738 | def ObjCPreciseLifetime : InheritableAttr { |
| 1739 | let Spellings = [Clang<"objc_precise_lifetime">]; |
| 1740 | let Subjects = SubjectList<[Var], ErrorDiag>; |
| 1741 | let Documentation = [Undocumented]; |
| 1742 | } |
| 1743 | |
| 1744 | def ObjCReturnsInnerPointer : InheritableAttr { |
| 1745 | let Spellings = [Clang<"objc_returns_inner_pointer">]; |
| 1746 | let Subjects = SubjectList<[ObjCMethod, ObjCProperty], ErrorDiag>; |
| 1747 | let Documentation = [Undocumented]; |
| 1748 | } |
| 1749 | |
| 1750 | def ObjCRequiresSuper : InheritableAttr { |
| 1751 | let Spellings = [Clang<"objc_requires_super">]; |
| 1752 | let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; |
| 1753 | let Documentation = [ObjCRequiresSuperDocs]; |
| 1754 | } |
| 1755 | |
| 1756 | def ObjCRootClass : InheritableAttr { |
| 1757 | let Spellings = [Clang<"objc_root_class">]; |
| 1758 | let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; |
| 1759 | let Documentation = [Undocumented]; |
| 1760 | } |
| 1761 | |
| 1762 | def ObjCNonLazyClass : Attr { |
| 1763 | let Spellings = [Clang<"objc_nonlazy_class">]; |
| 1764 | let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; |
| 1765 | let LangOpts = [ObjC]; |
| 1766 | let Documentation = [ObjCNonLazyClassDocs]; |
| 1767 | } |
| 1768 | |
| 1769 | def ObjCSubclassingRestricted : InheritableAttr { |
| 1770 | let Spellings = [Clang<"objc_subclassing_restricted">]; |
| 1771 | let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; |
| 1772 | let Documentation = [ObjCSubclassingRestrictedDocs]; |
| 1773 | } |
| 1774 | |
| 1775 | def ObjCExplicitProtocolImpl : InheritableAttr { |
| 1776 | let Spellings = [Clang<"objc_protocol_requires_explicit_implementation">]; |
| 1777 | let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>; |
| 1778 | let Documentation = [Undocumented]; |
| 1779 | } |
| 1780 | |
| 1781 | def ObjCDesignatedInitializer : Attr { |
| 1782 | let Spellings = [Clang<"objc_designated_initializer">]; |
| 1783 | let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; |
| 1784 | let Documentation = [Undocumented]; |
| 1785 | } |
| 1786 | |
| 1787 | def ObjCRuntimeName : Attr { |
| 1788 | let Spellings = [Clang<"objc_runtime_name">]; |
| 1789 | let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>; |
| 1790 | let Args = [StringArgument<"MetadataName">]; |
| 1791 | let Documentation = [ObjCRuntimeNameDocs]; |
| 1792 | } |
| 1793 | |
| 1794 | def ObjCRuntimeVisible : Attr { |
| 1795 | let Spellings = [Clang<"objc_runtime_visible">]; |
| 1796 | let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; |
| 1797 | let Documentation = [ObjCRuntimeVisibleDocs]; |
| 1798 | } |
| 1799 | |
| 1800 | def ObjCBoxable : Attr { |
| 1801 | let Spellings = [Clang<"objc_boxable">]; |
| 1802 | let Subjects = SubjectList<[Record], ErrorDiag>; |
| 1803 | let Documentation = [ObjCBoxableDocs]; |
| 1804 | } |
| 1805 | |
| 1806 | def OptimizeNone : InheritableAttr { |
| 1807 | let Spellings = [Clang<"optnone">]; |
| 1808 | let Subjects = SubjectList<[Function, ObjCMethod]>; |
| 1809 | let Documentation = [OptnoneDocs]; |
| 1810 | } |
| 1811 | |
| 1812 | def Overloadable : Attr { |
| 1813 | let Spellings = [Clang<"overloadable">]; |
| 1814 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1815 | let Documentation = [OverloadableDocs]; |
| 1816 | } |
| 1817 | |
| 1818 | def Override : InheritableAttr { |
| 1819 | let Spellings = [Keyword<"override">]; |
| 1820 | let SemaHandler = 0; |
| 1821 | let Documentation = [Undocumented]; |
| 1822 | } |
| 1823 | |
| 1824 | def Ownership : InheritableAttr { |
| 1825 | let Spellings = [Clang<"ownership_holds">, Clang<"ownership_returns">, |
| 1826 | Clang<"ownership_takes">]; |
| 1827 | let Accessors = [Accessor<"isHolds", [Clang<"ownership_holds">]>, |
| 1828 | Accessor<"isReturns", [Clang<"ownership_returns">]>, |
| 1829 | Accessor<"isTakes", [Clang<"ownership_takes">]>]; |
| 1830 | let AdditionalMembers = [{ |
| 1831 | enum OwnershipKind { Holds, Returns, Takes }; |
| 1832 | OwnershipKind getOwnKind() const { |
| 1833 | return isHolds() ? Holds : |
| 1834 | isTakes() ? Takes : |
| 1835 | Returns; |
| 1836 | } |
| 1837 | }]; |
| 1838 | let Args = [IdentifierArgument<"Module">, |
| 1839 | VariadicParamIdxArgument<"Args">]; |
| 1840 | let Subjects = SubjectList<[HasFunctionProto]>; |
| 1841 | let Documentation = [Undocumented]; |
| 1842 | } |
| 1843 | |
| 1844 | def Packed : InheritableAttr { |
| 1845 | let Spellings = [GCC<"packed">]; |
| 1846 | // let Subjects = [Tag, Field]; |
| 1847 | let Documentation = [Undocumented]; |
| 1848 | } |
| 1849 | |
| 1850 | def IntelOclBicc : DeclOrTypeAttr { |
| 1851 | let Spellings = [Clang<"intel_ocl_bicc", 0>]; |
| 1852 | // let Subjects = [Function, ObjCMethod]; |
| 1853 | let Documentation = [Undocumented]; |
| 1854 | } |
| 1855 | |
| 1856 | def Pcs : DeclOrTypeAttr { |
| 1857 | let Spellings = [GCC<"pcs">]; |
| 1858 | let Args = [EnumArgument<"PCS", "PCSType", |
| 1859 | ["aapcs", "aapcs-vfp"], |
| 1860 | ["AAPCS", "AAPCS_VFP"]>]; |
| 1861 | // let Subjects = [Function, ObjCMethod]; |
| 1862 | let Documentation = [PcsDocs]; |
| 1863 | } |
| 1864 | |
| 1865 | def AArch64VectorPcs: DeclOrTypeAttr { |
| 1866 | let Spellings = [Clang<"aarch64_vector_pcs">]; |
| 1867 | let Documentation = [AArch64VectorPcsDocs]; |
| 1868 | } |
| 1869 | |
| 1870 | def Pure : InheritableAttr { |
| 1871 | let Spellings = [GCC<"pure">]; |
| 1872 | let Documentation = [Undocumented]; |
| 1873 | } |
| 1874 | |
| 1875 | def Regparm : TypeAttr { |
| 1876 | let Spellings = [GCC<"regparm">]; |
| 1877 | let Args = [UnsignedArgument<"NumParams">]; |
| 1878 | let Documentation = [RegparmDocs]; |
| 1879 | // Represented as part of the enclosing function type. |
| 1880 | let ASTNode = 0; |
| 1881 | } |
| 1882 | |
| 1883 | def NoDeref : TypeAttr { |
| 1884 | let Spellings = [Clang<"noderef">]; |
| 1885 | let Documentation = [NoDerefDocs]; |
| 1886 | } |
| 1887 | |
| 1888 | def ReqdWorkGroupSize : InheritableAttr { |
| 1889 | // Does not have a [[]] spelling because it is an OpenCL-related attribute. |
| 1890 | let Spellings = [GNU<"reqd_work_group_size">]; |
| 1891 | let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">, |
| 1892 | UnsignedArgument<"ZDim">]; |
| 1893 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1894 | let Documentation = [Undocumented]; |
| 1895 | } |
| 1896 | |
| 1897 | def RequireConstantInit : InheritableAttr { |
| 1898 | // This attribute does not have a C [[]] spelling because it requires the |
| 1899 | // CPlusPlus language option. |
| 1900 | let Spellings = [Clang<"require_constant_initialization", 0>]; |
| 1901 | let Subjects = SubjectList<[GlobalVar], ErrorDiag>; |
| 1902 | let Documentation = [RequireConstantInitDocs]; |
| 1903 | let LangOpts = [CPlusPlus]; |
| 1904 | } |
| 1905 | |
| 1906 | def WorkGroupSizeHint : InheritableAttr { |
| 1907 | // Does not have a [[]] spelling because it is an OpenCL-related attribute. |
| 1908 | let Spellings = [GNU<"work_group_size_hint">]; |
| 1909 | let Args = [UnsignedArgument<"XDim">, |
| 1910 | UnsignedArgument<"YDim">, |
| 1911 | UnsignedArgument<"ZDim">]; |
| 1912 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1913 | let Documentation = [Undocumented]; |
| 1914 | } |
| 1915 | |
| 1916 | def InitPriority : InheritableAttr { |
| 1917 | let Spellings = [GCC<"init_priority">]; |
| 1918 | let Args = [UnsignedArgument<"Priority">]; |
| 1919 | let Subjects = SubjectList<[Var], ErrorDiag>; |
| 1920 | let Documentation = [Undocumented]; |
| 1921 | } |
| 1922 | |
| 1923 | def Section : InheritableAttr { |
| 1924 | let Spellings = [GCC<"section">, Declspec<"allocate">]; |
| 1925 | let Args = [StringArgument<"Name">]; |
| 1926 | let Subjects = |
| 1927 | SubjectList<[ Function, GlobalVar, ObjCMethod, ObjCProperty ], ErrorDiag>; |
| 1928 | let Documentation = [SectionDocs]; |
| 1929 | } |
| 1930 | |
| 1931 | def CodeSeg : InheritableAttr { |
| 1932 | let Spellings = [Declspec<"code_seg">]; |
| 1933 | let Args = [StringArgument<"Name">]; |
| 1934 | let Subjects = SubjectList<[Function, CXXRecord], ErrorDiag>; |
| 1935 | let Documentation = [CodeSegDocs]; |
| 1936 | } |
| 1937 | |
| 1938 | def PragmaClangBSSSection : InheritableAttr { |
| 1939 | // This attribute has no spellings as it is only ever created implicitly. |
| 1940 | let Spellings = []; |
| 1941 | let Args = [StringArgument<"Name">]; |
| 1942 | let Subjects = SubjectList<[GlobalVar], ErrorDiag>; |
| 1943 | let Documentation = [Undocumented]; |
| 1944 | } |
| 1945 | |
| 1946 | def PragmaClangDataSection : InheritableAttr { |
| 1947 | // This attribute has no spellings as it is only ever created implicitly. |
| 1948 | let Spellings = []; |
| 1949 | let Args = [StringArgument<"Name">]; |
| 1950 | let Subjects = SubjectList<[GlobalVar], ErrorDiag>; |
| 1951 | let Documentation = [Undocumented]; |
| 1952 | } |
| 1953 | |
| 1954 | def PragmaClangRodataSection : InheritableAttr { |
| 1955 | // This attribute has no spellings as it is only ever created implicitly. |
| 1956 | let Spellings = []; |
| 1957 | let Args = [StringArgument<"Name">]; |
| 1958 | let Subjects = SubjectList<[GlobalVar], ErrorDiag>; |
| 1959 | let Documentation = [Undocumented]; |
| 1960 | } |
| 1961 | |
| 1962 | def PragmaClangTextSection : InheritableAttr { |
| 1963 | // This attribute has no spellings as it is only ever created implicitly. |
| 1964 | let Spellings = []; |
| 1965 | let Args = [StringArgument<"Name">]; |
| 1966 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 1967 | let Documentation = [Undocumented]; |
| 1968 | } |
| 1969 | |
| 1970 | def Sentinel : InheritableAttr { |
| 1971 | let Spellings = [GCC<"sentinel">]; |
| 1972 | let Args = [DefaultIntArgument<"Sentinel", 0>, |
| 1973 | DefaultIntArgument<"NullPos", 0>]; |
| 1974 | // let Subjects = SubjectList<[Function, ObjCMethod, Block, Var]>; |
| 1975 | let Documentation = [Undocumented]; |
| 1976 | } |
| 1977 | |
| 1978 | def StdCall : DeclOrTypeAttr { |
| 1979 | let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">]; |
| 1980 | // let Subjects = [Function, ObjCMethod]; |
| 1981 | let Documentation = [StdCallDocs]; |
| 1982 | } |
| 1983 | |
| 1984 | def SwiftCall : DeclOrTypeAttr { |
| 1985 | let Spellings = [Clang<"swiftcall">]; |
| 1986 | // let Subjects = SubjectList<[Function]>; |
| 1987 | let Documentation = [SwiftCallDocs]; |
| 1988 | } |
| 1989 | |
| 1990 | def SwiftContext : ParameterABIAttr { |
| 1991 | let Spellings = [Clang<"swift_context">]; |
| 1992 | let Documentation = [SwiftContextDocs]; |
| 1993 | } |
| 1994 | |
| 1995 | def SwiftErrorResult : ParameterABIAttr { |
| 1996 | let Spellings = [Clang<"swift_error_result">]; |
| 1997 | let Documentation = [SwiftErrorResultDocs]; |
| 1998 | } |
| 1999 | |
| 2000 | def SwiftIndirectResult : ParameterABIAttr { |
| 2001 | let Spellings = [Clang<"swift_indirect_result">]; |
| 2002 | let Documentation = [SwiftIndirectResultDocs]; |
| 2003 | } |
| 2004 | |
| 2005 | def Suppress : StmtAttr { |
| 2006 | let Spellings = [CXX11<"gsl", "suppress">]; |
| 2007 | let Args = [VariadicStringArgument<"DiagnosticIdentifiers">]; |
| 2008 | let Documentation = [SuppressDocs]; |
| 2009 | } |
| 2010 | |
| 2011 | def SysVABI : DeclOrTypeAttr { |
| 2012 | let Spellings = [GCC<"sysv_abi">]; |
| 2013 | // let Subjects = [Function, ObjCMethod]; |
| 2014 | let Documentation = [Undocumented]; |
| 2015 | } |
| 2016 | |
| 2017 | def ThisCall : DeclOrTypeAttr { |
| 2018 | let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">, |
| 2019 | Keyword<"_thiscall">]; |
| 2020 | // let Subjects = [Function, ObjCMethod]; |
| 2021 | let Documentation = [ThisCallDocs]; |
| 2022 | } |
| 2023 | |
| 2024 | def VectorCall : DeclOrTypeAttr { |
| 2025 | let Spellings = [Clang<"vectorcall">, Keyword<"__vectorcall">, |
| 2026 | Keyword<"_vectorcall">]; |
| 2027 | // let Subjects = [Function, ObjCMethod]; |
| 2028 | let Documentation = [VectorCallDocs]; |
| 2029 | } |
| 2030 | |
| 2031 | def Pascal : DeclOrTypeAttr { |
| 2032 | let Spellings = [Clang<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">]; |
| 2033 | // let Subjects = [Function, ObjCMethod]; |
| 2034 | let Documentation = [Undocumented]; |
| 2035 | } |
| 2036 | |
| 2037 | def PreserveMost : DeclOrTypeAttr { |
| 2038 | let Spellings = [Clang<"preserve_most">]; |
| 2039 | let Documentation = [PreserveMostDocs]; |
| 2040 | } |
| 2041 | |
| 2042 | def PreserveAll : DeclOrTypeAttr { |
| 2043 | let Spellings = [Clang<"preserve_all">]; |
| 2044 | let Documentation = [PreserveAllDocs]; |
| 2045 | } |
| 2046 | |
| 2047 | def Target : InheritableAttr { |
| 2048 | let Spellings = [GCC<"target">]; |
| 2049 | let Args = [StringArgument<"featuresStr">]; |
| 2050 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 2051 | let Documentation = [TargetDocs]; |
| 2052 | let AdditionalMembers = [{ |
| 2053 | struct ParsedTargetAttr { |
| 2054 | std::vector<std::string> Features; |
| 2055 | StringRef Architecture; |
| 2056 | bool DuplicateArchitecture = false; |
| 2057 | bool operator ==(const ParsedTargetAttr &Other) const { |
| 2058 | return DuplicateArchitecture == Other.DuplicateArchitecture && |
| 2059 | Architecture == Other.Architecture && Features == Other.Features; |
| 2060 | } |
| 2061 | }; |
| 2062 | ParsedTargetAttr parse() const { |
| 2063 | return parse(getFeaturesStr()); |
| 2064 | } |
| 2065 | |
| 2066 | StringRef getArchitecture() const { |
| 2067 | StringRef Features = getFeaturesStr(); |
| 2068 | if (Features == "default") return {}; |
| 2069 | |
| 2070 | SmallVector<StringRef, 1> AttrFeatures; |
| 2071 | Features.split(AttrFeatures, ","); |
| 2072 | |
| 2073 | for (auto &Feature : AttrFeatures) { |
| 2074 | Feature = Feature.trim(); |
| 2075 | if (Feature.startswith("arch=")) |
| 2076 | return Feature.drop_front(sizeof("arch=") - 1); |
| 2077 | } |
| 2078 | return ""; |
| 2079 | } |
| 2080 | |
| 2081 | // Gets the list of features as simple string-refs with no +/- or 'no-'. |
| 2082 | // Only adds the items to 'Out' that are additions. |
| 2083 | void getAddedFeatures(llvm::SmallVectorImpl<StringRef> &Out) const { |
| 2084 | StringRef Features = getFeaturesStr(); |
| 2085 | if (Features == "default") return; |
| 2086 | |
| 2087 | SmallVector<StringRef, 1> AttrFeatures; |
| 2088 | Features.split(AttrFeatures, ","); |
| 2089 | |
| 2090 | for (auto &Feature : AttrFeatures) { |
| 2091 | Feature = Feature.trim(); |
| 2092 | |
| 2093 | if (!Feature.startswith("no-") && !Feature.startswith("arch=") && |
| 2094 | !Feature.startswith("fpmath=") && !Feature.startswith("tune=")) |
| 2095 | Out.push_back(Feature); |
| 2096 | } |
| 2097 | } |
| 2098 | |
| 2099 | template<class Compare> |
| 2100 | ParsedTargetAttr parse(Compare cmp) const { |
| 2101 | ParsedTargetAttr Attrs = parse(); |
| 2102 | llvm::sort(std::begin(Attrs.Features), std::end(Attrs.Features), cmp); |
| 2103 | return Attrs; |
| 2104 | } |
| 2105 | |
| 2106 | bool isDefaultVersion() const { return getFeaturesStr() == "default"; } |
| 2107 | |
| 2108 | static ParsedTargetAttr parse(StringRef Features) { |
| 2109 | ParsedTargetAttr Ret; |
| 2110 | if (Features == "default") return Ret; |
| 2111 | SmallVector<StringRef, 1> AttrFeatures; |
| 2112 | Features.split(AttrFeatures, ","); |
| 2113 | |
| 2114 | // Grab the various features and prepend a "+" to turn on the feature to |
| 2115 | // the backend and add them to our existing set of features. |
| 2116 | for (auto &Feature : AttrFeatures) { |
| 2117 | // Go ahead and trim whitespace rather than either erroring or |
| 2118 | // accepting it weirdly. |
| 2119 | Feature = Feature.trim(); |
| 2120 | |
| 2121 | // We don't support cpu tuning this way currently. |
| 2122 | // TODO: Support the fpmath option. It will require checking |
| 2123 | // overall feature validity for the function with the rest of the |
| 2124 | // attributes on the function. |
| 2125 | if (Feature.startswith("fpmath=") || Feature.startswith("tune=")) |
| 2126 | continue; |
| 2127 | |
| 2128 | // While we're here iterating check for a different target cpu. |
| 2129 | if (Feature.startswith("arch=")) { |
| 2130 | if (!Ret.Architecture.empty()) |
| 2131 | Ret.DuplicateArchitecture = true; |
| 2132 | else |
| 2133 | Ret.Architecture = Feature.split("=").second.trim(); |
| 2134 | } else if (Feature.startswith("no-")) |
| 2135 | Ret.Features.push_back("-" + Feature.split("-").second.str()); |
| 2136 | else |
| 2137 | Ret.Features.push_back("+" + Feature.str()); |
| 2138 | } |
| 2139 | return Ret; |
| 2140 | } |
| 2141 | }]; |
| 2142 | } |
| 2143 | |
| 2144 | def MinVectorWidth : InheritableAttr { |
| 2145 | let Spellings = [Clang<"min_vector_width">]; |
| 2146 | let Args = [UnsignedArgument<"VectorWidth">]; |
| 2147 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 2148 | let Documentation = [MinVectorWidthDocs]; |
| 2149 | } |
| 2150 | |
| 2151 | def TransparentUnion : InheritableAttr { |
| 2152 | let Spellings = [GCC<"transparent_union">]; |
| 2153 | // let Subjects = SubjectList<[Record, TypedefName]>; |
| 2154 | let Documentation = [TransparentUnionDocs]; |
| 2155 | let LangOpts = [COnly]; |
| 2156 | } |
| 2157 | |
| 2158 | def Unavailable : InheritableAttr { |
| 2159 | let Spellings = [Clang<"unavailable">]; |
| 2160 | let Args = [StringArgument<"Message", 1>, |
| 2161 | EnumArgument<"ImplicitReason", "ImplicitReason", |
| 2162 | ["", "", "", ""], |
| 2163 | ["IR_None", |
| 2164 | "IR_ARCForbiddenType", |
| 2165 | "IR_ForbiddenWeak", |
| 2166 | "IR_ARCForbiddenConversion", |
| 2167 | "IR_ARCInitReturnsUnrelated", |
| 2168 | "IR_ARCFieldWithOwnership"], 1, /*fake*/ 1>]; |
| 2169 | let Documentation = [Undocumented]; |
| 2170 | } |
| 2171 | |
| 2172 | def DiagnoseIf : InheritableAttr { |
| 2173 | // Does not have a [[]] spelling because this attribute requires the ability |
| 2174 | // to parse function arguments but the attribute is not written in the type |
| 2175 | // position. |
| 2176 | let Spellings = [GNU<"diagnose_if">]; |
| 2177 | let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>; |
| 2178 | let Args = [ExprArgument<"Cond">, StringArgument<"Message">, |
| 2179 | EnumArgument<"DiagnosticType", |
| 2180 | "DiagnosticType", |
| 2181 | ["error", "warning"], |
| 2182 | ["DT_Error", "DT_Warning"]>, |
| 2183 | BoolArgument<"ArgDependent", 0, /*fake*/ 1>, |
| 2184 | NamedArgument<"Parent", 0, /*fake*/ 1>]; |
| 2185 | let InheritEvenIfAlreadyPresent = 1; |
| 2186 | let LateParsed = 1; |
| 2187 | let AdditionalMembers = [{ |
| 2188 | bool isError() const { return diagnosticType == DT_Error; } |
| 2189 | bool isWarning() const { return diagnosticType == DT_Warning; } |
| 2190 | }]; |
| 2191 | let TemplateDependent = 1; |
| 2192 | let Documentation = [DiagnoseIfDocs]; |
| 2193 | } |
| 2194 | |
| 2195 | def ArcWeakrefUnavailable : InheritableAttr { |
| 2196 | let Spellings = [Clang<"objc_arc_weak_reference_unavailable">]; |
| 2197 | let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; |
| 2198 | let Documentation = [Undocumented]; |
| 2199 | } |
| 2200 | |
| 2201 | def ObjCGC : TypeAttr { |
| 2202 | let Spellings = [Clang<"objc_gc">]; |
| 2203 | let Args = [IdentifierArgument<"Kind">]; |
| 2204 | let Documentation = [Undocumented]; |
| 2205 | } |
| 2206 | |
| 2207 | def ObjCOwnership : DeclOrTypeAttr { |
| 2208 | let Spellings = [Clang<"objc_ownership">]; |
| 2209 | let Args = [IdentifierArgument<"Kind">]; |
| 2210 | let Documentation = [Undocumented]; |
| 2211 | } |
| 2212 | |
| 2213 | def ObjCRequiresPropertyDefs : InheritableAttr { |
| 2214 | let Spellings = [Clang<"objc_requires_property_definitions">]; |
| 2215 | let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; |
| 2216 | let Documentation = [Undocumented]; |
| 2217 | } |
| 2218 | |
| 2219 | def Unused : InheritableAttr { |
| 2220 | let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">, |
| 2221 | C2x<"", "maybe_unused">]; |
| 2222 | let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label, |
| 2223 | Field, ObjCMethod, FunctionLike]>; |
| 2224 | let Documentation = [WarnMaybeUnusedDocs]; |
| 2225 | } |
| 2226 | |
| 2227 | def Used : InheritableAttr { |
| 2228 | let Spellings = [GCC<"used">]; |
| 2229 | let Subjects = SubjectList<[NonLocalVar, Function, ObjCMethod]>; |
| 2230 | let Documentation = [Undocumented]; |
| 2231 | } |
| 2232 | |
| 2233 | def Uuid : InheritableAttr { |
| 2234 | let Spellings = [Declspec<"uuid">, Microsoft<"uuid">]; |
| 2235 | let Args = [StringArgument<"Guid">]; |
| 2236 | let Subjects = SubjectList<[Record, Enum]>; |
| 2237 | // FIXME: Allow expressing logical AND for LangOpts. Our condition should be: |
| 2238 | // CPlusPlus && (MicrosoftExt || Borland) |
| 2239 | let LangOpts = [MicrosoftExt, Borland]; |
| 2240 | let Documentation = [Undocumented]; |
| 2241 | } |
| 2242 | |
| 2243 | def VectorSize : TypeAttr { |
| 2244 | let Spellings = [GCC<"vector_size">]; |
| 2245 | let Args = [ExprArgument<"NumBytes">]; |
| 2246 | let Documentation = [Undocumented]; |
| 2247 | // Represented as VectorType instead. |
| 2248 | let ASTNode = 0; |
| 2249 | } |
| 2250 | |
| 2251 | def VecTypeHint : InheritableAttr { |
| 2252 | // Does not have a [[]] spelling because it is an OpenCL-related attribute. |
| 2253 | let Spellings = [GNU<"vec_type_hint">]; |
| 2254 | let Args = [TypeArgument<"TypeHint">]; |
| 2255 | let Subjects = SubjectList<[Function], ErrorDiag>; |
| 2256 | let Documentation = [Undocumented]; |
| 2257 | } |
| 2258 | |
| 2259 | def Visibility : InheritableAttr { |
| 2260 | let Clone = 0; |
| 2261 | let Spellings = [GCC<"visibility">]; |
| 2262 | let Args = [EnumArgument<"Visibility", "VisibilityType", |
| 2263 | ["default", "hidden", "internal", "protected"], |
| 2264 | ["Default", "Hidden", "Hidden", "Protected"]>]; |
| 2265 | let MeaningfulToClassTemplateDefinition = 1; |
| 2266 | let Documentation = [Undocumented]; |
| 2267 | } |
| 2268 | |
| 2269 | def TypeVisibility : InheritableAttr { |
| 2270 | let Clone = 0; |
| 2271 | let Spellings = [Clang<"type_visibility">]; |
| 2272 | let Args = [EnumArgument<"Visibility", "VisibilityType", |
| 2273 | ["default", "hidden", "internal", "protected"], |
| 2274 | ["Default", "Hidden", "Hidden", "Protected"]>]; |
| 2275 | // let Subjects = [Tag, ObjCInterface, Namespace]; |
| 2276 | let Documentation = [Undocumented]; |
| 2277 | } |
| 2278 | |
| 2279 | def VecReturn : InheritableAttr { |
| 2280 | // This attribute does not have a C [[]] spelling because it only appertains |
| 2281 | // to C++ struct/class/union. |
| 2282 | // FIXME: should this attribute have a CPlusPlus language option? |
| 2283 | let Spellings = [Clang<"vecreturn", 0>]; |
| 2284 | let Subjects = SubjectList<[CXXRecord], ErrorDiag>; |
| 2285 | let Documentation = [Undocumented]; |
| 2286 | } |
| 2287 | |
| 2288 | def WarnUnused : InheritableAttr { |
| 2289 | let Spellings = [GCC<"warn_unused">]; |
| 2290 | let Subjects = SubjectList<[Record]>; |
| 2291 | let Documentation = [Undocumented]; |
| 2292 | } |
| 2293 | |
| 2294 | def WarnUnusedResult : InheritableAttr { |
| 2295 | let Spellings = [CXX11<"", "nodiscard", 201603>, C2x<"", "nodiscard">, |
| 2296 | CXX11<"clang", "warn_unused_result">, |
| 2297 | GCC<"warn_unused_result">]; |
| 2298 | let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike]>; |
| 2299 | let Documentation = [WarnUnusedResultsDocs]; |
| 2300 | } |
| 2301 | |
| 2302 | def Weak : InheritableAttr { |
| 2303 | let Spellings = [GCC<"weak">]; |
| 2304 | let Subjects = SubjectList<[Var, Function, CXXRecord]>; |
| 2305 | let Documentation = [Undocumented]; |
| 2306 | } |
| 2307 | |
| 2308 | def WeakImport : InheritableAttr { |
| 2309 | let Spellings = [Clang<"weak_import">]; |
| 2310 | let Documentation = [Undocumented]; |
| 2311 | } |
| 2312 | |
| 2313 | def WeakRef : InheritableAttr { |
| 2314 | let Spellings = [GCC<"weakref">]; |
| 2315 | // A WeakRef that has an argument is treated as being an AliasAttr |
| 2316 | let Args = [StringArgument<"Aliasee", 1>]; |
| 2317 | let Subjects = SubjectList<[Var, Function], ErrorDiag>; |
| 2318 | let Documentation = [Undocumented]; |
| 2319 | } |
| 2320 | |
| 2321 | def LTOVisibilityPublic : InheritableAttr { |
| 2322 | let Spellings = [Clang<"lto_visibility_public">]; |
| 2323 | let Subjects = SubjectList<[Record]>; |
| 2324 | let Documentation = [LTOVisibilityDocs]; |
| 2325 | } |
| 2326 | |
| 2327 | def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> { |
| 2328 | // NOTE: If you add any additional spellings, ARMInterrupt's, |
| 2329 | // MSP430Interrupt's and MipsInterrupt's spellings must match. |
| 2330 | let Spellings = [GCC<"interrupt">]; |
| 2331 | let Subjects = SubjectList<[HasFunctionProto]>; |
| 2332 | let ParseKind = "Interrupt"; |
| 2333 | let HasCustomParsing = 1; |
| 2334 | let Documentation = [Undocumented]; |
| 2335 | } |
| 2336 | |
| 2337 | def AnyX86NoCallerSavedRegisters : InheritableAttr, |
| 2338 | TargetSpecificAttr<TargetAnyX86> { |
| 2339 | let Spellings = [GCC<"no_caller_saved_registers">]; |
| 2340 | let Documentation = [AnyX86NoCallerSavedRegistersDocs]; |
| 2341 | } |
| 2342 | |
| 2343 | def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86>{ |
| 2344 | let Spellings = [GCC<"nocf_check">]; |
| 2345 | let Subjects = SubjectList<[FunctionLike]>; |
| 2346 | let Documentation = [AnyX86NoCfCheckDocs]; |
| 2347 | } |
| 2348 | |
| 2349 | def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetAnyX86> { |
| 2350 | let Spellings = [GCC<"force_align_arg_pointer">]; |
| 2351 | // Technically, this appertains to a FunctionDecl, but the target-specific |
| 2352 | // code silently allows anything function-like (such as typedefs or function |
| 2353 | // pointers), but does not apply the attribute to them. |
| 2354 | let Documentation = [X86ForceAlignArgPointerDocs]; |
| 2355 | } |
| 2356 | |
| 2357 | def NoSanitize : InheritableAttr { |
| 2358 | let Spellings = [Clang<"no_sanitize">]; |
| 2359 | let Args = [VariadicStringArgument<"Sanitizers">]; |
| 2360 | let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag>; |
| 2361 | let Documentation = [NoSanitizeDocs]; |
| 2362 | let AdditionalMembers = [{ |
| 2363 | SanitizerMask getMask() const { |
| 2364 | SanitizerMask Mask; |
| 2365 | for (auto SanitizerName : sanitizers()) { |
| 2366 | SanitizerMask ParsedMask = |
| 2367 | parseSanitizerValue(SanitizerName, /*AllowGroups=*/true); |
| 2368 | Mask |= expandSanitizerGroups(ParsedMask); |
| 2369 | } |
| 2370 | return Mask; |
| 2371 | } |
| 2372 | }]; |
| 2373 | } |
| 2374 | |
| 2375 | // Attributes to disable a specific sanitizer. No new sanitizers should be added |
| 2376 | // to this list; the no_sanitize attribute should be extended instead. |
| 2377 | def NoSanitizeSpecific : InheritableAttr { |
| 2378 | let Spellings = [GCC<"no_address_safety_analysis">, |
| 2379 | GCC<"no_sanitize_address">, |
| 2380 | GCC<"no_sanitize_thread">, |
| 2381 | Clang<"no_sanitize_memory">]; |
| 2382 | let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>; |
| 2383 | let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs, |
| 2384 | NoSanitizeMemoryDocs]; |
| 2385 | let ASTNode = 0; |
| 2386 | } |
| 2387 | |
| 2388 | // C/C++ Thread safety attributes (e.g. for deadlock, data race checking) |
| 2389 | // Not all of these attributes will be given a [[]] spelling. The attributes |
| 2390 | // which require access to function parameter names cannot use the [[]] spelling |
| 2391 | // because they are not written in the type position. Some attributes are given |
| 2392 | // an updated captability-based name and the older name will only be supported |
| 2393 | // under the GNU-style spelling. |
| 2394 | def GuardedVar : InheritableAttr { |
| 2395 | let Spellings = [Clang<"guarded_var", 0>]; |
| 2396 | let Subjects = SubjectList<[Field, SharedVar]>; |
| 2397 | let Documentation = [Undocumented]; |
| 2398 | } |
| 2399 | |
| 2400 | def PtGuardedVar : InheritableAttr { |
| 2401 | let Spellings = [Clang<"pt_guarded_var", 0>]; |
| 2402 | let Subjects = SubjectList<[Field, SharedVar]>; |
| 2403 | let Documentation = [Undocumented]; |
| 2404 | } |
| 2405 | |
| 2406 | def Lockable : InheritableAttr { |
| 2407 | let Spellings = [GNU<"lockable">]; |
| 2408 | let Subjects = SubjectList<[Record]>; |
| 2409 | let Documentation = [Undocumented]; |
| 2410 | let ASTNode = 0; // Replaced by Capability |
| 2411 | } |
| 2412 | |
| 2413 | def ScopedLockable : InheritableAttr { |
| 2414 | let Spellings = [Clang<"scoped_lockable", 0>]; |
| 2415 | let Subjects = SubjectList<[Record]>; |
| 2416 | let Documentation = [Undocumented]; |
| 2417 | } |
| 2418 | |
| 2419 | def Capability : InheritableAttr { |
| 2420 | let Spellings = [Clang<"capability", 0>, Clang<"shared_capability", 0>]; |
| 2421 | let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>; |
| 2422 | let Args = [StringArgument<"Name">]; |
| 2423 | let Accessors = [Accessor<"isShared", |
| 2424 | [Clang<"shared_capability", 0>]>]; |
| 2425 | let Documentation = [Undocumented]; |
| 2426 | let AdditionalMembers = [{ |
| 2427 | bool isMutex() const { return getName().equals_lower("mutex"); } |
| 2428 | bool isRole() const { return getName().equals_lower("role"); } |
| 2429 | }]; |
| 2430 | } |
| 2431 | |
| 2432 | def AssertCapability : InheritableAttr { |
| 2433 | let Spellings = [Clang<"assert_capability", 0>, |
| 2434 | Clang<"assert_shared_capability", 0>]; |
| 2435 | let Subjects = SubjectList<[Function]>; |
| 2436 | let LateParsed = 1; |
| 2437 | let TemplateDependent = 1; |
| 2438 | let ParseArgumentsAsUnevaluated = 1; |
| 2439 | let InheritEvenIfAlreadyPresent = 1; |
| 2440 | let Args = [VariadicExprArgument<"Args">]; |
| 2441 | let Accessors = [Accessor<"isShared", |
| 2442 | [Clang<"assert_shared_capability", 0>]>]; |
| 2443 | let Documentation = [AssertCapabilityDocs]; |
| 2444 | } |
| 2445 | |
| 2446 | def AcquireCapability : InheritableAttr { |
| 2447 | let Spellings = [Clang<"acquire_capability", 0>, |
| 2448 | Clang<"acquire_shared_capability", 0>, |
| 2449 | GNU<"exclusive_lock_function">, |
| 2450 | GNU<"shared_lock_function">]; |
| 2451 | let Subjects = SubjectList<[Function]>; |
| 2452 | let LateParsed = 1; |
| 2453 | let TemplateDependent = 1; |
| 2454 | let ParseArgumentsAsUnevaluated = 1; |
| 2455 | let InheritEvenIfAlreadyPresent = 1; |
| 2456 | let Args = [VariadicExprArgument<"Args">]; |
| 2457 | let Accessors = [Accessor<"isShared", |
| 2458 | [Clang<"acquire_shared_capability", 0>, |
| 2459 | GNU<"shared_lock_function">]>]; |
| 2460 | let Documentation = [AcquireCapabilityDocs]; |
| 2461 | } |
| 2462 | |
| 2463 | def TryAcquireCapability : InheritableAttr { |
| 2464 | let Spellings = [Clang<"try_acquire_capability", 0>, |
| 2465 | Clang<"try_acquire_shared_capability", 0>]; |
| 2466 | let Subjects = SubjectList<[Function], |
| 2467 | ErrorDiag>; |
| 2468 | let LateParsed = 1; |
| 2469 | let TemplateDependent = 1; |
| 2470 | let ParseArgumentsAsUnevaluated = 1; |
| 2471 | let InheritEvenIfAlreadyPresent = 1; |
| 2472 | let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; |
| 2473 | let Accessors = [Accessor<"isShared", |
| 2474 | [Clang<"try_acquire_shared_capability", 0>]>]; |
| 2475 | let Documentation = [TryAcquireCapabilityDocs]; |
| 2476 | } |
| 2477 | |
| 2478 | def ReleaseCapability : InheritableAttr { |
| 2479 | let Spellings = [Clang<"release_capability", 0>, |
| 2480 | Clang<"release_shared_capability", 0>, |
| 2481 | Clang<"release_generic_capability", 0>, |
| 2482 | Clang<"unlock_function", 0>]; |
| 2483 | let Subjects = SubjectList<[Function]>; |
| 2484 | let LateParsed = 1; |
| 2485 | let TemplateDependent = 1; |
| 2486 | let ParseArgumentsAsUnevaluated = 1; |
| 2487 | let InheritEvenIfAlreadyPresent = 1; |
| 2488 | let Args = [VariadicExprArgument<"Args">]; |
| 2489 | let Accessors = [Accessor<"isShared", |
| 2490 | [Clang<"release_shared_capability", 0>]>, |
| 2491 | Accessor<"isGeneric", |
| 2492 | [Clang<"release_generic_capability", 0>, |
| 2493 | Clang<"unlock_function", 0>]>]; |
| 2494 | let Documentation = [ReleaseCapabilityDocs]; |
| 2495 | } |
| 2496 | |
| 2497 | def RequiresCapability : InheritableAttr { |
| 2498 | let Spellings = [Clang<"requires_capability", 0>, |
| 2499 | Clang<"exclusive_locks_required", 0>, |
| 2500 | Clang<"requires_shared_capability", 0>, |
| 2501 | Clang<"shared_locks_required", 0>]; |
| 2502 | let Args = [VariadicExprArgument<"Args">]; |
| 2503 | let LateParsed = 1; |
| 2504 | let TemplateDependent = 1; |
| 2505 | let ParseArgumentsAsUnevaluated = 1; |
| 2506 | let InheritEvenIfAlreadyPresent = 1; |
| 2507 | let Subjects = SubjectList<[Function]>; |
| 2508 | let Accessors = [Accessor<"isShared", [Clang<"requires_shared_capability", 0>, |
| 2509 | Clang<"shared_locks_required", 0>]>]; |
| 2510 | let Documentation = [Undocumented]; |
| 2511 | } |
| 2512 | |
| 2513 | def NoThreadSafetyAnalysis : InheritableAttr { |
| 2514 | let Spellings = [Clang<"no_thread_safety_analysis">]; |
| 2515 | let Subjects = SubjectList<[Function]>; |
| 2516 | let Documentation = [Undocumented]; |
| 2517 | } |
| 2518 | |
| 2519 | def GuardedBy : InheritableAttr { |
| 2520 | let Spellings = [GNU<"guarded_by">]; |
| 2521 | let Args = [ExprArgument<"Arg">]; |
| 2522 | let LateParsed = 1; |
| 2523 | let TemplateDependent = 1; |
| 2524 | let ParseArgumentsAsUnevaluated = 1; |
| 2525 | let InheritEvenIfAlreadyPresent = 1; |
| 2526 | let Subjects = SubjectList<[Field, SharedVar]>; |
| 2527 | let Documentation = [Undocumented]; |
| 2528 | } |
| 2529 | |
| 2530 | def PtGuardedBy : InheritableAttr { |
| 2531 | let Spellings = [GNU<"pt_guarded_by">]; |
| 2532 | let Args = [ExprArgument<"Arg">]; |
| 2533 | let LateParsed = 1; |
| 2534 | let TemplateDependent = 1; |
| 2535 | let ParseArgumentsAsUnevaluated = 1; |
| 2536 | let InheritEvenIfAlreadyPresent = 1; |
| 2537 | let Subjects = SubjectList<[Field, SharedVar]>; |
| 2538 | let Documentation = [Undocumented]; |
| 2539 | } |
| 2540 | |
| 2541 | def AcquiredAfter : InheritableAttr { |
| 2542 | let Spellings = [GNU<"acquired_after">]; |
| 2543 | let Args = [VariadicExprArgument<"Args">]; |
| 2544 | let LateParsed = 1; |
| 2545 | let TemplateDependent = 1; |
| 2546 | let ParseArgumentsAsUnevaluated = 1; |
| 2547 | let InheritEvenIfAlreadyPresent = 1; |
| 2548 | let Subjects = SubjectList<[Field, SharedVar]>; |
| 2549 | let Documentation = [Undocumented]; |
| 2550 | } |
| 2551 | |
| 2552 | def AcquiredBefore : InheritableAttr { |
| 2553 | let Spellings = [GNU<"acquired_before">]; |
| 2554 | let Args = [VariadicExprArgument<"Args">]; |
| 2555 | let LateParsed = 1; |
| 2556 | let TemplateDependent = 1; |
| 2557 | let ParseArgumentsAsUnevaluated = 1; |
| 2558 | let InheritEvenIfAlreadyPresent = 1; |
| 2559 | let Subjects = SubjectList<[Field, SharedVar]>; |
| 2560 | let Documentation = [Undocumented]; |
| 2561 | } |
| 2562 | |
| 2563 | def AssertExclusiveLock : InheritableAttr { |
| 2564 | let Spellings = [GNU<"assert_exclusive_lock">]; |
| 2565 | let Args = [VariadicExprArgument<"Args">]; |
| 2566 | let LateParsed = 1; |
| 2567 | let TemplateDependent = 1; |
| 2568 | let ParseArgumentsAsUnevaluated = 1; |
| 2569 | let InheritEvenIfAlreadyPresent = 1; |
| 2570 | let Subjects = SubjectList<[Function]>; |
| 2571 | let Documentation = [Undocumented]; |
| 2572 | } |
| 2573 | |
| 2574 | def AssertSharedLock : InheritableAttr { |
| 2575 | let Spellings = [GNU<"assert_shared_lock">]; |
| 2576 | let Args = [VariadicExprArgument<"Args">]; |
| 2577 | let LateParsed = 1; |
| 2578 | let TemplateDependent = 1; |
| 2579 | let ParseArgumentsAsUnevaluated = 1; |
| 2580 | let InheritEvenIfAlreadyPresent = 1; |
| 2581 | let Subjects = SubjectList<[Function]>; |
| 2582 | let Documentation = [Undocumented]; |
| 2583 | } |
| 2584 | |
| 2585 | // The first argument is an integer or boolean value specifying the return value |
| 2586 | // of a successful lock acquisition. |
| 2587 | def ExclusiveTrylockFunction : InheritableAttr { |
| 2588 | let Spellings = [GNU<"exclusive_trylock_function">]; |
| 2589 | let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; |
| 2590 | let LateParsed = 1; |
| 2591 | let TemplateDependent = 1; |
| 2592 | let ParseArgumentsAsUnevaluated = 1; |
| 2593 | let InheritEvenIfAlreadyPresent = 1; |
| 2594 | let Subjects = SubjectList<[Function]>; |
| 2595 | let Documentation = [Undocumented]; |
| 2596 | } |
| 2597 | |
| 2598 | // The first argument is an integer or boolean value specifying the return value |
| 2599 | // of a successful lock acquisition. |
| 2600 | def SharedTrylockFunction : InheritableAttr { |
| 2601 | let Spellings = [GNU<"shared_trylock_function">]; |
| 2602 | let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; |
| 2603 | let LateParsed = 1; |
| 2604 | let TemplateDependent = 1; |
| 2605 | let ParseArgumentsAsUnevaluated = 1; |
| 2606 | let InheritEvenIfAlreadyPresent = 1; |
| 2607 | let Subjects = SubjectList<[Function]>; |
| 2608 | let Documentation = [Undocumented]; |
| 2609 | } |
| 2610 | |
| 2611 | def LockReturned : InheritableAttr { |
| 2612 | let Spellings = [GNU<"lock_returned">]; |
| 2613 | let Args = [ExprArgument<"Arg">]; |
| 2614 | let LateParsed = 1; |
| 2615 | let TemplateDependent = 1; |
| 2616 | let ParseArgumentsAsUnevaluated = 1; |
| 2617 | let Subjects = SubjectList<[Function]>; |
| 2618 | let Documentation = [Undocumented]; |
| 2619 | } |
| 2620 | |
| 2621 | def LocksExcluded : InheritableAttr { |
| 2622 | let Spellings = [GNU<"locks_excluded">]; |
| 2623 | let Args = [VariadicExprArgument<"Args">]; |
| 2624 | let LateParsed = 1; |
| 2625 | let TemplateDependent = 1; |
| 2626 | let ParseArgumentsAsUnevaluated = 1; |
| 2627 | let InheritEvenIfAlreadyPresent = 1; |
| 2628 | let Subjects = SubjectList<[Function]>; |
| 2629 | let Documentation = [Undocumented]; |
| 2630 | } |
| 2631 | |
| 2632 | // C/C++ consumed attributes. |
| 2633 | |
| 2634 | def Consumable : InheritableAttr { |
| 2635 | // This attribute does not have a C [[]] spelling because it only appertains |
| 2636 | // to C++ struct/class/union. |
| 2637 | // FIXME: should this attribute have a CPlusPlus language option? |
| 2638 | let Spellings = [Clang<"consumable", 0>]; |
| 2639 | let Subjects = SubjectList<[CXXRecord]>; |
| 2640 | let Args = [EnumArgument<"DefaultState", "ConsumedState", |
| 2641 | ["unknown", "consumed", "unconsumed"], |
| 2642 | ["Unknown", "Consumed", "Unconsumed"]>]; |
| 2643 | let Documentation = [ConsumableDocs]; |
| 2644 | } |
| 2645 | |
| 2646 | def ConsumableAutoCast : InheritableAttr { |
| 2647 | // This attribute does not have a C [[]] spelling because it only appertains |
| 2648 | // to C++ struct/class/union. |
| 2649 | // FIXME: should this attribute have a CPlusPlus language option? |
| 2650 | let Spellings = [Clang<"consumable_auto_cast_state", 0>]; |
| 2651 | let Subjects = SubjectList<[CXXRecord]>; |
| 2652 | let Documentation = [Undocumented]; |
| 2653 | } |
| 2654 | |
| 2655 | def ConsumableSetOnRead : InheritableAttr { |
| 2656 | // This attribute does not have a C [[]] spelling because it only appertains |
| 2657 | // to C++ struct/class/union. |
| 2658 | // FIXME: should this attribute have a CPlusPlus language option? |
| 2659 | let Spellings = [Clang<"consumable_set_state_on_read", 0>]; |
| 2660 | let Subjects = SubjectList<[CXXRecord]>; |
| 2661 | let Documentation = [Undocumented]; |
| 2662 | } |
| 2663 | |
| 2664 | def CallableWhen : InheritableAttr { |
| 2665 | // This attribute does not have a C [[]] spelling because it only appertains |
| 2666 | // to C++ function (but doesn't require it to be a member function). |
| 2667 | // FIXME: should this attribute have a CPlusPlus language option? |
| 2668 | let Spellings = [Clang<"callable_when", 0>]; |
| 2669 | let Subjects = SubjectList<[CXXMethod]>; |
| 2670 | let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState", |
| 2671 | ["unknown", "consumed", "unconsumed"], |
| 2672 | ["Unknown", "Consumed", "Unconsumed"]>]; |
| 2673 | let Documentation = [CallableWhenDocs]; |
| 2674 | } |
| 2675 | |
| 2676 | def ParamTypestate : InheritableAttr { |
| 2677 | // This attribute does not have a C [[]] spelling because it only appertains |
| 2678 | // to a parameter whose type is a consumable C++ class. |
| 2679 | // FIXME: should this attribute have a CPlusPlus language option? |
| 2680 | let Spellings = [Clang<"param_typestate", 0>]; |
| 2681 | let Subjects = SubjectList<[ParmVar]>; |
| 2682 | let Args = [EnumArgument<"ParamState", "ConsumedState", |
| 2683 | ["unknown", "consumed", "unconsumed"], |
| 2684 | ["Unknown", "Consumed", "Unconsumed"]>]; |
| 2685 | let Documentation = [ParamTypestateDocs]; |
| 2686 | } |
| 2687 | |
| 2688 | def ReturnTypestate : InheritableAttr { |
| 2689 | // This attribute does not have a C [[]] spelling because it only appertains |
| 2690 | // to a parameter or function return type that is a consumable C++ class. |
| 2691 | // FIXME: should this attribute have a CPlusPlus language option? |
| 2692 | let Spellings = [Clang<"return_typestate", 0>]; |
| 2693 | let Subjects = SubjectList<[Function, ParmVar]>; |
| 2694 | let Args = [EnumArgument<"State", "ConsumedState", |
| 2695 | ["unknown", "consumed", "unconsumed"], |
| 2696 | ["Unknown", "Consumed", "Unconsumed"]>]; |
| 2697 | let Documentation = [ReturnTypestateDocs]; |
| 2698 | } |
| 2699 | |
| 2700 | def SetTypestate : InheritableAttr { |
| 2701 | // This attribute does not have a C [[]] spelling because it only appertains |
| 2702 | // to C++ function (but doesn't require it to be a member function). |
| 2703 | // FIXME: should this attribute have a CPlusPlus language option? |
| 2704 | let Spellings = [Clang<"set_typestate", 0>]; |
| 2705 | let Subjects = SubjectList<[CXXMethod]>; |
| 2706 | let Args = [EnumArgument<"NewState", "ConsumedState", |
| 2707 | ["unknown", "consumed", "unconsumed"], |
| 2708 | ["Unknown", "Consumed", "Unconsumed"]>]; |
| 2709 | let Documentation = [SetTypestateDocs]; |
| 2710 | } |
| 2711 | |
| 2712 | def TestTypestate : InheritableAttr { |
| 2713 | // This attribute does not have a C [[]] spelling because it only appertains |
| 2714 | // to C++ function (but doesn't require it to be a member function). |
| 2715 | // FIXME: should this attribute have a CPlusPlus language option? |
| 2716 | let Spellings = [Clang<"test_typestate", 0>]; |
| 2717 | let Subjects = SubjectList<[CXXMethod]>; |
| 2718 | let Args = [EnumArgument<"TestState", "ConsumedState", |
| 2719 | ["consumed", "unconsumed"], |
| 2720 | ["Consumed", "Unconsumed"]>]; |
| 2721 | let Documentation = [TestTypestateDocs]; |
| 2722 | } |
| 2723 | |
| 2724 | // Type safety attributes for `void *' pointers and type tags. |
| 2725 | |
| 2726 | def ArgumentWithTypeTag : InheritableAttr { |
| 2727 | let Spellings = [Clang<"argument_with_type_tag">, |
| 2728 | Clang<"pointer_with_type_tag">]; |
| 2729 | let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>; |
| 2730 | let Args = [IdentifierArgument<"ArgumentKind">, |
| 2731 | ParamIdxArgument<"ArgumentIdx">, |
| 2732 | ParamIdxArgument<"TypeTagIdx">, |
| 2733 | BoolArgument<"IsPointer", /*opt*/0, /*fake*/1>]; |
| 2734 | let Documentation = [ArgumentWithTypeTagDocs, PointerWithTypeTagDocs]; |
| 2735 | } |
| 2736 | |
| 2737 | def TypeTagForDatatype : InheritableAttr { |
| 2738 | let Spellings = [Clang<"type_tag_for_datatype">]; |
| 2739 | let Args = [IdentifierArgument<"ArgumentKind">, |
| 2740 | TypeArgument<"MatchingCType">, |
| 2741 | BoolArgument<"LayoutCompatible">, |
| 2742 | BoolArgument<"MustBeNull">]; |
| 2743 | // let Subjects = SubjectList<[Var], ErrorDiag>; |
| 2744 | let HasCustomParsing = 1; |
| 2745 | let Documentation = [TypeTagForDatatypeDocs]; |
| 2746 | } |
| 2747 | |
| 2748 | // Microsoft-related attributes |
| 2749 | |
| 2750 | def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> { |
| 2751 | let Spellings = [Declspec<"novtable">]; |
| 2752 | let Subjects = SubjectList<[CXXRecord]>; |
| 2753 | let Documentation = [MSNoVTableDocs]; |
| 2754 | } |
| 2755 | |
| 2756 | def : IgnoredAttr { |
| 2757 | let Spellings = [Declspec<"property">]; |
| 2758 | } |
| 2759 | |
| 2760 | def MSAllocator : InheritableAttr { |
| 2761 | let Spellings = [Declspec<"allocator">]; |
| 2762 | let Subjects = SubjectList<[Function]>; |
| 2763 | let Documentation = [MSAllocatorDocs]; |
| 2764 | } |
| 2765 | |
| 2766 | def MSStruct : InheritableAttr { |
| 2767 | let Spellings = [GCC<"ms_struct">]; |
| 2768 | let Subjects = SubjectList<[Record]>; |
| 2769 | let Documentation = [Undocumented]; |
| 2770 | } |
| 2771 | |
| 2772 | def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> { |
| 2773 | let Spellings = [Declspec<"dllexport">, GCC<"dllexport">]; |
| 2774 | let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; |
| 2775 | let Documentation = [DLLExportDocs]; |
| 2776 | } |
| 2777 | |
| 2778 | def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> { |
| 2779 | // This attribute is used internally only when -fno-dllexport-inlines is |
| 2780 | // passed. This attribute is added to inline function of class having |
| 2781 | // dllexport attribute. And if the function has static local variables, this |
| 2782 | // attribute is used to whether the variables are exported or not. Also if |
| 2783 | // function has local static variables, the function is dllexported too. |
| 2784 | let Spellings = []; |
| 2785 | let Subjects = SubjectList<[Function]>; |
| 2786 | let Documentation = [Undocumented]; |
| 2787 | } |
| 2788 | |
| 2789 | def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> { |
| 2790 | let Spellings = [Declspec<"dllimport">, GCC<"dllimport">]; |
| 2791 | let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; |
| 2792 | let Documentation = [DLLImportDocs]; |
| 2793 | |
| 2794 | |
| 2795 | let AdditionalMembers = [{ |
| 2796 | private: |
| 2797 | bool PropagatedToBaseTemplate = false; |
| 2798 | |
| 2799 | public: |
| 2800 | void setPropagatedToBaseTemplate() { PropagatedToBaseTemplate = true; } |
| 2801 | bool wasPropagatedToBaseTemplate() { return PropagatedToBaseTemplate; } |
| 2802 | }]; |
| 2803 | } |
| 2804 | |
| 2805 | def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> { |
| 2806 | // This attribute is used internally only when -fno-dllexport-inlines is |
| 2807 | // passed. This attribute is added to inline function of class having |
| 2808 | // dllimport attribute. And if the function has static local variables, this |
| 2809 | // attribute is used to whether the variables are imported or not. |
| 2810 | let Spellings = []; |
| 2811 | let Subjects = SubjectList<[Function]>; |
| 2812 | let Documentation = [Undocumented]; |
| 2813 | } |
| 2814 | |
| 2815 | def SelectAny : InheritableAttr { |
| 2816 | let Spellings = [Declspec<"selectany">, GCC<"selectany">]; |
| 2817 | let Documentation = [SelectAnyDocs]; |
| 2818 | } |
| 2819 | |
| 2820 | def Thread : Attr { |
| 2821 | let Spellings = [Declspec<"thread">]; |
| 2822 | let LangOpts = [MicrosoftExt]; |
| 2823 | let Documentation = [ThreadDocs]; |
| 2824 | let Subjects = SubjectList<[Var]>; |
| 2825 | } |
| 2826 | |
| 2827 | def Win64 : IgnoredAttr { |
| 2828 | let Spellings = [Keyword<"__w64">]; |
| 2829 | let LangOpts = [MicrosoftExt]; |
| 2830 | } |
| 2831 | |
| 2832 | def Ptr32 : TypeAttr { |
| 2833 | let Spellings = [Keyword<"__ptr32">]; |
| 2834 | let Documentation = [Undocumented]; |
| 2835 | } |
| 2836 | |
| 2837 | def Ptr64 : TypeAttr { |
| 2838 | let Spellings = [Keyword<"__ptr64">]; |
| 2839 | let Documentation = [Undocumented]; |
| 2840 | } |
| 2841 | |
| 2842 | def SPtr : TypeAttr { |
| 2843 | let Spellings = [Keyword<"__sptr">]; |
| 2844 | let Documentation = [Undocumented]; |
| 2845 | } |
| 2846 | |
| 2847 | def UPtr : TypeAttr { |
| 2848 | let Spellings = [Keyword<"__uptr">]; |
| 2849 | let Documentation = [Undocumented]; |
| 2850 | } |
| 2851 | |
| 2852 | def MSInheritance : InheritableAttr { |
| 2853 | let LangOpts = [MicrosoftExt]; |
| 2854 | let Args = [DefaultBoolArgument<"BestCase", /*default*/1, /*fake*/1>]; |
| 2855 | let Spellings = [Keyword<"__single_inheritance">, |
| 2856 | Keyword<"__multiple_inheritance">, |
| 2857 | Keyword<"__virtual_inheritance">, |
| 2858 | Keyword<"__unspecified_inheritance">]; |
| 2859 | let AdditionalMembers = [{ |
| 2860 | static bool hasVBPtrOffsetField(Spelling Inheritance) { |
| 2861 | return Inheritance == Keyword_unspecified_inheritance; |
| 2862 | } |
| 2863 | |
| 2864 | // Only member pointers to functions need a this adjustment, since it can be |
| 2865 | // combined with the field offset for data pointers. |
| 2866 | static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) { |
| 2867 | return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance; |
| 2868 | } |
| 2869 | |
| 2870 | static bool hasVBTableOffsetField(Spelling Inheritance) { |
| 2871 | return Inheritance >= Keyword_virtual_inheritance; |
| 2872 | } |
| 2873 | |
| 2874 | static bool hasOnlyOneField(bool IsMemberFunction, |
| 2875 | Spelling Inheritance) { |
| 2876 | if (IsMemberFunction) |
| 2877 | return Inheritance <= Keyword_single_inheritance; |
| 2878 | return Inheritance <= Keyword_multiple_inheritance; |
| 2879 | } |
| 2880 | }]; |
| 2881 | let Documentation = [MSInheritanceDocs]; |
| 2882 | } |
| 2883 | |
| 2884 | def MSVtorDisp : InheritableAttr { |
| 2885 | // This attribute has no spellings as it is only ever created implicitly. |
| 2886 | let Spellings = []; |
| 2887 | let Args = [UnsignedArgument<"vdm">]; |
| 2888 | let SemaHandler = 0; |
| 2889 | |
| 2890 | let AdditionalMembers = [{ |
| 2891 | enum Mode { |
| 2892 | Never, |
| 2893 | ForVBaseOverride, |
| 2894 | ForVFTable |
| 2895 | }; |
| 2896 | |
| 2897 | Mode getVtorDispMode() const { return Mode(vdm); } |
| 2898 | }]; |
| 2899 | let Documentation = [Undocumented]; |
| 2900 | } |
| 2901 | |
| 2902 | def InitSeg : Attr { |
| 2903 | let Spellings = [Pragma<"", "init_seg">]; |
| 2904 | let Args = [StringArgument<"Section">]; |
| 2905 | let SemaHandler = 0; |
| 2906 | let Documentation = [InitSegDocs]; |
| 2907 | let AdditionalMembers = [{ |
| 2908 | void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { |
| 2909 | OS << " (" << getSection() << ')'; |
| 2910 | } |
| 2911 | }]; |
| 2912 | } |
| 2913 | |
| 2914 | def LoopHint : Attr { |
| 2915 | /// #pragma clang loop <option> directive |
| 2916 | /// vectorize: vectorizes loop operations if State == Enable. |
| 2917 | /// vectorize_width: vectorize loop operations with width 'Value'. |
| 2918 | /// interleave: interleave multiple loop iterations if State == Enable. |
| 2919 | /// interleave_count: interleaves 'Value' loop iterations. |
| 2920 | /// unroll: fully unroll loop if State == Enable. |
| 2921 | /// unroll_count: unrolls loop 'Value' times. |
| 2922 | /// unroll_and_jam: attempt to unroll and jam loop if State == Enable. |
| 2923 | /// unroll_and_jam_count: unroll and jams loop 'Value' times. |
| 2924 | /// distribute: attempt to distribute loop if State == Enable. |
| 2925 | /// pipeline: disable pipelining loop if State == Disable. |
| 2926 | /// pipeline_initiation_interval: create loop schedule with initiation interval equal to 'Value'. |
| 2927 | |
| 2928 | /// #pragma unroll <argument> directive |
| 2929 | /// <no arg>: fully unrolls loop. |
| 2930 | /// boolean: fully unrolls loop if State == Enable. |
| 2931 | /// expression: unrolls loop 'Value' times. |
| 2932 | |
| 2933 | let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">, |
| 2934 | Pragma<"", "nounroll">, Pragma<"", "unroll_and_jam">, |
| 2935 | Pragma<"", "nounroll_and_jam">]; |
| 2936 | |
| 2937 | /// State of the loop optimization specified by the spelling. |
| 2938 | let Args = [EnumArgument<"Option", "OptionType", |
| 2939 | ["vectorize", "vectorize_width", "interleave", "interleave_count", |
| 2940 | "unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count", |
| 2941 | "pipeline", "pipeline_initiation_interval", "distribute"], |
| 2942 | ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount", |
| 2943 | "Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount", |
| 2944 | "PipelineDisabled", "PipelineInitiationInterval", "Distribute"]>, |
| 2945 | EnumArgument<"State", "LoopHintState", |
| 2946 | ["enable", "disable", "numeric", "assume_safety", "full"], |
| 2947 | ["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>, |
| 2948 | ExprArgument<"Value">]; |
| 2949 | |
| 2950 | let AdditionalMembers = [{ |
| 2951 | static const char *getOptionName(int Option) { |
| 2952 | switch(Option) { |
| 2953 | case Vectorize: return "vectorize"; |
| 2954 | case VectorizeWidth: return "vectorize_width"; |
| 2955 | case Interleave: return "interleave"; |
| 2956 | case InterleaveCount: return "interleave_count"; |
| 2957 | case Unroll: return "unroll"; |
| 2958 | case UnrollCount: return "unroll_count"; |
| 2959 | case UnrollAndJam: return "unroll_and_jam"; |
| 2960 | case UnrollAndJamCount: return "unroll_and_jam_count"; |
| 2961 | case PipelineDisabled: return "pipeline"; |
| 2962 | case PipelineInitiationInterval: return "pipeline_initiation_interval"; |
| 2963 | case Distribute: return "distribute"; |
| 2964 | } |
| 2965 | llvm_unreachable("Unhandled LoopHint option."); |
| 2966 | } |
| 2967 | |
| 2968 | void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { |
| 2969 | unsigned SpellingIndex = getSpellingListIndex(); |
| 2970 | // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or |
| 2971 | // "nounroll" is already emitted as the pragma name. |
| 2972 | if (SpellingIndex == Pragma_nounroll || SpellingIndex == Pragma_nounroll_and_jam) |
| 2973 | return; |
| 2974 | else if (SpellingIndex == Pragma_unroll || SpellingIndex == Pragma_unroll_and_jam) { |
| 2975 | OS << ' ' << getValueString(Policy); |
| 2976 | return; |
| 2977 | } |
| 2978 | |
| 2979 | assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); |
| 2980 | OS << ' ' << getOptionName(option) << getValueString(Policy); |
| 2981 | } |
| 2982 | |
| 2983 | // Return a string containing the loop hint argument including the |
| 2984 | // enclosing parentheses. |
| 2985 | std::string getValueString(const PrintingPolicy &Policy) const { |
| 2986 | std::string ValueName; |
| 2987 | llvm::raw_string_ostream OS(ValueName); |
| 2988 | OS << "("; |
| 2989 | if (state == Numeric) |
| 2990 | value->printPretty(OS, nullptr, Policy); |
| 2991 | else if (state == Enable) |
| 2992 | OS << "enable"; |
| 2993 | else if (state == Full) |
| 2994 | OS << "full"; |
| 2995 | else if (state == AssumeSafety) |
| 2996 | OS << "assume_safety"; |
| 2997 | else |
| 2998 | OS << "disable"; |
| 2999 | OS << ")"; |
| 3000 | return OS.str(); |
| 3001 | } |
| 3002 | |
| 3003 | // Return a string suitable for identifying this attribute in diagnostics. |
| 3004 | std::string getDiagnosticName(const PrintingPolicy &Policy) const { |
| 3005 | unsigned SpellingIndex = getSpellingListIndex(); |
| 3006 | if (SpellingIndex == Pragma_nounroll) |
| 3007 | return "#pragma nounroll"; |
| 3008 | else if (SpellingIndex == Pragma_unroll) |
| 3009 | return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : ""); |
| 3010 | else if (SpellingIndex == Pragma_nounroll_and_jam) |
| 3011 | return "#pragma nounroll_and_jam"; |
| 3012 | else if (SpellingIndex == Pragma_unroll_and_jam) |
| 3013 | return "#pragma unroll_and_jam" + |
| 3014 | (option == UnrollAndJamCount ? getValueString(Policy) : ""); |
| 3015 | |
| 3016 | assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); |
| 3017 | return getOptionName(option) + getValueString(Policy); |
| 3018 | } |
| 3019 | }]; |
| 3020 | |
| 3021 | let Documentation = [LoopHintDocs, UnrollHintDocs]; |
| 3022 | } |
| 3023 | |
| 3024 | def CapturedRecord : InheritableAttr { |
| 3025 | // This attribute has no spellings as it is only ever created implicitly. |
| 3026 | let Spellings = []; |
| 3027 | let SemaHandler = 0; |
| 3028 | let Documentation = [Undocumented]; |
| 3029 | } |
| 3030 | |
| 3031 | def OMPThreadPrivateDecl : InheritableAttr { |
| 3032 | // This attribute has no spellings as it is only ever created implicitly. |
| 3033 | let Spellings = []; |
| 3034 | let SemaHandler = 0; |
| 3035 | let Documentation = [Undocumented]; |
| 3036 | } |
| 3037 | |
| 3038 | def OMPCaptureNoInit : InheritableAttr { |
| 3039 | // This attribute has no spellings as it is only ever created implicitly. |
| 3040 | let Spellings = []; |
| 3041 | let SemaHandler = 0; |
| 3042 | let Documentation = [Undocumented]; |
| 3043 | } |
| 3044 | |
| 3045 | def OMPCaptureKind : Attr { |
| 3046 | // This attribute has no spellings as it is only ever created implicitly. |
| 3047 | let Spellings = []; |
| 3048 | let SemaHandler = 0; |
| 3049 | let Args = [UnsignedArgument<"CaptureKind">]; |
| 3050 | let Documentation = [Undocumented]; |
| 3051 | } |
| 3052 | |
| 3053 | def OMPReferencedVar : Attr { |
| 3054 | // This attribute has no spellings as it is only ever created implicitly. |
| 3055 | let Spellings = []; |
| 3056 | let SemaHandler = 0; |
| 3057 | let Args = [ExprArgument<"Ref">]; |
| 3058 | let Documentation = [Undocumented]; |
| 3059 | } |
| 3060 | |
| 3061 | def OMPDeclareSimdDecl : Attr { |
| 3062 | let Spellings = [Pragma<"omp", "declare simd">]; |
| 3063 | let Subjects = SubjectList<[Function]>; |
| 3064 | let SemaHandler = 0; |
| 3065 | let HasCustomParsing = 1; |
| 3066 | let Documentation = [OMPDeclareSimdDocs]; |
| 3067 | let Args = [ |
| 3068 | EnumArgument<"BranchState", "BranchStateTy", |
| 3069 | [ "", "inbranch", "notinbranch" ], |
| 3070 | [ "BS_Undefined", "BS_Inbranch", "BS_Notinbranch" ]>, |
| 3071 | ExprArgument<"Simdlen">, VariadicExprArgument<"Uniforms">, |
| 3072 | VariadicExprArgument<"Aligneds">, VariadicExprArgument<"Alignments">, |
| 3073 | VariadicExprArgument<"Linears">, VariadicUnsignedArgument<"Modifiers">, |
| 3074 | VariadicExprArgument<"Steps"> |
| 3075 | ]; |
| 3076 | let AdditionalMembers = [{ |
| 3077 | void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy) |
| 3078 | const { |
| 3079 | if (getBranchState() != BS_Undefined) |
| 3080 | OS << ' ' << ConvertBranchStateTyToStr(getBranchState()); |
| 3081 | if (auto *E = getSimdlen()) { |
| 3082 | OS << " simdlen("; |
| 3083 | E->printPretty(OS, nullptr, Policy); |
| 3084 | OS << ")"; |
| 3085 | } |
| 3086 | if (uniforms_size() > 0) { |
| 3087 | OS << " uniform"; |
| 3088 | StringRef Sep = "("; |
| 3089 | for (auto *E : uniforms()) { |
| 3090 | OS << Sep; |
| 3091 | E->printPretty(OS, nullptr, Policy); |
| 3092 | Sep = ", "; |
| 3093 | } |
| 3094 | OS << ")"; |
| 3095 | } |
| 3096 | alignments_iterator NI = alignments_begin(); |
| 3097 | for (auto *E : aligneds()) { |
| 3098 | OS << " aligned("; |
| 3099 | E->printPretty(OS, nullptr, Policy); |
| 3100 | if (*NI) { |
| 3101 | OS << ": "; |
| 3102 | (*NI)->printPretty(OS, nullptr, Policy); |
| 3103 | } |
| 3104 | OS << ")"; |
| 3105 | ++NI; |
| 3106 | } |
| 3107 | steps_iterator I = steps_begin(); |
| 3108 | modifiers_iterator MI = modifiers_begin(); |
| 3109 | for (auto *E : linears()) { |
| 3110 | OS << " linear("; |
| 3111 | if (*MI != OMPC_LINEAR_unknown) |
| 3112 | OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "("; |
| 3113 | E->printPretty(OS, nullptr, Policy); |
| 3114 | if (*MI != OMPC_LINEAR_unknown) |
| 3115 | OS << ")"; |
| 3116 | if (*I) { |
| 3117 | OS << ": "; |
| 3118 | (*I)->printPretty(OS, nullptr, Policy); |
| 3119 | } |
| 3120 | OS << ")"; |
| 3121 | ++I; |
| 3122 | ++MI; |
| 3123 | } |
| 3124 | } |
| 3125 | }]; |
| 3126 | } |
| 3127 | |
| 3128 | def OMPDeclareTargetDecl : InheritableAttr { |
| 3129 | let Spellings = [Pragma<"omp", "declare target">]; |
| 3130 | let SemaHandler = 0; |
| 3131 | let Subjects = SubjectList<[Function, SharedVar]>; |
| 3132 | let Documentation = [OMPDeclareTargetDocs]; |
| 3133 | let Args = [ |
| 3134 | EnumArgument<"MapType", "MapTypeTy", |
| 3135 | [ "to", "link" ], |
| 3136 | [ "MT_To", "MT_Link" ]> |
| 3137 | ]; |
| 3138 | let AdditionalMembers = [{ |
| 3139 | void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { |
| 3140 | // Use fake syntax because it is for testing and debugging purpose only. |
| 3141 | if (getMapType() != MT_To) |
| 3142 | OS << ' ' << ConvertMapTypeTyToStr(getMapType()); |
| 3143 | } |
| 3144 | static llvm::Optional<MapTypeTy> |
| 3145 | isDeclareTargetDeclaration(const ValueDecl *VD) { |
| 3146 | if (!VD->hasAttrs()) |
| 3147 | return llvm::None; |
| 3148 | if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>()) |
| 3149 | return Attr->getMapType(); |
| 3150 | |
| 3151 | return llvm::None; |
| 3152 | } |
| 3153 | }]; |
| 3154 | } |
| 3155 | |
| 3156 | def OMPAllocateDecl : InheritableAttr { |
| 3157 | // This attribute has no spellings as it is only ever created implicitly. |
| 3158 | let Spellings = []; |
| 3159 | let SemaHandler = 0; |
| 3160 | let Args = [ |
| 3161 | EnumArgument<"AllocatorType", "AllocatorTypeTy", |
| 3162 | [ |
| 3163 | "omp_default_mem_alloc", "omp_large_cap_mem_alloc", |
| 3164 | "omp_const_mem_alloc", "omp_high_bw_mem_alloc", |
| 3165 | "omp_low_lat_mem_alloc", "omp_cgroup_mem_alloc", |
| 3166 | "omp_pteam_mem_alloc", "omp_thread_mem_alloc", "" |
| 3167 | ], |
| 3168 | [ |
| 3169 | "OMPDefaultMemAlloc", "OMPLargeCapMemAlloc", |
| 3170 | "OMPConstMemAlloc", "OMPHighBWMemAlloc", "OMPLowLatMemAlloc", |
| 3171 | "OMPCGroupMemAlloc", "OMPPTeamMemAlloc", "OMPThreadMemAlloc", |
| 3172 | "OMPUserDefinedMemAlloc" |
| 3173 | ]>, |
| 3174 | ExprArgument<"Allocator"> |
| 3175 | ]; |
| 3176 | let Documentation = [Undocumented]; |
| 3177 | } |
| 3178 | |
| 3179 | def InternalLinkage : InheritableAttr { |
| 3180 | let Spellings = [Clang<"internal_linkage">]; |
| 3181 | let Subjects = SubjectList<[Var, Function, CXXRecord]>; |
| 3182 | let Documentation = [InternalLinkageDocs]; |
| 3183 | } |
| 3184 | |
| 3185 | def ExcludeFromExplicitInstantiation : InheritableAttr { |
| 3186 | let Spellings = [Clang<"exclude_from_explicit_instantiation">]; |
| 3187 | let Subjects = SubjectList<[Var, Function, CXXRecord]>; |
| 3188 | let Documentation = [ExcludeFromExplicitInstantiationDocs]; |
| 3189 | let MeaningfulToClassTemplateDefinition = 1; |
| 3190 | } |
| 3191 | |
| 3192 | def Reinitializes : InheritableAttr { |
| 3193 | let Spellings = [Clang<"reinitializes", 0>]; |
| 3194 | let Subjects = SubjectList<[NonStaticNonConstCXXMethod], ErrorDiag>; |
| 3195 | let Documentation = [ReinitializesDocs]; |
| 3196 | } |
| 3197 | |
| 3198 | def NoDestroy : InheritableAttr { |
| 3199 | let Spellings = [Clang<"no_destroy", 0>]; |
| 3200 | let Subjects = SubjectList<[Var]>; |
| 3201 | let Documentation = [NoDestroyDocs]; |
| 3202 | } |
| 3203 | |
| 3204 | def AlwaysDestroy : InheritableAttr { |
| 3205 | let Spellings = [Clang<"always_destroy", 0>]; |
| 3206 | let Subjects = SubjectList<[Var]>; |
| 3207 | let Documentation = [AlwaysDestroyDocs]; |
| 3208 | } |
| 3209 | |
| 3210 | def SpeculativeLoadHardening : InheritableAttr { |
| 3211 | let Spellings = [Clang<"speculative_load_hardening">]; |
| 3212 | let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>; |
| 3213 | let Documentation = [SpeculativeLoadHardeningDocs]; |
| 3214 | } |
| 3215 | |
| 3216 | def NoSpeculativeLoadHardening : InheritableAttr { |
| 3217 | let Spellings = [Clang<"no_speculative_load_hardening">]; |
| 3218 | let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>; |
| 3219 | let Documentation = [NoSpeculativeLoadHardeningDocs]; |
| 3220 | } |
| 3221 | |
| 3222 | def Uninitialized : InheritableAttr { |
| 3223 | let Spellings = [Clang<"uninitialized", 0>]; |
| 3224 | let Subjects = SubjectList<[LocalVar]>; |
| 3225 | let Documentation = [UninitializedDocs]; |
| 3226 | } |
| 3227 | |
| 3228 | def ObjCExternallyRetained : InheritableAttr { |
| 3229 | let LangOpts = [ObjCAutoRefCount]; |
| 3230 | let Spellings = [Clang<"objc_externally_retained">]; |
| 3231 | let Subjects = SubjectList<[NonParmVar, Function, Block, ObjCMethod]>; |
| 3232 | let Documentation = [ObjCExternallyRetainedDocs]; |
| 3233 | } |
| 3234 | |