1 /**
2 * This module contains UDA's (User Defined Attributes) either used in
3 * the runtime or special UDA's recognized by compiler.
4 *
5 * Copyright: Copyright Jacob Carlborg 2015.
6 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7 * Authors: Jacob Carlborg
8 * Source: $(DRUNTIMESRC core/_attribute.d)
9 */
10
11 /* Copyright Jacob Carlborg 2015.
12 * Distributed under the Boost Software License, Version 1.0.
13 * (See accompanying file LICENSE or copy at
14 * http://www.boost.org/LICENSE_1_0.txt)
15 */
16 module core.attribute;
17
18 version (GNU)
19 public import gcc.attributes;
20
21 version (LDC)
22 public import ldc.attributes;
23
version(D_ObjectiveC)24 version (D_ObjectiveC)
25 {
26 version = UdaOptional;
27 version = UdaSelector;
28 }
29
30 version (Posix)
31 version = UdaGNUAbiTag;
32
version(CoreDdoc)33 version (CoreDdoc)
34 {
35 version = UdaGNUAbiTag;
36 version = UdaOptional;
37 version = UdaSelector;
38 }
39
40 /**
41 * Use this attribute to specify that a global symbol should be emitted with
42 * weak linkage. This is primarily useful in defining library functions that
43 * can be overridden by user code, though it can also be used with shared and
44 * static variables too.
45 *
46 * The overriding symbol must have the same type as the weak symbol. In
47 * addition, if it designates a variable it must also have the same size and
48 * alignment as the weak symbol.
49 *
50 * Quote from the LLVM manual: "Note that weak linkage does not actually allow
51 * the optimizer to inline the body of this function into callers because it
52 * doesn’t know if this definition of the function is the definitive definition
53 * within the program or whether it will be overridden by a stronger
54 * definition."
55 *
56 * This attribute is only meaningful to the GNU and LLVM D compilers. The
57 * Digital Mars D compiler emits all symbols with weak linkage by default.
58 */
version(DigitalMars)59 version (DigitalMars)
60 {
61 enum weak;
62 }
63 else
64 {
65 // GDC and LDC declare this attribute in their own modules.
66 }
67
68 /**
69 * Use this attribute to attach an Objective-C selector to a method.
70 *
71 * This is a special compiler recognized attribute, it has several
72 * requirements, which all will be enforced by the compiler:
73 *
74 * $(UL
75 * $(LI
76 * The attribute can only be attached to methods or constructors which
77 * have Objective-C linkage. That is, a method or a constructor in a
78 * class or interface declared as $(D_CODE extern(Objective-C)).
79 * ),
80 *
81 * $(LI It cannot be attached to a method or constructor that is a template),
82 *
83 * $(LI
84 * The number of colons in the string need to match the number of
85 * arguments the method accept.
86 * ),
87 *
88 * $(LI It can only be used once in a method declaration)
89 * )
90 *
91 * Examples:
92 * ---
93 * extern (Objective-C)
94 * class NSObject
95 * {
96 * this() @selector("init");
97 * static NSObject alloc() @selector("alloc");
98 * NSObject initWithUTF8String(in char* str) @selector("initWithUTF8String:");
99 * ObjcObject copyScriptingValue(ObjcObject value, NSString key, NSDictionary properties)
100 * @selector("copyScriptingValue:forKey:withProperties:");
101 * }
102 * ---
103 */
104 version (UdaSelector) struct selector
105 {
106 string selector;
107 }
108
109 /**
110 * Use this attribute to make an Objective-C interface method optional.
111 *
112 * An optional method is a method that does **not** have to be implemented in
113 * the class that implements the interface. To safely call an optional method,
114 * a runtime check should be performed to make sure the receiver implements the
115 * method.
116 *
117 * This is a special compiler recognized attribute, it has several
118 * requirements, which all will be enforced by the compiler:
119 *
120 * * The attribute can only be attached to methods which have Objective-C
121 * linkage. That is, a method inside an interface declared as `extern (Objective-C)`
122 *
123 * * It can only be used for methods that are declared inside an interface
124 * * It can only be used once in a method declaration
125 * * It cannot be attached to a method that is a template
126 *
127 * Examples:
128 * ---
129 * import core.attribute : optional, selector;
130 *
131 * extern (Objective-C):
132 *
133 * struct objc_selector;
134 * alias SEL = objc_selector*;
135 *
136 * SEL sel_registerName(in char* str);
137 *
138 * extern class NSObject
139 * {
140 * bool respondsToSelector(SEL sel) @selector("respondsToSelector:");
141 * }
142 *
143 * interface Foo
144 * {
145 * @optional void foo() @selector("foo");
146 * @optional void bar() @selector("bar");
147 * }
148 *
149 * class Bar : NSObject
150 * {
151 * static Bar alloc() @selector("alloc");
152 * Bar init() @selector("init");
153 *
154 * void bar() @selector("bar")
155 * {
156 * }
157 * }
158 *
159 * extern (D) void main()
160 * {
161 * auto bar = Bar.alloc.init;
162 *
163 * if (bar.respondsToSelector(sel_registerName("bar")))
164 * bar.bar();
165 * }
166 * ---
167 */
168 version (UdaOptional)
169 enum optional;
170
171 /**
172 * Use this attribute to declare an ABI tag on a C++ symbol.
173 *
174 * ABI tag is an attribute introduced by the GNU C++ compiler.
175 * It modifies the mangled name of the symbol to incorporate the tag name,
176 * in order to distinguish from an earlier version with a different ABI.
177 *
178 * This is a special compiler recognized attribute, it has a few
179 * requirements, which all will be enforced by the compiler:
180 *
181 * $(UL
182 * $(LI
183 * There can only be one such attribute per symbol.
184 * ),
185 * $(LI
186 * The attribute can only be attached to an `extern(C++)` symbol
187 * (`struct`, `class`, `enum`, function, and their templated counterparts).
188 * ),
189 * $(LI
190 * The attribute cannot be applied to C++ namespaces.
191 * This is to prevent confusion with the C++ semantic, which allows it to
192 * be applied to namespaces.
193 * ),
194 * $(LI
195 * The string arguments must only contain valid characters
196 * for C++ name mangling which currently include alphanumerics
197 * and the underscore character.
198 * ),
199 * )
200 *
201 * This UDA is not transitive, and inner scope do not inherit outer scopes'
202 * ABI tag. See examples below for how to translate a C++ declaration to D.
203 * Also note that entries in this UDA will be automatically sorted
204 * alphabetically, hence `gnuAbiTag("c", "b", "a")` will appear as
205 * `@gnuAbiTag("a", "b", "c")`.
206 *
207 * See_Also:
208 * $(LINK2 https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.abi-tag, Itanium ABI spec)
209 * $(LINK2 https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html, GCC attributes documentation).
210 *
211 * Examples:
212 * ---
213 * // ---- foo.cpp
214 * struct [[gnu::abi_tag ("tag1", "tag2")]] Tagged1_2
215 * {
216 * struct [[gnu::abi_tag ("tag3")]] Tagged3
217 * {
218 * [[gnu::abi_tag ("tag4")]]
219 * int Tagged4 () { return 42; }
220 * }
221 * }
222 * Tagged1_2 inst1;
223 * // ---- foo.d
224 * @gnuAbiTag("tag1", "tag2") struct Tagged1_2
225 * {
226 * // Notice the repetition
227 * @gnuAbiTag("tag1", "tag2", "tag3") struct Tagged3
228 * {
229 * @gnuAbiTag("tag1", "tag2", "tag3", "tag4") int Tagged4 ();
230 * }
231 * }
232 * extern __gshared Tagged1_2 inst1;
233 * ---
234 */
235 version (UdaGNUAbiTag) struct gnuAbiTag
236 {
237 string[] tags;
238
thisgnuAbiTag239 this(string[] tags...)
240 {
241 this.tags = tags;
242 }
243 }
244