2022-07-15 14:33:44 +02:00
|
|
|
|
/**
|
|
|
|
|
* 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;
|
|
|
|
|
|
2023-06-18 01:43:18 +01:00
|
|
|
|
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.
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-15 14:33:44 +02:00
|
|
|
|
/**
|
|
|
|
|
* 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)).
|
2023-06-18 01:43:18 +01:00
|
|
|
|
* )
|
2022-07-15 14:33:44 +02:00
|
|
|
|
*
|
2023-06-18 01:43:18 +01:00
|
|
|
|
* $(LI It cannot be attached to a method or constructor that is a template)
|
2022-07-15 14:33:44 +02:00
|
|
|
|
*
|
|
|
|
|
* $(LI
|
|
|
|
|
* The number of colons in the string need to match the number of
|
|
|
|
|
* arguments the method accept.
|
2023-06-18 01:43:18 +01:00
|
|
|
|
* )
|
2022-07-15 14:33:44 +02:00
|
|
|
|
*
|
|
|
|
|
* $(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:");
|
|
|
|
|
* }
|
|
|
|
|
* ---
|
|
|
|
|
*/
|
2023-06-18 01:43:18 +01:00
|
|
|
|
version (UdaSelector) struct selector
|
2022-07-15 14:33:44 +02:00
|
|
|
|
{
|
|
|
|
|
string selector;
|
|
|
|
|
}
|
2023-06-18 01:43:18 +01:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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;
|