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;