1 ////////////////////////////////////////////////////////////////////////////////
2 // Note: This file is a work in progress. Please do not apply non-trivial
3 // updates unless you have talked to Sean Hunt <rideau3@gmail.com> prior.
4 // Merely adding a new attribute is a trivial update.
5 ////////////////////////////////////////////////////////////////////////////////
7 // An attribute's subject is whatever it appertains to. In this file, it is
8 // more accurately a list of things that an attribute can appertain to. All
9 // Decls and Stmts are possibly AttrSubjects (even though the syntax may not
10 // allow attributes on a given Decl or Stmt).
13 include "clang/Basic/DeclNodes.td"
14 include "clang/Basic/StmtNodes.td"
16 // A subset-subject is an AttrSubject constrained to operate only on some subset
19 // The description is used in output messages to specify what the subject
20 // represents. FIXME: Deal with translation issues.
22 // The code fragment is a boolean expression that will confirm that the subject
23 // meets the requirements; the subject will have the name S, and will have the
24 // type specified by the base. It should be a simple boolean expression.
25 class SubsetSubject<AttrSubject base, string description, code check>
27 AttrSubject Base = base;
28 string Description = description;
29 code CheckCode = check;
32 // This is the type of a variable which C++0x defines [[aligned()]] as being
33 // a possible subject.
34 def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable",
35 [{S->getStorageClass() != VarDecl::Register &&
36 S->getKind() != Decl::ImplicitParam &&
37 S->getKind() != Decl::ParmVar &&
38 S->getKind() != Decl::NonTypeTemplateParm}]>;
39 def CXXVirtualMethod : SubsetSubject<CXXRecord, "virtual member function",
41 def NonBitField : SubsetSubject<Field, "non-bit field",
42 [{!S->isBitField()}]>;
44 // A single argument to an attribute
45 class Argument<string name> {
49 class BoolArgument<string name> : Argument<name>;
50 class IdentifierArgument<string name> : Argument<name>;
51 class IntArgument<string name> : Argument<name>;
52 class StringArgument<string name> : Argument<name>;
53 class ExprArgument<string name> : Argument<name>;
54 class FunctionArgument<string name> : Argument<name>;
55 class TypeArgument<string name> : Argument<name>;
56 class UnsignedArgument<string name> : Argument<name>;
57 class SourceLocArgument<string name> : Argument<name>;
58 class VariadicUnsignedArgument<string name> : Argument<name>;
59 class VariadicExprArgument<string name> : Argument<name>;
61 // A version of the form major.minor[.subminor].
62 class VersionArgument<string name> : Argument<name>;
64 // This one's a doozy, so it gets its own special type
65 // It can be an unsigned integer, or a type. Either can
67 class AlignedArgument<string name> : Argument<name>;
69 // An integer argument with a default value
70 class DefaultIntArgument<string name, int default> : IntArgument<name> {
71 int Default = default;
74 // This argument is more complex, it includes the enumerator type name,
75 // a list of strings to accept, and a list of enumerators to map them to.
76 class EnumArgument<string name, string type, list<string> values,
77 list<string> enums> : Argument<name> {
79 list<string> Values = values;
80 list<string> Enums = enums;
84 // The various ways in which an attribute can be spelled in source
85 list<string> Spellings;
86 // The things to which an attribute can appertain
87 list<AttrSubject> Subjects;
88 // The arguments allowed on an attribute
89 list<Argument> Args = [];
90 // The namespaces in which the attribute appears in C++0x attributes.
91 // The attribute will not be permitted in C++0x attribute-specifiers if
92 // this is empty; the empty string can be used as a namespace.
93 list<string> Namespaces = [];
94 // Set to true for attributes with arguments which require delayed parsing.
96 // Any additional text that should be included verbatim in the class.
97 code AdditionalMembers = [{}];
100 /// An inheritable attribute is inherited by later redeclarations.
101 class InheritableAttr : Attr;
103 /// An inheritable parameter attribute is inherited by later
104 /// redeclarations, even when it's written on a parameter.
105 class InheritableParamAttr : InheritableAttr;
108 // Attributes begin here
111 def Alias : InheritableAttr {
112 let Spellings = ["alias"];
113 let Args = [StringArgument<"Aliasee">];
116 def Aligned : InheritableAttr {
117 let Spellings = ["aligned"];
118 let Subjects = [NonBitField, NormalVar, Tag];
119 let Args = [AlignedArgument<"Alignment">];
120 let Namespaces = ["", "std"];
123 def AlignMac68k : InheritableAttr {
127 def AlwaysInline : InheritableAttr {
128 let Spellings = ["always_inline"];
131 def AnalyzerNoReturn : InheritableAttr {
132 let Spellings = ["analyzer_noreturn"];
135 def Annotate : InheritableParamAttr {
136 let Spellings = ["annotate"];
137 let Args = [StringArgument<"Annotation">];
140 def AsmLabel : InheritableAttr {
142 let Args = [StringArgument<"Label">];
145 def Availability : InheritableAttr {
146 let Spellings = ["availability"];
147 let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
148 VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
149 BoolArgument<"unavailable">];
150 let AdditionalMembers =
151 [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
152 return llvm::StringSwitch<llvm::StringRef>(Platform)
154 .Case("macosx", "Mac OS X")
155 .Default(llvm::StringRef());
159 def Blocks : InheritableAttr {
160 let Spellings = ["blocks"];
161 let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
164 def CarriesDependency : InheritableParamAttr {
165 let Spellings = ["carries_dependency"];
166 let Subjects = [ParmVar, Function];
167 let Namespaces = ["", "std"];
170 def CDecl : InheritableAttr {
171 let Spellings = ["cdecl", "__cdecl"];
174 // cf_audited_transfer indicates that the given function has been
175 // audited and has been marked with the appropriate cf_consumed and
176 // cf_returns_retained attributes. It is generally applied by
177 // '#pragma clang arc_cf_code_audited' rather than explicitly.
178 def CFAuditedTransfer : InheritableAttr {
179 let Spellings = ["cf_audited_transfer"];
180 let Subjects = [Function];
183 // cf_unknown_transfer is an explicit opt-out of cf_audited_transfer.
184 // It indicates that the function has unknown or unautomatable
185 // transfer semantics.
186 def CFUnknownTransfer : InheritableAttr {
187 let Spellings = ["cf_unknown_transfer"];
188 let Subjects = [Function];
191 def CFReturnsRetained : InheritableAttr {
192 let Spellings = ["cf_returns_retained"];
193 let Subjects = [ObjCMethod, Function];
196 def CFReturnsNotRetained : InheritableAttr {
197 let Spellings = ["cf_returns_not_retained"];
198 let Subjects = [ObjCMethod, Function];
201 def CFConsumed : InheritableParamAttr {
202 let Spellings = ["cf_consumed"];
203 let Subjects = [ParmVar];
206 def Cleanup : InheritableAttr {
207 let Spellings = ["cleanup"];
208 let Args = [FunctionArgument<"FunctionDecl">];
211 def Common : InheritableAttr {
212 let Spellings = ["common"];
215 def Const : InheritableAttr {
216 let Spellings = ["const"];
219 def Constructor : InheritableAttr {
220 let Spellings = ["constructor"];
221 let Args = [IntArgument<"Priority">];
224 def CUDAConstant : InheritableAttr {
225 let Spellings = ["constant"];
228 def CUDADevice : Attr {
229 let Spellings = ["device"];
232 def CUDAGlobal : InheritableAttr {
233 let Spellings = ["global"];
236 def CUDAHost : Attr {
237 let Spellings = ["host"];
240 def CUDALaunchBounds : InheritableAttr {
241 let Spellings = ["launch_bounds"];
242 let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>];
245 def CUDAShared : InheritableAttr {
246 let Spellings = ["shared"];
249 def OpenCLKernel : Attr {
250 let Spellings = ["opencl_kernel_function"];
253 def Deprecated : InheritableAttr {
254 let Spellings = ["deprecated"];
255 let Args = [StringArgument<"Message">];
258 def Destructor : InheritableAttr {
259 let Spellings = ["destructor"];
260 let Args = [IntArgument<"Priority">];
263 def DLLExport : InheritableAttr {
264 let Spellings = ["dllexport"];
267 def DLLImport : InheritableAttr {
268 let Spellings = ["dllimport"];
271 def FastCall : InheritableAttr {
272 let Spellings = ["fastcall", "__fastcall"];
275 def Final : InheritableAttr {
279 def MsStruct : InheritableAttr {
280 let Spellings = ["__ms_struct__"];
283 def Format : InheritableAttr {
284 let Spellings = ["format"];
285 let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
286 IntArgument<"FirstArg">];
289 def FormatArg : InheritableAttr {
290 let Spellings = ["format_arg"];
291 let Args = [IntArgument<"FormatIdx">];
294 def GNUInline : InheritableAttr {
295 let Spellings = ["gnu_inline"];
298 def IBAction : InheritableAttr {
299 let Spellings = ["ibaction"];
302 def IBOutlet : InheritableAttr {
303 let Spellings = ["iboutlet"];
306 def IBOutletCollection : InheritableAttr {
307 let Spellings = ["iboutletcollection"];
308 let Args = [TypeArgument<"Interface">, SourceLocArgument<"InterfaceLoc">];
311 def Malloc : InheritableAttr {
312 let Spellings = ["malloc"];
315 def MaxFieldAlignment : InheritableAttr {
317 let Args = [UnsignedArgument<"Alignment">];
320 def MayAlias : InheritableAttr {
321 let Spellings = ["may_alias"];
324 def MSP430Interrupt : InheritableAttr {
326 let Args = [UnsignedArgument<"Number">];
329 def MBlazeInterruptHandler : InheritableAttr {
333 def MBlazeSaveVolatiles : InheritableAttr {
337 def Naked : InheritableAttr {
338 let Spellings = ["naked"];
341 def ReturnsTwice : InheritableAttr {
342 let Spellings = ["returns_twice"];
345 def NoCommon : InheritableAttr {
346 let Spellings = ["nocommon"];
349 def NoDebug : InheritableAttr {
350 let Spellings = ["nodebug"];
353 def NoInline : InheritableAttr {
354 let Spellings = ["noinline"];
357 def NonNull : InheritableAttr {
358 let Spellings = ["nonnull"];
359 let Args = [VariadicUnsignedArgument<"Args">];
360 let AdditionalMembers =
361 [{bool isNonNull(unsigned idx) const {
362 for (args_iterator i = args_begin(), e = args_end();
370 def NoReturn : InheritableAttr {
371 let Spellings = ["noreturn"];
372 // FIXME: Does GCC allow this on the function instead?
373 let Subjects = [Function];
374 let Namespaces = ["", "std"];
377 def NoInstrumentFunction : InheritableAttr {
378 let Spellings = ["no_instrument_function"];
379 let Subjects = [Function];
382 def NoThrow : InheritableAttr {
383 let Spellings = ["nothrow"];
386 def NSBridged : InheritableAttr {
387 let Spellings = ["ns_bridged"];
388 let Subjects = [Record];
389 let Args = [IdentifierArgument<"BridgedType">];
392 def NSReturnsRetained : InheritableAttr {
393 let Spellings = ["ns_returns_retained"];
394 let Subjects = [ObjCMethod, Function];
397 def NSReturnsNotRetained : InheritableAttr {
398 let Spellings = ["ns_returns_not_retained"];
399 let Subjects = [ObjCMethod, Function];
402 def NSReturnsAutoreleased : InheritableAttr {
403 let Spellings = ["ns_returns_autoreleased"];
404 let Subjects = [ObjCMethod, Function];
407 def NSConsumesSelf : InheritableAttr {
408 let Spellings = ["ns_consumes_self"];
409 let Subjects = [ObjCMethod];
412 def NSConsumed : InheritableParamAttr {
413 let Spellings = ["ns_consumed"];
414 let Subjects = [ParmVar];
417 def ObjCException : InheritableAttr {
418 let Spellings = ["objc_exception"];
421 def ObjCMethodFamily : InheritableAttr {
422 let Spellings = ["objc_method_family"];
423 let Subjects = [ObjCMethod];
424 let Args = [EnumArgument<"Family", "FamilyKind",
425 ["none", "alloc", "copy", "init", "mutableCopy", "new"],
426 ["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init",
427 "OMF_mutableCopy", "OMF_new"]>];
430 def ObjCNSObject : InheritableAttr {
431 let Spellings = ["NSObject"];
434 def ObjCPreciseLifetime : Attr {
435 let Spellings = ["objc_precise_lifetime"];
436 let Subjects = [Var];
439 def ObjCReturnsInnerPointer : Attr {
440 let Spellings = ["objc_returns_inner_pointer"];
441 let Subjects = [ObjCMethod];
444 def Overloadable : Attr {
445 let Spellings = ["overloadable"];
448 def Override : InheritableAttr {
452 def Ownership : InheritableAttr {
453 let Spellings = ["ownership_holds", "ownership_returns", "ownership_takes"];
454 let Args = [EnumArgument<"OwnKind", "OwnershipKind",
455 ["ownership_holds", "ownership_returns", "ownership_takes"],
456 ["Holds", "Returns", "Takes"]>,
457 StringArgument<"Module">, VariadicUnsignedArgument<"Args">];
460 def Packed : InheritableAttr {
461 let Spellings = ["packed"];
464 def Pcs : InheritableAttr {
465 let Spellings = ["pcs"];
466 let Args = [EnumArgument<"PCS", "PCSType",
467 ["aapcs", "aapcs-vfp"],
468 ["AAPCS", "AAPCS_VFP"]>];
471 def Pure : InheritableAttr {
472 let Spellings = ["pure"];
475 def Regparm : InheritableAttr {
476 let Spellings = ["regparm"];
477 let Args = [UnsignedArgument<"NumParams">];
480 def ReqdWorkGroupSize : InheritableAttr {
481 let Spellings = ["reqd_work_group_size"];
482 let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
483 UnsignedArgument<"ZDim">];
486 def InitPriority : InheritableAttr {
487 let Spellings = ["init_priority"];
488 let Args = [UnsignedArgument<"Priority">];
491 def Section : InheritableAttr {
492 let Spellings = ["section"];
493 let Args = [StringArgument<"Name">];
496 def Sentinel : InheritableAttr {
497 let Spellings = ["sentinel"];
498 let Args = [DefaultIntArgument<"Sentinel", 0>,
499 DefaultIntArgument<"NullPos", 0>];
502 def StdCall : InheritableAttr {
503 let Spellings = ["stdcall", "__stdcall"];
506 def ThisCall : InheritableAttr {
507 let Spellings = ["thiscall", "__thiscall"];
510 def Pascal : InheritableAttr {
511 let Spellings = ["pascal", "__pascal"];
514 def TransparentUnion : InheritableAttr {
515 let Spellings = ["transparent_union"];
518 def Unavailable : InheritableAttr {
519 let Spellings = ["unavailable"];
520 let Args = [StringArgument<"Message">];
523 def ArcWeakrefUnavailable : InheritableAttr {
524 let Spellings = ["objc_arc_weak_reference_unavailable"];
527 def Unused : InheritableAttr {
528 let Spellings = ["unused"];
531 def Used : InheritableAttr {
532 let Spellings = ["used"];
535 def Uuid : InheritableAttr {
536 let Spellings = ["uuid"];
537 let Args = [StringArgument<"Guid">];
538 let Subjects = [CXXRecord];
541 def Visibility : InheritableAttr {
542 let Spellings = ["visibility"];
543 let Args = [EnumArgument<"Visibility", "VisibilityType",
544 ["default", "hidden", "internal", "protected"],
545 ["Default", "Hidden", "Hidden", "Protected"]>];
548 def VecReturn : InheritableAttr {
549 let Spellings = ["vecreturn"];
550 let Subjects = [CXXRecord];
553 def WarnUnusedResult : InheritableAttr {
554 let Spellings = ["warn_unused_result"];
557 def Weak : InheritableAttr {
558 let Spellings = ["weak"];
561 def WeakImport : InheritableAttr {
562 let Spellings = ["weak_import"];
565 def WeakRef : InheritableAttr {
566 let Spellings = ["weakref"];
569 def X86ForceAlignArgPointer : InheritableAttr {
574 // C/C++ Thread safety attributes (e.g. for deadlock, data race checking)
576 def GuardedVar : InheritableAttr {
577 let Spellings = ["guarded_var"];
580 def PtGuardedVar : InheritableAttr {
581 let Spellings = ["pt_guarded_var"];
584 def Lockable : InheritableAttr {
585 let Spellings = ["lockable"];
588 def ScopedLockable : InheritableAttr {
589 let Spellings = ["scoped_lockable"];
592 def NoThreadSafetyAnalysis : InheritableAttr {
593 let Spellings = ["no_thread_safety_analysis"];
596 def GuardedBy : InheritableAttr {
597 let Spellings = ["guarded_by"];
598 let Args = [ExprArgument<"Arg">];
602 def PtGuardedBy : InheritableAttr {
603 let Spellings = ["pt_guarded_by"];
604 let Args = [ExprArgument<"Arg">];
608 def AcquiredAfter : InheritableAttr {
609 let Spellings = ["acquired_after"];
610 let Args = [VariadicExprArgument<"Args">];
614 def AcquiredBefore : InheritableAttr {
615 let Spellings = ["acquired_before"];
616 let Args = [VariadicExprArgument<"Args">];
620 def ExclusiveLockFunction : InheritableAttr {
621 let Spellings = ["exclusive_lock_function"];
622 let Args = [VariadicExprArgument<"Args">];
626 def SharedLockFunction : InheritableAttr {
627 let Spellings = ["shared_lock_function"];
628 let Args = [VariadicExprArgument<"Args">];
632 // The first argument is an integer or boolean value specifying the return value
633 // of a successful lock acquisition.
634 def ExclusiveTrylockFunction : InheritableAttr {
635 let Spellings = ["exclusive_trylock_function"];
636 let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
640 // The first argument is an integer or boolean value specifying the return value
641 // of a successful lock acquisition.
642 def SharedTrylockFunction : InheritableAttr {
643 let Spellings = ["shared_trylock_function"];
644 let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
648 def UnlockFunction : InheritableAttr {
649 let Spellings = ["unlock_function"];
650 let Args = [VariadicExprArgument<"Args">];
654 def LockReturned : InheritableAttr {
655 let Spellings = ["lock_returned"];
656 let Args = [ExprArgument<"Arg">];
660 def LocksExcluded : InheritableAttr {
661 let Spellings = ["locks_excluded"];
662 let Args = [VariadicExprArgument<"Args">];
666 def ExclusiveLocksRequired : InheritableAttr {
667 let Spellings = ["exclusive_locks_required"];
668 let Args = [VariadicExprArgument<"Args">];
672 def SharedLocksRequired : InheritableAttr {
673 let Spellings = ["shared_locks_required"];
674 let Args = [VariadicExprArgument<"Args">];