Make Objective-C interoperability configurable in the runtime

In order to be able to debug, for example, a Linux process from a macOS host, we
need to be able to initialize a ReflectionContext without Objective-C
interoperability. This patch turns ObjCInterOp into another template trait, so
it's possible to instantiate a non-ObjC MetadataReader on a system built with
ObjC-interop (but not vice versa).

This patch changes the class hierarchy to

                          TargetMetadata<Runtime>
                                    |
                          TargetHeapMetadata<Runtime>
                                    |
                          TargetAnyClassMetadata<Runtime>
                                   /                \
                                  /               TargetAnyClassMetadataObjCInterop<Runtime>
                                 /                              \
TargetClassMetadata<Runtime, TargetAnyClassMetadata<Runtime>>    \
                                                                  \
                    TargetClassMetadata<Runtime, TargetAnyClassMetadataObjCInterop<Runtime>>

TargetAnyClassMetadataObjCInterop inherits from TargetAnyClassMetadata because
most of the implementation is the same. This choice makes TargetClassMetadata a
bit tricky. In this patch I went with templating the parent class.

rdar://87179578
This commit is contained in:
Adrian Prantl
2022-01-13 14:49:48 -08:00
parent 477b4d68fa
commit fede775269
7 changed files with 332 additions and 188 deletions

View File

@@ -649,13 +649,24 @@ static RemoteASTContextImpl *createImpl(ASTContext &ctx,
std::shared_ptr<MemoryReader> &&reader) {
auto &target = ctx.LangOpts.Target;
assert(target.isArch32Bit() || target.isArch64Bit());
bool objcInterop = ctx.LangOpts.EnableObjCInterop;
if (target.isArch32Bit()) {
using Target = External<RuntimeTarget<4>>;
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
if (objcInterop) {
using Target = External<WithObjCInterop<RuntimeTarget<4>>>;
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
} else {
using Target = External<NoObjCInterop<RuntimeTarget<4>>>;
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
}
} else {
using Target = External<RuntimeTarget<8>>;
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
if (objcInterop) {
using Target = External<WithObjCInterop<RuntimeTarget<8>>>;
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
} else {
using Target = External<NoObjCInterop<RuntimeTarget<8>>>;
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
}
}
}