1 /**
2     Numem attribute hooks for various compilers.
3 
4     We implement them here to avoid relying on druntime,
5     or phobos.
6 
7     Some of this code references druntime in dmd, ldc and gcc.
8     
9     Copyright:
10         Copyright © 2023-2025, Kitsunebi Games
11         Copyright © 2023-2025, Inochi2D Project
12     
13     License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
14     Authors:   Luna Nielsen
15 */
16 module numem.core.attributes;
17 
18 // TODO: Ask GCC maintainers whether this is OK licensing wise.
19 // Internal Helpers.
20 version(GDC) {
21     private struct Attribute(A...) {
22         A arguments;
23     }
24 }
25 
26 /**
27     When applied to a global symbol, specifies that the symbol should be emitted
28     with weak linkage. An example use case is a library function that should be
29     overridable by user code.
30 
31     Quote from the LLVM manual: "Note that weak linkage does not actually allow
32     the optimizer to inline the body of this function into callers because it
33     doesn’t know if this definition of the function is the definitive definition
34     within the program or whether it will be overridden by a stronger
35     definition."
36 
37     Examples:
38         ---
39         import numem.core.attributes;
40 
41         @weak int user_hook() { return 1; }
42         ---
43 */
44 version(LDC) {
45     immutable weak = _weak();
46     private struct _weak { }
47 } else version(GDC) {
48     enum weak = Attribute!string("weak");
49 } else {
50     // NOTE: Not used by other compilers.
51     struct weak;
52 }
53 
54 /**
55     When applied to a global variable or function, causes it to be emitted to a
56     non-standard object file/executable section.
57 
58     The target platform might impose certain restrictions on the format for
59     section names.
60 
61     Examples:
62         ---
63         import numem.core.attributes;
64 
65         @section(".mySection") int myGlobal;
66         ---
67 */
68 version(LDC) {
69     struct section { string name; }
70 } else version(GDC) {
71     auto section(string sectionName) {
72         return Attribute!(string, string)("section", sectionName);
73     }
74 } else {
75 
76     // DMD doesn't support this, but whatever.
77     struct section { string name; }
78 }
79 
80 /**
81     Use this attribute to attach an Objective-C selector to a method.
82 
83     Examples:
84         ---
85         extern (Objective-C)
86         class NSObject
87         {
88             this() @selector("init");
89             static NSObject alloc() @selector("alloc");
90             NSObject initWithUTF8String(in char* str) @selector("initWithUTF8String:");
91             ObjcObject copyScriptingValue(ObjcObject value, NSString key, NSDictionary properties)
92                 @selector("copyScriptingValue:forKey:withProperties:");
93         }
94         ---
95 */
96 version(D_ObjectiveC)
97 struct selector {
98     string selector;
99 }
100 
101 /**
102     Use this attribute to make an Objective-C interface method optional.
103 
104     An optional method is a method that does **not** have to be implemented in
105     the class that implements the interface. To safely call an optional method,
106     a runtime check should be performed to make sure the receiver implements the
107     method.
108 */
109 version(D_ObjectiveC)
110 enum optional;