|
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