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 
24 version (D_ObjectiveC)
25 {
26     version = UdaOptional;
27     version = UdaSelector;
28 }
29 
30 version (Posix)
31     version = UdaGNUAbiTag;
32 
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  */
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 
239     this(string[] tags...) @safe pure nothrow
240     {
241         this.tags = tags.dup;
242     }
243 }
244 
245 /**
246  * Use this attribute to ensure that values of a `struct` or `union` type are
247  * not discarded.
248  *
249  * The value of an expression is considered to be discarded if
250  *
251  * $(UL
252  *  $(LI
253  *      the expression is the top-level expression in a statement or the
254  *      left-hand expression in a comma expression, and
255  *  )
256  *  $(LI
257  *      the expression is not an assignment (`=`, `+=`, etc.), increment
258  *      (`++`), or decrement (`--`) expression.
259  *  )
260  * )
261  *
262  * If the declaration of a `struct` or `union` type has the `@mustuse`
263  * attribute, the compiler will emit an error any time a value of that type
264  * would be discarded.
265  *
266  * Currently, `@mustuse` is only recognized by the compiler when attached to
267  * `struct` and `union` declarations. To allow for future expansion, attaching
268  * `@mustuse` to a `class`, `interface`, `enum`, or function declaration is
269  * currently forbidden, and will result in a compile-time error. All other uses
270  * of `@mustuse` are ignored.
271  *
272  * Examples:
273  * ---
274  * @mustuse struct ErrorCode { int value; }
275  *
276  * extern(C) ErrorCode doSomething();
277  *
278  * void main()
279  * {
280  *     // error: would discard a value of type ErrorCode
281  *     //doSomething();
282  *
283  *     ErrorCode result;
284  *     // ok: value is assigned to a variable
285  *     result = doSomething();
286  *
287  *     // ok: can ignore the value explicitly with a cast
288  *     cast(void) doSomething();
289  * }
290  * ---
291  */
292 enum mustuse;