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 | |