|  | /** | 
|  | * 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; | 
|  | } | 
|  | } |