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 // Set to true for attributes which must be instantiated within templates
97 bit TemplateDependent = 0;
98 // Set to true for attributes which have handler in Sema.
100 // Any additional text that should be included verbatim in the class.
101 code AdditionalMembers = [{}];
104 /// An inheritable attribute is inherited by later redeclarations.
105 class InheritableAttr : Attr;
107 /// An inheritable parameter attribute is inherited by later
108 /// redeclarations, even when it's written on a parameter.
109 class InheritableParamAttr : InheritableAttr;
112 // Attributes begin here
115 def Alias : InheritableAttr {
116 let Spellings = ["alias"];
117 let Args = [StringArgument<"Aliasee">];
120 def Aligned : InheritableAttr {
121 let Spellings = ["aligned"];
122 let Subjects = [NonBitField, NormalVar, Tag];
123 let Args = [AlignedArgument<"Alignment">];
124 let Namespaces = ["", "std"];
127 def AlignMac68k : InheritableAttr {
132 def AlwaysInline : InheritableAttr {
133 let Spellings = ["always_inline"];
136 def AnalyzerNoReturn : InheritableAttr {
137 let Spellings = ["analyzer_noreturn"];
140 def Annotate : InheritableParamAttr {
141 let Spellings = ["annotate"];
142 let Args = [StringArgument<"Annotation">];
145 def AsmLabel : InheritableAttr {
147 let Args = [StringArgument<"Label">];
151 def Availability : InheritableAttr {
152 let Spellings = ["availability"];
153 let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
154 VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
155 BoolArgument<"unavailable">, StringArgument<"message">];
156 let AdditionalMembers =
157 [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
158 return llvm::StringSwitch<llvm::StringRef>(Platform)
160 .Case("macosx", "Mac OS X")
161 .Default(llvm::StringRef());
165 def Blocks : InheritableAttr {
166 let Spellings = ["blocks"];
167 let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
170 def CarriesDependency : InheritableParamAttr {
171 let Spellings = ["carries_dependency"];
172 let Subjects = [ParmVar, Function];
173 let Namespaces = ["", "std"];
176 def CDecl : InheritableAttr {
177 let Spellings = ["cdecl", "__cdecl"];
180 // cf_audited_transfer indicates that the given function has been
181 // audited and has been marked with the appropriate cf_consumed and
182 // cf_returns_retained attributes. It is generally applied by
183 // '#pragma clang arc_cf_code_audited' rather than explicitly.
184 def CFAuditedTransfer : InheritableAttr {
185 let Spellings = ["cf_audited_transfer"];
186 let Subjects = [Function];
189 // cf_unknown_transfer is an explicit opt-out of cf_audited_transfer.
190 // It indicates that the function has unknown or unautomatable
191 // transfer semantics.
192 def CFUnknownTransfer : InheritableAttr {
193 let Spellings = ["cf_unknown_transfer"];
194 let Subjects = [Function];
197 def CFReturnsRetained : InheritableAttr {
198 let Spellings = ["cf_returns_retained"];
199 let Subjects = [ObjCMethod, Function];
202 def CFReturnsNotRetained : InheritableAttr {
203 let Spellings = ["cf_returns_not_retained"];
204 let Subjects = [ObjCMethod, Function];
207 def CFConsumed : InheritableParamAttr {
208 let Spellings = ["cf_consumed"];
209 let Subjects = [ParmVar];
212 def Cleanup : InheritableAttr {
213 let Spellings = ["cleanup"];
214 let Args = [FunctionArgument<"FunctionDecl">];
217 def Common : InheritableAttr {
218 let Spellings = ["common"];
221 def Const : InheritableAttr {
222 let Spellings = ["const"];
225 def Constructor : InheritableAttr {
226 let Spellings = ["constructor"];
227 let Args = [IntArgument<"Priority">];
230 def CUDAConstant : InheritableAttr {
231 let Spellings = ["constant"];
234 def CUDADevice : Attr {
235 let Spellings = ["device"];
238 def CUDAGlobal : InheritableAttr {
239 let Spellings = ["global"];
242 def CUDAHost : Attr {
243 let Spellings = ["host"];
246 def CUDALaunchBounds : InheritableAttr {
247 let Spellings = ["launch_bounds"];
248 let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>];
251 def CUDAShared : InheritableAttr {
252 let Spellings = ["shared"];
255 def OpenCLKernel : Attr {
256 let Spellings = ["opencl_kernel_function"];
259 def Deprecated : InheritableAttr {
260 let Spellings = ["deprecated"];
261 let Args = [StringArgument<"Message">];
264 def Destructor : InheritableAttr {
265 let Spellings = ["destructor"];
266 let Args = [IntArgument<"Priority">];
269 def DLLExport : InheritableAttr {
270 let Spellings = ["dllexport"];
273 def DLLImport : InheritableAttr {
274 let Spellings = ["dllimport"];
277 def FastCall : InheritableAttr {
278 let Spellings = ["fastcall", "__fastcall"];
281 def Final : InheritableAttr {
286 def MsStruct : InheritableAttr {
287 let Spellings = ["__ms_struct__"];
290 def Format : InheritableAttr {
291 let Spellings = ["format"];
292 let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
293 IntArgument<"FirstArg">];
296 def FormatArg : InheritableAttr {
297 let Spellings = ["format_arg"];
298 let Args = [IntArgument<"FormatIdx">];
301 def GNUInline : InheritableAttr {
302 let Spellings = ["gnu_inline"];
305 def IBAction : InheritableAttr {
306 let Spellings = ["ibaction"];
309 def IBOutlet : InheritableAttr {
310 let Spellings = ["iboutlet"];
313 def IBOutletCollection : InheritableAttr {
314 let Spellings = ["iboutletcollection"];
315 let Args = [TypeArgument<"Interface">, SourceLocArgument<"InterfaceLoc">];
318 def Malloc : InheritableAttr {
319 let Spellings = ["malloc"];
322 def MaxFieldAlignment : InheritableAttr {
324 let Args = [UnsignedArgument<"Alignment">];
328 def MayAlias : InheritableAttr {
329 let Spellings = ["may_alias"];
332 def MSP430Interrupt : InheritableAttr {
334 let Args = [UnsignedArgument<"Number">];
338 def MBlazeInterruptHandler : InheritableAttr {
343 def MBlazeSaveVolatiles : InheritableAttr {
348 def Naked : InheritableAttr {
349 let Spellings = ["naked"];
352 def ReturnsTwice : InheritableAttr {
353 let Spellings = ["returns_twice"];
356 def NoCommon : InheritableAttr {
357 let Spellings = ["nocommon"];
360 def NoDebug : InheritableAttr {
361 let Spellings = ["nodebug"];
364 def NoInline : InheritableAttr {
365 let Spellings = ["noinline"];
368 def NonNull : InheritableAttr {
369 let Spellings = ["nonnull"];
370 let Args = [VariadicUnsignedArgument<"Args">];
371 let AdditionalMembers =
372 [{bool isNonNull(unsigned idx) const {
373 for (args_iterator i = args_begin(), e = args_end();
381 def NoReturn : InheritableAttr {
382 let Spellings = ["noreturn"];
383 // FIXME: Does GCC allow this on the function instead?
384 let Subjects = [Function];
385 let Namespaces = ["", "std"];
388 def NoInstrumentFunction : InheritableAttr {
389 let Spellings = ["no_instrument_function"];
390 let Subjects = [Function];
393 def NoThrow : InheritableAttr {
394 let Spellings = ["nothrow"];
397 def NSBridged : InheritableAttr {
398 let Spellings = ["ns_bridged"];
399 let Subjects = [Record];
400 let Args = [IdentifierArgument<"BridgedType">];
403 def NSReturnsRetained : InheritableAttr {
404 let Spellings = ["ns_returns_retained"];
405 let Subjects = [ObjCMethod, Function];
408 def NSReturnsNotRetained : InheritableAttr {
409 let Spellings = ["ns_returns_not_retained"];
410 let Subjects = [ObjCMethod, Function];
413 def NSReturnsAutoreleased : InheritableAttr {
414 let Spellings = ["ns_returns_autoreleased"];
415 let Subjects = [ObjCMethod, Function];
418 def NSConsumesSelf : InheritableAttr {
419 let Spellings = ["ns_consumes_self"];
420 let Subjects = [ObjCMethod];
423 def NSConsumed : InheritableParamAttr {
424 let Spellings = ["ns_consumed"];
425 let Subjects = [ParmVar];
428 def ObjCException : InheritableAttr {
429 let Spellings = ["objc_exception"];
432 def ObjCMethodFamily : InheritableAttr {
433 let Spellings = ["objc_method_family"];
434 let Subjects = [ObjCMethod];
435 let Args = [EnumArgument<"Family", "FamilyKind",
436 ["none", "alloc", "copy", "init", "mutableCopy", "new"],
437 ["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init",
438 "OMF_mutableCopy", "OMF_new"]>];
441 def ObjCNSObject : InheritableAttr {
442 let Spellings = ["NSObject"];
445 def ObjCPreciseLifetime : Attr {
446 let Spellings = ["objc_precise_lifetime"];
447 let Subjects = [Var];
450 def ObjCReturnsInnerPointer : Attr {
451 let Spellings = ["objc_returns_inner_pointer"];
452 let Subjects = [ObjCMethod];
455 def ObjCRootClass : Attr {
456 let Spellings = ["objc_root_class"];
457 let Subjects = [ObjCInterface];
460 def Overloadable : Attr {
461 let Spellings = ["overloadable"];
464 def Override : InheritableAttr {
469 def Ownership : InheritableAttr {
470 let Spellings = ["ownership_holds", "ownership_returns", "ownership_takes"];
471 let Args = [EnumArgument<"OwnKind", "OwnershipKind",
472 ["ownership_holds", "ownership_returns", "ownership_takes"],
473 ["Holds", "Returns", "Takes"]>,
474 StringArgument<"Module">, VariadicUnsignedArgument<"Args">];
477 def Packed : InheritableAttr {
478 let Spellings = ["packed"];
481 def Pcs : InheritableAttr {
482 let Spellings = ["pcs"];
483 let Args = [EnumArgument<"PCS", "PCSType",
484 ["aapcs", "aapcs-vfp"],
485 ["AAPCS", "AAPCS_VFP"]>];
488 def Pure : InheritableAttr {
489 let Spellings = ["pure"];
492 def Regparm : InheritableAttr {
493 let Spellings = ["regparm"];
494 let Args = [UnsignedArgument<"NumParams">];
497 def ReqdWorkGroupSize : InheritableAttr {
498 let Spellings = ["reqd_work_group_size"];
499 let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
500 UnsignedArgument<"ZDim">];
503 def InitPriority : InheritableAttr {
504 let Spellings = ["init_priority"];
505 let Args = [UnsignedArgument<"Priority">];
508 def Section : InheritableAttr {
509 let Spellings = ["section"];
510 let Args = [StringArgument<"Name">];
513 def Sentinel : InheritableAttr {
514 let Spellings = ["sentinel"];
515 let Args = [DefaultIntArgument<"Sentinel", 0>,
516 DefaultIntArgument<"NullPos", 0>];
519 def StdCall : InheritableAttr {
520 let Spellings = ["stdcall", "__stdcall"];
523 def ThisCall : InheritableAttr {
524 let Spellings = ["thiscall", "__thiscall"];
527 def Pascal : InheritableAttr {
528 let Spellings = ["pascal", "__pascal"];
531 def TransparentUnion : InheritableAttr {
532 let Spellings = ["transparent_union"];
535 def Unavailable : InheritableAttr {
536 let Spellings = ["unavailable"];
537 let Args = [StringArgument<"Message">];
540 def ArcWeakrefUnavailable : InheritableAttr {
541 let Spellings = ["objc_arc_weak_reference_unavailable"];
542 let Subjects = [ObjCInterface];
545 def ObjCRequiresPropertyDefs : InheritableAttr {
546 let Spellings = ["objc_requires_property_definitions"];
547 let Subjects = [ObjCInterface];
550 def Unused : InheritableAttr {
551 let Spellings = ["unused"];
554 def Used : InheritableAttr {
555 let Spellings = ["used"];
558 def Uuid : InheritableAttr {
559 let Spellings = ["uuid"];
560 let Args = [StringArgument<"Guid">];
561 let Subjects = [CXXRecord];
564 def Visibility : InheritableAttr {
565 let Spellings = ["visibility"];
566 let Args = [EnumArgument<"Visibility", "VisibilityType",
567 ["default", "hidden", "internal", "protected"],
568 ["Default", "Hidden", "Hidden", "Protected"]>];
571 def VecReturn : InheritableAttr {
572 let Spellings = ["vecreturn"];
573 let Subjects = [CXXRecord];
576 def WarnUnusedResult : InheritableAttr {
577 let Spellings = ["warn_unused_result"];
580 def Weak : InheritableAttr {
581 let Spellings = ["weak"];
584 def WeakImport : InheritableAttr {
585 let Spellings = ["weak_import"];
588 def WeakRef : InheritableAttr {
589 let Spellings = ["weakref"];
592 def X86ForceAlignArgPointer : InheritableAttr {
596 // AddressSafety attribute (e.g. for AddressSanitizer)
597 def NoAddressSafetyAnalysis : InheritableAttr {
598 let Spellings = ["no_address_safety_analysis"];
601 // C/C++ Thread safety attributes (e.g. for deadlock, data race checking)
603 def GuardedVar : InheritableAttr {
604 let Spellings = ["guarded_var"];
607 def PtGuardedVar : InheritableAttr {
608 let Spellings = ["pt_guarded_var"];
611 def Lockable : InheritableAttr {
612 let Spellings = ["lockable"];
615 def ScopedLockable : InheritableAttr {
616 let Spellings = ["scoped_lockable"];
619 def NoThreadSafetyAnalysis : InheritableAttr {
620 let Spellings = ["no_thread_safety_analysis"];
623 def GuardedBy : InheritableAttr {
624 let Spellings = ["guarded_by"];
625 let Args = [ExprArgument<"Arg">];
627 let TemplateDependent = 1;
630 def PtGuardedBy : InheritableAttr {
631 let Spellings = ["pt_guarded_by"];
632 let Args = [ExprArgument<"Arg">];
634 let TemplateDependent = 1;
637 def AcquiredAfter : InheritableAttr {
638 let Spellings = ["acquired_after"];
639 let Args = [VariadicExprArgument<"Args">];
641 let TemplateDependent = 1;
644 def AcquiredBefore : InheritableAttr {
645 let Spellings = ["acquired_before"];
646 let Args = [VariadicExprArgument<"Args">];
648 let TemplateDependent = 1;
651 def ExclusiveLockFunction : InheritableAttr {
652 let Spellings = ["exclusive_lock_function"];
653 let Args = [VariadicExprArgument<"Args">];
655 let TemplateDependent = 1;
658 def SharedLockFunction : InheritableAttr {
659 let Spellings = ["shared_lock_function"];
660 let Args = [VariadicExprArgument<"Args">];
662 let TemplateDependent = 1;
665 // The first argument is an integer or boolean value specifying the return value
666 // of a successful lock acquisition.
667 def ExclusiveTrylockFunction : InheritableAttr {
668 let Spellings = ["exclusive_trylock_function"];
669 let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
671 let TemplateDependent = 1;
674 // The first argument is an integer or boolean value specifying the return value
675 // of a successful lock acquisition.
676 def SharedTrylockFunction : InheritableAttr {
677 let Spellings = ["shared_trylock_function"];
678 let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
680 let TemplateDependent = 1;
683 def UnlockFunction : InheritableAttr {
684 let Spellings = ["unlock_function"];
685 let Args = [VariadicExprArgument<"Args">];
687 let TemplateDependent = 1;
690 def LockReturned : InheritableAttr {
691 let Spellings = ["lock_returned"];
692 let Args = [ExprArgument<"Arg">];
694 let TemplateDependent = 1;
697 def LocksExcluded : InheritableAttr {
698 let Spellings = ["locks_excluded"];
699 let Args = [VariadicExprArgument<"Args">];
701 let TemplateDependent = 1;
704 def ExclusiveLocksRequired : InheritableAttr {
705 let Spellings = ["exclusive_locks_required"];
706 let Args = [VariadicExprArgument<"Args">];
708 let TemplateDependent = 1;
711 def SharedLocksRequired : InheritableAttr {
712 let Spellings = ["shared_locks_required"];
713 let Args = [VariadicExprArgument<"Args">];
715 let TemplateDependent = 1;