diff options
| author | Yong He <yonghe@outlook.com> | 2020-08-25 21:55:05 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-25 21:55:05 -0700 |
| commit | b8702dfb6d0e41515fa0f9f899d86b7935dfc3fd (patch) | |
| tree | 302e8e2bd8002de583101046bafeee4c16b2d7b7 | |
| parent | 4804753d4a2ec389cc6ecd759f7ea712848fddf0 (diff) | |
Export witness table and RTTI objects in compiled libraries. (#1514)
* Export witness table objects in compiled code.
- Ensure that witness tables are preceeded with `extern "C"` modifier in the generated C++ code.
- RTTI objects use the mangled name of the type directly, so that can be queried using the type's mangled name directly from the resulting DLL.
- Expose `Linkage::getTypeConformanceWitnessMangledName` to return the mangled name of witness tables to the host.
- Ensure that all witness tables (including those for associated types) have proper mangled name.
* Fix GCC error in Slang generated code.
| -rw-r--r-- | slang.h | 7 | ||||
| -rw-r--r-- | source/slang/slang-ast-support-types.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 2 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 10 | ||||
| -rw-r--r-- | source/slang/slang-ir-generics-lowering-context.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 11 |
8 files changed, 41 insertions, 4 deletions
@@ -3102,6 +3102,13 @@ namespace slang LayoutRules rules = LayoutRules::Default, ISlangBlob** outDiagnostics = nullptr) = 0; + /** Get the mangled name for a type witness. + */ + virtual SLANG_NO_THROW SlangResult SLANG_MCALL getTypeConformanceWitnessMangledName( + TypeReflection* type, + TypeReflection* interfaceType, + ISlangBlob** outNameBlob) = 0; + /** Create a request to load/compile front-end code. */ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createCompileRequest( diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h index b8923643c..f667c5fc3 100644 --- a/source/slang/slang-ast-support-types.h +++ b/source/slang/slang-ast-support-types.h @@ -1318,6 +1318,9 @@ namespace Slang // The type that the witness table witnesses conformance to (e.g. an Interface) Type* baseType; + + // The type witnessesd by the witness table (a concrete type). + Type* witnessedType; }; typedef Dictionary<unsigned int, NodeBase*> AttributeArgumentValueDict; diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index f9a514d23..4fa5fff17 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -2450,6 +2450,7 @@ namespace Slang { witnessTable = new WitnessTable(); witnessTable->baseType = DeclRefType::create(m_astBuilder, interfaceDeclRef); + witnessTable->witnessedType = type; } context->mapInterfaceToWitnessTable.Add(interfaceDeclRef, witnessTable); @@ -3021,6 +3022,7 @@ namespace Slang // RefPtr<WitnessTable> witnessTable = new WitnessTable(); witnessTable->baseType = enumConformanceDecl->base.type; + witnessTable->witnessedType = enumTypeType; enumConformanceDecl->witnessTable = witnessTable; Name* tagAssociatedTypeName = getSession()->getNameObj("__Tag"); diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 8996f5512..ac22270f8 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -1205,6 +1205,10 @@ namespace Slang SlangInt targetIndex = 0, slang::LayoutRules rules = slang::LayoutRules::Default, ISlangBlob** outDiagnostics = nullptr) override; + SLANG_NO_THROW SlangResult SLANG_MCALL getTypeConformanceWitnessMangledName( + slang::TypeReflection* type, + slang::TypeReflection* interfaceType, + ISlangBlob** outNameBlob) override; SLANG_NO_THROW SlangResult SLANG_MCALL createCompileRequest( SlangCompileRequest** outCompileRequest) override; diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 0c2b4cd93..e7c90f657 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -1611,7 +1611,7 @@ void CPPSourceEmitter::emitWitnessTable(IRWitnessTable* witnessTable) _maybeEmitWitnessTableTypeDefinition(interfaceType); // Define a global variable for the witness table. - m_writer->emit("extern "); + m_writer->emit("extern \"C\" "); emitSimpleType(interfaceType); m_writer->emit(" "); m_writer->emit(getName(witnessTable)); @@ -1692,7 +1692,13 @@ void CPPSourceEmitter::emitInterface(IRInterfaceType* interfaceType) void CPPSourceEmitter::emitRTTIObject(IRRTTIObject* rttiObject) { - m_writer->emit("static TypeInfo "); + // Declare the type info object as `extern "C"` first. + m_writer->emit("extern \"C\" TypeInfo "); + m_writer->emit(getName(rttiObject)); + m_writer->emit(";\n"); + + // Now actually define the object. + m_writer->emit("TypeInfo "); m_writer->emit(getName(rttiObject)); m_writer->emit(" = {"); auto typeSizeDecoration = rttiObject->findDecoration<IRRTTITypeSizeDecoration>(); diff --git a/source/slang/slang-ir-generics-lowering-context.cpp b/source/slang/slang-ir-generics-lowering-context.cpp index 67f376153..317532e8c 100644 --- a/source/slang/slang-ir-generics-lowering-context.cpp +++ b/source/slang/slang-ir-generics-lowering-context.cpp @@ -72,7 +72,7 @@ namespace Slang // Give a name to the rtti object. if (auto exportDecoration = typeInst->findDecoration<IRExportDecoration>()) { - String rttiObjName = String(exportDecoration->getMangledName()) + "_rtti"; + String rttiObjName = exportDecoration->getMangledName(); builder->addExportDecoration(result, rttiObjName.getUnownedSlice()); } mapTypeToRTTIObject[typeInst] = result; diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index f87b6bd69..f756cf28a 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -5170,7 +5170,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> // Need to construct a sub-witness-table auto irWitnessTableBaseType = lowerType(subContext, astReqWitnessTable->baseType); irSatisfyingWitnessTable = subBuilder->createWitnessTable(irWitnessTableBaseType); - + auto mangledName = getMangledNameForConformanceWitness( + subContext->astBuilder, + astReqWitnessTable->witnessedType, + astReqWitnessTable->baseType); + subBuilder->addExportDecoration(irSatisfyingWitnessTable, mangledName.getUnownedSlice()); // Recursively lower the sub-table. lowerWitnessTable( subContext, diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 6bffa0f65..074c71f21 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -623,6 +623,17 @@ SLANG_NO_THROW slang::TypeLayoutReflection* SLANG_MCALL Linkage::getTypeLayout( return asExternal(typeLayout); } +SLANG_NO_THROW SlangResult SLANG_MCALL Linkage::getTypeConformanceWitnessMangledName( + slang::TypeReflection* type, slang::TypeReflection* interfaceType, ISlangBlob** outNameBlob) +{ + auto subType = asInternal(type); + auto supType = asInternal(interfaceType); + auto name = getMangledNameForConformanceWitness(subType->getASTBuilder(), subType, supType); + Slang::ComPtr<ISlangBlob> blob = Slang::StringUtil::createStringBlob(name); + *outNameBlob = blob.detach(); + return SLANG_OK; +} + SLANG_NO_THROW SlangResult SLANG_MCALL Linkage::createCompileRequest( SlangCompileRequest** outCompileRequest) { |
