|
22 | 22 |
|
23 | 23 | namespace swift { |
24 | 24 |
|
| 25 | +/// A reference to an external macro definition that is understood by ASTGen. |
| 26 | +struct ExternalMacroDefinition { |
| 27 | + /// ASTGen's notion of an macro definition, which is opaque to the C++ part |
| 28 | + /// of the compiler. |
| 29 | + void *opaqueHandle = nullptr; |
| 30 | +}; |
| 31 | + |
| 32 | +/// A reference to an external macro. |
| 33 | +struct ExternalMacroReference { |
| 34 | + Identifier moduleName; |
| 35 | + Identifier macroTypeName; |
| 36 | +}; |
| 37 | + |
| 38 | +/// Describes the known kinds of builtin macros. |
| 39 | +enum class BuiltinMacroKind: uint8_t { |
| 40 | + /// #externalMacro, which references an external macro. |
| 41 | + ExternalMacro, |
| 42 | +}; |
| 43 | + |
25 | 44 | /// Provides the definition of a macro. |
26 | 45 | class MacroDefinition { |
27 | 46 | public: |
28 | | - /// Describes a missing macro definition. |
29 | | - struct MissingDefinition { |
30 | | - Identifier externalModuleName; |
31 | | - Identifier externalMacroTypeName; |
32 | | - }; |
33 | | - |
34 | 47 | /// Describes how the macro is implemented. |
35 | | - enum class ImplementationKind: uint8_t { |
| 48 | + enum class Kind: uint8_t { |
| 49 | + /// The macro has a definition, but it is invalid, so the macro cannot be |
| 50 | + /// expanded. |
| 51 | + Invalid, |
| 52 | + |
36 | 53 | /// The macro has no definition. |
37 | 54 | Undefined, |
38 | 55 |
|
39 | | - /// The macro has a definition, but it could not be found. |
40 | | - Missing, |
| 56 | + /// An externally-provided macro definition. |
| 57 | + External, |
41 | 58 |
|
42 | | - /// The macro is in the same process as the compiler, whether built-in or |
43 | | - /// loaded via a compiler plugin. |
44 | | - InProcess, |
| 59 | + /// A builtin macro definition, which has a separate builtin kind. |
| 60 | + Builtin, |
45 | 61 | }; |
46 | 62 |
|
47 | | - ImplementationKind implKind; |
| 63 | + Kind kind; |
48 | 64 |
|
49 | 65 | private: |
50 | | - void *opaqueHandle; |
| 66 | + union Data { |
| 67 | + ExternalMacroReference external; |
| 68 | + BuiltinMacroKind builtin; |
51 | 69 |
|
52 | | - MacroDefinition(ImplementationKind implKind, void *opaqueHandle) |
53 | | - : implKind(implKind), opaqueHandle(opaqueHandle) { } |
| 70 | + Data() : builtin(BuiltinMacroKind::ExternalMacro) { } |
| 71 | + } data; |
| 72 | + |
| 73 | + MacroDefinition(Kind kind) : kind(kind) { } |
| 74 | + |
| 75 | + MacroDefinition(ExternalMacroReference external) : kind(Kind::External) { |
| 76 | + data.external = external; |
| 77 | + } |
| 78 | + |
| 79 | + MacroDefinition(BuiltinMacroKind builtinKind) : kind(Kind::Builtin) { |
| 80 | + data.builtin = builtinKind; |
| 81 | + } |
54 | 82 |
|
55 | 83 | public: |
| 84 | + static MacroDefinition forInvalid() { |
| 85 | + return MacroDefinition(Kind::Invalid); |
| 86 | + } |
| 87 | + |
56 | 88 | static MacroDefinition forUndefined() { |
57 | | - return MacroDefinition{ |
58 | | - ImplementationKind::Undefined, nullptr |
59 | | - }; |
| 89 | + return MacroDefinition(Kind::Undefined); |
60 | 90 | } |
61 | 91 |
|
62 | | - static MacroDefinition forMissing( |
63 | | - ASTContext &ctx, |
64 | | - Identifier externalModuleName, |
65 | | - Identifier externalMacroTypeName |
66 | | - ); |
| 92 | + static MacroDefinition forExternal( |
| 93 | + Identifier moduleName, |
| 94 | + Identifier macroTypeName |
| 95 | + ) { |
| 96 | + return MacroDefinition(ExternalMacroReference{moduleName, macroTypeName}); |
| 97 | + } |
67 | 98 |
|
68 | | - static MacroDefinition forInProcess(void *opaqueHandle) { |
69 | | - return MacroDefinition{ImplementationKind::InProcess, opaqueHandle}; |
| 99 | + static MacroDefinition forBuiltin(BuiltinMacroKind builtinKind) { |
| 100 | + return MacroDefinition(builtinKind); |
70 | 101 | } |
71 | 102 |
|
72 | | - /// Return the opaque handle for an in-process macro definition. |
73 | | - void *getInProcessOpaqueHandle() const { |
74 | | - assert(implKind == ImplementationKind::InProcess); |
75 | | - return opaqueHandle; |
| 103 | + /// Retrieve the external macro being referenced. |
| 104 | + ExternalMacroReference getExternalMacro() const { |
| 105 | + assert(kind == Kind::External); |
| 106 | + return data.external; |
76 | 107 | } |
77 | 108 |
|
78 | | - /// Return more information about a missing macro definition. |
79 | | - MissingDefinition *getMissingDefinition() const { |
80 | | - assert(implKind == ImplementationKind::Missing); |
81 | | - return static_cast<MissingDefinition *>(opaqueHandle); |
| 109 | + /// Retrieve the builtin kind. |
| 110 | + BuiltinMacroKind getBuiltinKind() const { |
| 111 | + assert(kind == Kind::Builtin); |
| 112 | + return data.builtin; |
82 | 113 | } |
| 114 | + |
| 115 | + explicit operator bool() const { return kind != Kind::Invalid; } |
83 | 116 | }; |
84 | 117 |
|
85 | 118 | } |
|
0 commit comments