summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2020-08-25 21:55:05 -0700
committerGitHub <noreply@github.com>2020-08-25 21:55:05 -0700
commitb8702dfb6d0e41515fa0f9f899d86b7935dfc3fd (patch)
tree302e8e2bd8002de583101046bafeee4c16b2d7b7 /source/slang
parent4804753d4a2ec389cc6ecd759f7ea712848fddf0 (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.
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-ast-support-types.h3
-rw-r--r--source/slang/slang-check-decl.cpp2
-rwxr-xr-xsource/slang/slang-compiler.h4
-rw-r--r--source/slang/slang-emit-cpp.cpp10
-rw-r--r--source/slang/slang-ir-generics-lowering-context.cpp2
-rw-r--r--source/slang/slang-lower-to-ir.cpp6
-rw-r--r--source/slang/slang.cpp11
7 files changed, 34 insertions, 4 deletions
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)
{