| /** |
| * This module contains UDA's (User Defined Attributes) either used in |
| * the runtime or special UDA's recognized by compiler. |
| * |
| * 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...) |
| { |
| this.tags = tags; |
| } |
| } |
| |
| /** |
| * 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; |