1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
|
/**
* This module contains UDA's (User Defined Attributes) either used in
* the runtime or special UDA's recognized by compiler.
*
* $(SCRIPT inhibitQuickIndex = 1;)
* $(BOOKTABLE Cheat Sheet,
* $(THEAD Attribute Name, Linkage, Description)
* $(TROW $(LREF gnuAbiTag), C++,
* Declares an ABI tag on a C++ symbol.)
* $(TROW $(LREF mustuse),,
* Ensures that values of a struct or union type are not discarded.)
* $(TROW $(LREF optional), Objective-C,
* Makes an Objective-C interface method optional.)
* $(TROW $(LREF selector), Objective-C,
* Attaches an Objective-C selector to a method.)
* $(TROW $(LREF standalone),,
* Marks a shared module constructor as not depending on any
* other module constructor being run first.)
* $(TROW $(LREF weak),,
* Specifies that a global symbol should be emitted with weak linkage.)
* )
*
* Copyright: Copyright Jacob Carlborg 2015.
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Authors: Jacob Carlborg
* Source: $(DRUNTIMESRC core/_attribute.d)
*/
/* Copyright Jacob Carlborg 2015.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
module core.attribute;
version (GNU)
public import gcc.attributes;
version (LDC)
public import ldc.attributes;
version (D_ObjectiveC)
{
version = UdaOptional;
version = UdaSelector;
}
version (Posix)
version = UdaGNUAbiTag;
version (CoreDdoc)
{
version = UdaGNUAbiTag;
version = UdaOptional;
version = UdaSelector;
}
/**
* Use this attribute to specify that a global symbol should be emitted with
* weak linkage. This is primarily useful in defining library functions that
* can be overridden by user code, though it can also be used with shared and
* static variables too.
*
* The overriding symbol must have the same type as the weak symbol. In
* addition, if it designates a variable it must also have the same size and
* alignment as the weak symbol.
*
* Quote from the LLVM manual: "Note that weak linkage does not actually allow
* the optimizer to inline the body of this function into callers because it
* doesn’t know if this definition of the function is the definitive definition
* within the program or whether it will be overridden by a stronger
* definition."
*
* This attribute is only meaningful to the GNU and LLVM D compilers. The
* Digital Mars D compiler emits all symbols with weak linkage by default.
*/
version (DigitalMars)
{
enum weak;
}
else
{
// GDC and LDC declare this attribute in their own modules.
}
/**
* Use this attribute to attach an Objective-C selector to a method.
*
* This is a special compiler recognized attribute, it has several
* requirements, which all will be enforced by the compiler:
*
* $(UL
* $(LI
* The attribute can only be attached to methods or constructors which
* have Objective-C linkage. That is, a method or a constructor in a
* class or interface declared as $(D_CODE extern(Objective-C)).
* )
*
* $(LI It cannot be attached to a method or constructor that is a template)
*
* $(LI
* The number of colons in the string need to match the number of
* arguments the method accept.
* )
*
* $(LI It can only be used once in a method declaration)
* )
*
* Examples:
* ---
* extern (Objective-C)
* class NSObject
* {
* this() @selector("init");
* static NSObject alloc() @selector("alloc");
* NSObject initWithUTF8String(in char* str) @selector("initWithUTF8String:");
* ObjcObject copyScriptingValue(ObjcObject value, NSString key, NSDictionary properties)
* @selector("copyScriptingValue:forKey:withProperties:");
* }
* ---
*/
version (UdaSelector) struct selector
{
string selector;
}
/**
* Use this attribute to make an Objective-C interface method optional.
*
* An optional method is a method that does **not** have to be implemented in
* the class that implements the interface. To safely call an optional method,
* a runtime check should be performed to make sure the receiver implements the
* method.
*
* This is a special compiler recognized attribute, it has several
* requirements, which all will be enforced by the compiler:
*
* * The attribute can only be attached to methods which have Objective-C
* linkage. That is, a method inside an interface declared as `extern (Objective-C)`
*
* * It can only be used for methods that are declared inside an interface
* * It can only be used once in a method declaration
* * It cannot be attached to a method that is a template
*
* Examples:
* ---
* import core.attribute : optional, selector;
*
* extern (Objective-C):
*
* struct objc_selector;
* alias SEL = objc_selector*;
*
* SEL sel_registerName(in char* str);
*
* extern class NSObject
* {
* bool respondsToSelector(SEL sel) @selector("respondsToSelector:");
* }
*
* interface Foo
* {
* @optional void foo() @selector("foo");
* @optional void bar() @selector("bar");
* }
*
* class Bar : NSObject
* {
* static Bar alloc() @selector("alloc");
* Bar init() @selector("init");
*
* void bar() @selector("bar")
* {
* }
* }
*
* extern (D) void main()
* {
* auto bar = Bar.alloc.init;
*
* if (bar.respondsToSelector(sel_registerName("bar")))
* bar.bar();
* }
* ---
*/
version (UdaOptional)
enum optional;
/**
* Use this attribute to declare an ABI tag on a C++ symbol.
*
* ABI tag is an attribute introduced by the GNU C++ compiler.
* It modifies the mangled name of the symbol to incorporate the tag name,
* in order to distinguish from an earlier version with a different ABI.
*
* This is a special compiler recognized attribute, it has a few
* requirements, which all will be enforced by the compiler:
*
* $(UL
* $(LI
* There can only be one such attribute per symbol.
* )
* $(LI
* The attribute can only be attached to an `extern(C++)` symbol
* (`struct`, `class`, `enum`, function, and their templated counterparts).
* )
* $(LI
* The attribute cannot be applied to C++ namespaces.
* This is to prevent confusion with the C++ semantic, which allows it to
* be applied to namespaces.
* )
* $(LI
* The string arguments must only contain valid characters
* for C++ name mangling which currently include alphanumerics
* and the underscore character.
* )
* )
*
* This UDA is not transitive, and inner scope do not inherit outer scopes'
* ABI tag. See examples below for how to translate a C++ declaration to D.
* Also note that entries in this UDA will be automatically sorted
* alphabetically, hence `gnuAbiTag("c", "b", "a")` will appear as
* `@gnuAbiTag("a", "b", "c")`.
*
* See_Also:
* $(LINK2 https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.abi-tag, Itanium ABI spec)
* $(LINK2 https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html, GCC attributes documentation).
*
* Examples:
* ---
* // ---- foo.cpp
* struct [[gnu::abi_tag ("tag1", "tag2")]] Tagged1_2
* {
* struct [[gnu::abi_tag ("tag3")]] Tagged3
* {
* [[gnu::abi_tag ("tag4")]]
* int Tagged4 () { return 42; }
* }
* }
* Tagged1_2 inst1;
* // ---- foo.d
* @gnuAbiTag("tag1", "tag2") struct Tagged1_2
* {
* // Notice the repetition
* @gnuAbiTag("tag1", "tag2", "tag3") struct Tagged3
* {
* @gnuAbiTag("tag1", "tag2", "tag3", "tag4") int Tagged4 ();
* }
* }
* extern __gshared Tagged1_2 inst1;
* ---
*/
version (UdaGNUAbiTag) struct gnuAbiTag
{
string[] tags;
this(string[] tags...) @safe pure nothrow
{
this.tags = tags.dup;
}
}
/**
* Use this attribute to ensure that values of a `struct` or `union` type are
* not discarded.
*
* The value of an expression is considered to be discarded if
*
* $(UL
* $(LI
* the expression is the top-level expression in a statement or the
* left-hand expression in a comma expression, and
* )
* $(LI
* the expression is not an assignment (`=`, `+=`, etc.), increment
* (`++`), or decrement (`--`) expression.
* )
* )
*
* If the declaration of a `struct` or `union` type has the `@mustuse`
* attribute, the compiler will emit an error any time a value of that type
* would be discarded.
*
* Currently, `@mustuse` is only recognized by the compiler when attached to
* `struct` and `union` declarations. To allow for future expansion, attaching
* `@mustuse` to a `class`, `interface`, `enum`, or function declaration is
* currently forbidden, and will result in a compile-time error. All other uses
* of `@mustuse` are ignored.
*
* Examples:
* ---
* @mustuse struct ErrorCode { int value; }
*
* extern(C) ErrorCode doSomething();
*
* void main()
* {
* // error: would discard a value of type ErrorCode
* //doSomething();
*
* ErrorCode result;
* // ok: value is assigned to a variable
* result = doSomething();
*
* // ok: can ignore the value explicitly with a cast
* cast(void) doSomething();
* }
* ---
*/
enum mustuse;
/**
* Use this attribute to indicate that a shared module constructor does not depend on any
* other module constructor being run first. This avoids errors on cyclic module constructors.
*
* However, it is now up to the user to enforce safety.
* The module constructor must be marked `@system` as a result.
* Prefer to refactor the module constructor causing the cycle so it's in its own module if possible.
*
* This is only allowed on `shared` static constructors, not thread-local module constructors.
*/
enum standalone;
|