summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2018-01-21 07:09:55 -0500
committerYong He <yonghe@outlook.com>2018-01-21 07:09:55 -0500
commitce879112cb16e3def1b8673104e7123b8b17ee2a (patch)
tree9b2a63c4c2c6256d33cb32b925ed9820cf13071d /source
parent913f4d09b91e3fd7449468b135881c940cacb3c0 (diff)
Improvements and bug fixes for global type parameters
1. allow spReflection_FindTypeByName to accept arbitrary type expression string 2. allow const int generic value to be used as expression value, and as array size 3. various bug fixes in witness table specialization / function cloning during specializeIRForEntryPoint to avoid creating duplicate global values, not copying the right definition of a function from the other module, not cloning witness tables that are required by specializeGenerics etc.
Diffstat (limited to 'source')
-rw-r--r--source/slang/check.cpp29
-rw-r--r--source/slang/compiler.h2
-rw-r--r--source/slang/emit.cpp2
-rw-r--r--source/slang/ir-insts.h3
-rw-r--r--source/slang/ir.cpp193
-rw-r--r--source/slang/legalize-types.cpp2
-rw-r--r--source/slang/lower-to-ir.cpp49
-rw-r--r--source/slang/reflection.cpp16
-rw-r--r--source/slang/slang.cpp29
-rw-r--r--source/slang/syntax.cpp4
10 files changed, 240 insertions, 89 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index c4aa9bfba..52558ee15 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -6849,6 +6849,23 @@ namespace Slang
return (!decl->primaryDecl) || (decl == decl->primaryDecl);
}
+ RefPtr<Type> checkProperType(TranslationUnitRequest * tu, TypeExp typeExp)
+ {
+ RefPtr<Type> type;
+ DiagnosticSink nSink;
+ nSink.sourceManager = tu->compileRequest->sourceManager;
+ SemanticsVisitor visitor(
+ &nSink,
+ tu->compileRequest,
+ tu);
+ auto typeOut = visitor.CheckProperType(typeExp);
+ if (!nSink.errorCount)
+ {
+ type = typeOut.type;
+ }
+ return type;
+ }
+
void validateEntryPoint(
EntryPointRequest* entryPoint)
{
@@ -6956,15 +6973,9 @@ namespace Slang
{
RefPtr<Expr> typeExpr = entryPoint->compileRequest->parseTypeString(entryPoint->getTranslationUnit(),
name, s);
- DiagnosticSink nSink;
- SemanticsVisitor visitor(
- &nSink,
- translationUnit->compileRequest,
- translationUnit);
- auto typeOut = visitor.CheckProperType(TypeExp(typeExpr));
- if (!nSink.errorCount)
- {
- type = typeOut.type;
+ type = checkProperType(translationUnit, TypeExp(typeExpr));
+ if (type)
+ {
break;
}
}
diff --git a/source/slang/compiler.h b/source/slang/compiler.h
index 4854f4060..960e67ffe 100644
--- a/source/slang/compiler.h
+++ b/source/slang/compiler.h
@@ -319,6 +319,8 @@ namespace Slang
~CompileRequest();
RefPtr<Expr> parseTypeString(TranslationUnitRequest * translationUnit, String typeStr, RefPtr<Scope> scope);
+
+ Type* getTypeFromString(String typeStr);
void parseTranslationUnit(
TranslationUnitRequest* translationUnit);
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 53f02cc56..18216de81 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -7500,7 +7500,7 @@ String emitEntryPoint(
// none of our target supports generics, or interfaces,
// so we need to specialize those away.
//
- specializeGenerics(irModule);
+ specializeGenerics(irModule, sharedContext.target);
// Debugging code for IR transformations...
#if 0
diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h
index 23e948b3a..dedc906d0 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -641,7 +641,8 @@ void specializeIRForEntryPoint(
// Find suitable uses of the `specialize` instruction that
// can be replaced with references to specialized functions.
void specializeGenerics(
- IRModule* module);
+ IRModule* module,
+ CodeGenTarget target);
//
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 994ac82ff..7318bff4c 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -7,6 +7,13 @@
namespace Slang
{
+ struct IRSpecContext;
+
+ IRGlobalValue* cloneGlobalValueWithMangledName(
+ IRSpecContext* context,
+ String const& mangledName,
+ IRGlobalValue* originalVal);
+
static const IROpInfo kIROpInfos[] =
{
@@ -3065,6 +3072,9 @@ namespace Slang
struct IRSharedSpecContext
{
+ // The code-generation target in use
+ CodeGenTarget target;
+
// The specialized module we are building
IRModule* module;
@@ -3091,6 +3101,10 @@ namespace Slang
struct IRSpecContextBase
{
+ // A map from the mangled name of a global variable
+ // to the layout to use for it.
+ Dictionary<String, VarLayout*> globalVarLayouts;
+
IRSharedSpecContext* shared;
IRSharedSpecContext* getShared() { return shared; }
@@ -3224,13 +3238,6 @@ namespace Slang
struct IRSpecContext : IRSpecContextBase
{
- // The code-generation target in use
- CodeGenTarget target;
-
- // A map from the mangled name of a global variable
- // to the layout to use for it.
- Dictionary<String, VarLayout*> globalVarLayouts;
-
// Override the "maybe clone" logic so that we always clone
virtual IRValue* maybeCloneValue(IRValue* originalVal) override;
@@ -3434,18 +3441,31 @@ namespace Slang
return newDeclRef;
}
-
IRValue* cloneValue(
IRSpecContextBase* context,
IRValue* originalValue)
{
IRValue* clonedValue = nullptr;
if (context->getClonedValues().TryGetValue(originalValue, clonedValue))
+ {
return clonedValue;
+ }
return context->maybeCloneValue(originalValue);
}
+ IRValue* maybeCloneValueWithMangledName(
+ IRSpecContextBase* context,
+ IRGlobalValue* originalValue)
+ {
+ for (auto gv = context->shared->module->firstGlobalValue; gv; gv = gv->nextGlobalValue)
+ {
+ if (gv->mangledName == originalValue->mangledName)
+ return gv;
+ }
+ return cloneValue(context, originalValue);
+ }
+
void cloneInst(
IRSpecContextBase* context,
IRBuilder* builder,
@@ -3468,18 +3488,23 @@ namespace Slang
context->maybeCloneType(originalInst->type),
0, nullptr,
argCount, nullptr);
- builder->addInst(clonedInst);
registerClonedValue(context, clonedInst, originalInst);
-
- cloneDecorations(context, clonedInst, originalInst);
-
+ auto oldBuilder = context->builder;
+ context->builder = builder;
for (UInt aa = 0; aa < argCount; ++aa)
{
IRValue* originalArg = originalInst->getArg(aa);
- IRValue* clonedArg = cloneValue(context, originalArg);
-
+ IRValue* clonedArg;
+ if (originalArg->op == kIROp_witness_table)
+ clonedArg = cloneGlobalValueWithMangledName((IRSpecContext*)context,
+ ((IRGlobalValue*)originalArg)->mangledName, (IRGlobalValue*)originalArg);
+ else
+ clonedArg = cloneValue(context, originalArg);
clonedInst->getArgs()[aa].init(clonedInst, clonedArg);
}
+ builder->addInst(clonedInst);
+ context->builder = oldBuilder;
+ cloneDecorations(context, clonedInst, originalInst);
}
break;
@@ -3524,12 +3549,15 @@ namespace Slang
IRSpecContextBase* context,
IRWitnessTable* originalTable,
IROriginalValuesForClone const& originalValues,
- IRWitnessTable* dstTable = nullptr)
+ IRWitnessTable* dstTable = nullptr,
+ bool registerValue = true)
{
auto clonedTable = dstTable ? dstTable : context->builder->createWitnessTable();
- registerClonedValue(context, clonedTable, originalValues);
+ if (registerValue)
+ registerClonedValue(context, clonedTable, originalValues);
auto mangledName = originalTable->mangledName;
+
clonedTable->mangledName = mangledName;
clonedTable->genericDecl = originalTable->genericDecl;
clonedTable->subTypeDeclRef = originalTable->subTypeDeclRef;
@@ -3539,8 +3567,11 @@ namespace Slang
// Clone the entries in the witness table as well
for( auto originalEntry : originalTable->entries )
{
- auto clonedKey = context->maybeCloneValue(originalEntry->requirementKey.usedValue);
- auto clonedVal = context->maybeCloneValue(originalEntry->satisfyingVal.usedValue);
+ auto clonedKey = cloneValue(context, originalEntry->requirementKey.usedValue);
+
+ // if a global val with the mangled name already exists, don't clone again
+ auto clonedVal = maybeCloneValueWithMangledName(context, (IRGlobalValue*)(originalEntry->satisfyingVal.usedValue));
+
/*auto clonedEntry = */context->builder->createWitnessTableEntry(
clonedTable,
clonedKey,
@@ -3555,7 +3586,7 @@ namespace Slang
IRWitnessTable* originalTable,
IRWitnessTable* dstTable = nullptr)
{
- return cloneWitnessTableImpl(context, originalTable, IROriginalValuesForClone(), dstTable);
+ return cloneWitnessTableImpl(context, originalTable, IROriginalValuesForClone(), dstTable, false);
}
void cloneGlobalValueWithCodeCommon(
@@ -3690,14 +3721,6 @@ namespace Slang
// and their instructions.
cloneFunctionCommon(context, clonedFunc, originalFunc);
- // for now, clone all unreferenced witness tables
- for (auto gv = context->getOriginalModule()->getFirstGlobalValue();
- gv; gv = gv->getNextValue())
- {
- if (gv->op == kIROp_witness_table)
- cloneGlobalValue(context, (IRWitnessTable*)gv);
- }
-
// We need to attach the layout information for
// the entry point to this declaration, so that
// we can use it to inform downstream code emit.
@@ -3746,7 +3769,7 @@ namespace Slang
// TODO: We shouldn't be using strings for this.
String getTargetName(IRSpecContext* context)
{
- switch( context->target )
+ switch( context->shared->target )
{
case CodeGenTarget::HLSL:
return "hlsl";
@@ -4035,7 +4058,8 @@ namespace Slang
IRSharedSpecContext* sharedContext,
Session* session,
IRModule* module,
- IRModule* originalModule)
+ IRModule* originalModule,
+ CodeGenTarget target)
{
SharedIRBuilder* sharedBuilder = &sharedContext->sharedBuilderStorage;
@@ -4053,7 +4077,7 @@ namespace Slang
sharedContext->module = module;
sharedContext->originalModule = originalModule;
-
+ sharedContext->target = target;
// We will populate a map with all of the IR values
// that use the same mangled name, to make lookup easier
// in other steps.
@@ -4110,7 +4134,9 @@ namespace Slang
sharedContext,
compileRequest->mSession,
nullptr,
- originalIRModule);
+ originalIRModule,
+ target);
+
state->irModule = sharedContext->module;
// We also need to attach the IR definitions for symbols from
@@ -4123,7 +4149,6 @@ namespace Slang
auto context = state->getContext();
context->shared = sharedContext;
context->builder = &sharedContext->builderStorage;
- context->target = target;
// Create the GlobalGenericParamSubstitution for substituting global generic types
// into user-provided type arguments
@@ -4146,6 +4171,12 @@ namespace Slang
context->globalVarLayouts.AddIfNotExists(mangledName, globalVarLayout);
}
+ // for now, clone all unreferenced witness tables
+ for (auto sym :context->getSymbols())
+ {
+ if (sym.Value->irGlobalValue->op == kIROp_witness_table)
+ cloneGlobalValue(context, (IRWitnessTable*)sym.Value->irGlobalValue);
+ }
return state;
}
@@ -4263,7 +4294,31 @@ namespace Slang
return symbol->irGlobalValue;
}
else
- return nullptr;
+ {
+ // we don't have the required witness table yet,
+ // try to emit a specialize instruction to get one
+ auto subDeclRef = subtypeWitness->sub->AsDeclRefType();
+ auto subDeclRefGen = DeclRef<Decl>(subDeclRef->declRef.decl,
+ createDefaultSubstitutions(context->builder->getSession(), subDeclRef->declRef.decl));
+
+ String genericName = getMangledNameForConformanceWitness(
+ subDeclRefGen,
+ subtypeWitness->sup);
+ if (context->getSymbols().TryGetValue(genericName, symbol))
+ {
+ auto specInst = context->builder->emitSpecializeInst(subtypeWitness->sup, symbol->irGlobalValue, subDeclRef->declRef);
+ return specInst;
+ }
+ else
+ {
+ SLANG_UNEXPECTED("witness table not exist");
+ UNREACHABLE_RETURN(nullptr);
+ }
+ }
+ }
+ else if (auto intVal = dynamic_cast<ConstantIntVal*>(val))
+ {
+ return context->builder->getIntValue(context->shared->originalModule->session->getBuiltinType(BaseType::Int), intVal->value);
}
else if (auto proxyVal = dynamic_cast<IRProxyVal*>(val))
{
@@ -4321,10 +4376,34 @@ namespace Slang
return getIRValue(context, subst->args[argIndex]);
}
+ else if (auto valDeclRef = declRef.As<GenericValueParamDecl>())
+ {
+ // We have a constraint, but we need to find its index in the
+ // argument list of the substitutions.
+ UInt argIdx = 0;
+ bool found = false;
+ for (auto cd : genericDecl->Members)
+ {
+ if (cd.Ptr() == valDeclRef.getDecl())
+ {
+ found = true;
+ break;
+ }
+ if (cd.As<GenericTypeParamDecl>())
+ argIdx++;
+ else if (cd.As<GenericValueParamDecl>())
+ argIdx++;
+ }
+ assert(found);
+
+ assert(argIdx < subst->args.Count());
+
+ return getIRValue(context, subst->args[argIdx]);
+ }
else
{
- SLANG_UNEXPECTED("unhandled case");
- return nullptr;
+ SLANG_UNEXPECTED("unimplemented");
+ UNREACHABLE_RETURN(nullptr);
}
}
@@ -4342,12 +4421,13 @@ namespace Slang
// of the generic we are specializing, and in that case
// we nee to translate it over to the equiavalent of
// the `Val` we have been given.
- if(declRef.getDecl()->ParentDecl == genSubst->genericDecl)
+ if(declRef.getDecl()->ParentDecl == genSubst->genericDecl &&
+ (declRef.As<GenericTypeParamDecl>() || declRef.As<GenericValueParamDecl>()||
+ declRef.As<GenericTypeConstraintDecl>()))
{
if (auto substVal = getSubstValue(this, declRef))
return substVal;
}
-
int diff = 0;
auto substDeclRef = declRefVal->declRef.SubstituteImpl(subst, &diff);
if(!diff)
@@ -4455,7 +4535,6 @@ namespace Slang
// has already been made. To do that we will need to
// compute the mangled name of the specialized function,
// so that we can look for existing declarations.
- String specMangledName;
String specializedMangledName = getMangledNameForConformanceWitness(specDeclRef.Substitute(originalTable->subTypeDeclRef),
specDeclRef.Substitute(originalTable->supTypeDeclRef));
@@ -4466,13 +4545,15 @@ namespace Slang
// avoid it by building a dictionary ahead of time,
// as is being done for the `IRSpecContext` used above.
// We can probalby use the same basic context, actually.
- auto module = originalTable->parentModule;
- for (auto gv = module->getFirstGlobalValue(); gv; gv = gv->getNextValue())
+ if (!dstTable)
{
- if (gv->mangledName == specMangledName)
- return (IRWitnessTable*)gv;
+ auto module = sharedContext->module;
+ for (auto gv = module->getFirstGlobalValue(); gv; gv = gv->getNextValue())
+ {
+ if (gv->mangledName == specializedMangledName)
+ return (IRWitnessTable*)gv;
+ }
}
-
RefPtr<GenericSubstitution> newSubst = cloneSubstitutionsForSpecialization(
sharedContext,
specDeclRef.substitutions.genericSubstitutions,
@@ -4483,13 +4564,12 @@ namespace Slang
context.builder = &sharedContext->builderStorage;
context.subst = specDeclRef.substitutions;
context.subst.genericSubstitutions = newSubst;
-
// TODO: other initialization is needed here...
auto specTable = cloneWitnessTableWithoutRegistering(&context, originalTable, dstTable);
// Set up the clone to recognize that it is no longer generic
- specTable->mangledName = specMangledName;
+ specTable->mangledName = specializedMangledName;
specTable->genericDecl = nullptr;
// Specialization of witness tables should trigger cascading specializations
@@ -4499,8 +4579,9 @@ namespace Slang
if (entry->satisfyingVal.usedValue->op == kIROp_Func)
{
IRFunc* func = (IRFunc*)entry->satisfyingVal.usedValue;
- if (func->getGenericDecl())
- entry->satisfyingVal.set(getSpecializedFunc(sharedContext, func, specDeclRef));
+ auto specFunc = getSpecializedFunc(sharedContext, func, specDeclRef);
+ entry->satisfyingVal.set(specFunc);
+ insertGlobalValueSymbol(sharedContext, specFunc);
}
}
@@ -4526,13 +4607,16 @@ namespace Slang
specMangledName = getMangledName(specDeclRef);
else
specMangledName = mangleSpecializedFuncName(genericFunc->mangledName, specDeclRef.substitutions);
-
+ RefPtr<IRSpecSymbol> symb;
+ if (sharedContext->symbols.TryGetValue(specMangledName, symb))
+ {
+ return (IRFunc*)(symb->irGlobalValue);
+ }
// TODO: This is a terrible linear search, and we should
// avoid it by building a dictionary ahead of time,
// as is being done for the `IRSpecContext` used above.
// We can probalby use the same basic context, actually.
- auto module = genericFunc->parentModule;
- for (auto gv = module->getFirstGlobalValue(); gv; gv = gv->getNextValue())
+ for (auto gv = sharedContext->module->getFirstGlobalValue(); gv; gv = gv->getNextValue())
{
if (gv->mangledName == specMangledName)
return (IRFunc*) gv;
@@ -4639,7 +4723,8 @@ namespace Slang
// are known, and specialize the callee based on those
// known values.
void specializeGenerics(
- IRModule* module)
+ IRModule* module,
+ CodeGenTarget target)
{
IRSharedSpecContext sharedContextStorage;
auto sharedContext = &sharedContextStorage;
@@ -4648,7 +4733,8 @@ namespace Slang
sharedContext,
module->session,
module,
- module);
+ module,
+ target);
// Our goal here is to find `specialize` instructions that
// can be replaced with references to a suitably sepcialized
@@ -4895,11 +4981,10 @@ namespace Slang
table = findWitnessTableByName(genericWitnessTableName);
SLANG_ASSERT(table);
WitnessTableSpecializationWorkItem workItem;
- workItem.srcTable = (IRWitnessTable*)table;
+ workItem.srcTable = (IRWitnessTable*)cloneGlobalValue(context, (IRWitnessTable*)(table));
workItem.dstTable = context->builder->createWitnessTable();
workItem.dstTable->mangledName = getMangledNameForConformanceWitness(subDeclRefType->declRef, subtypeWitness->sup);
workItem.specDeclRef = subDeclRefType->declRef;
- registerClonedValue(context, workItem.dstTable, workItem.srcTable);
witnessTablesToSpecailize.Add(workItem);
table = workItem.dstTable;
}
diff --git a/source/slang/legalize-types.cpp b/source/slang/legalize-types.cpp
index 211685aa2..d1cef4dac 100644
--- a/source/slang/legalize-types.cpp
+++ b/source/slang/legalize-types.cpp
@@ -916,7 +916,7 @@ LegalType legalizeType(
}
legalType = builder.getResult();
- context->mapDeclRefToLegalType.Add(declRef, legalType);
+ context->mapDeclRefToLegalType.AddIfNotExists(declRef, legalType);
return legalType;
}
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 5e7e05a23..5d710725a 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -1021,6 +1021,7 @@ RefPtr<IRFuncType> getFuncType(
return funcType;
}
+SubstitutionSet lowerSubstitutions(IRGenContext* context, SubstitutionSet subst);
//
struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, LoweredTypeInfo>
@@ -1080,8 +1081,6 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower
// TODO: actually test what module the type is coming from.
lowerDecl(context, type->declRef);
-
-
return LoweredTypeInfo(type);
}
@@ -3006,6 +3005,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return globalVal;
}
+ LoweredValInfo visitGenericValueParamDecl(GenericValueParamDecl* decl)
+ {
+ return LoweredValInfo::simple(context->irBuilder->getDeclRefVal(DeclRefBase(decl)));
+ }
+
LoweredValInfo visitVarDeclBase(VarDeclBase* decl)
{
// Detect global (or effectively global) variables
@@ -3733,7 +3737,10 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
if (auto innerFuncDecl = genDecl->inner->As<FuncDecl>())
return lowerFuncDecl(innerFuncDecl);
else if (auto innerStructDecl = genDecl->inner->As<StructDecl>())
+ {
+ visitAggTypeDecl(innerStructDecl);
return LoweredValInfo();
+ }
SLANG_RELEASE_ASSERT(false);
UNREACHABLE_RETURN(LoweredValInfo());
}
@@ -3910,6 +3917,32 @@ RefPtr<GenericSubstitution> lowerGenericSubstitutions(
return result;
}
+RefPtr<GlobalGenericParamSubstitution> lowerGlobalGenericSubstitutions(
+ IRGenContext* context,
+ GlobalGenericParamSubstitution* genSubst)
+{
+ if (!genSubst)
+ return nullptr;
+ RefPtr<GlobalGenericParamSubstitution> result;
+ RefPtr<GlobalGenericParamSubstitution> newSubst = new GlobalGenericParamSubstitution();
+ newSubst->actualType = lowerSubstitutionArg(context, genSubst->actualType);
+ newSubst->paramDecl = genSubst->paramDecl;
+ for (auto & tbl : genSubst->witnessTables)
+ {
+ auto ntbl = tbl;
+ ntbl.Value = lowerSubstitutionArg(context, tbl.Value);
+ newSubst->witnessTables.Add(ntbl);
+ }
+ result = newSubst;
+ if (genSubst->outer)
+ {
+ result->outer = lowerGlobalGenericSubstitutions(
+ context,
+ genSubst->outer);
+ }
+ return result;
+}
+
RefPtr<ThisTypeSubstitution> lowerThisTypeSubstitution(
IRGenContext* context,
ThisTypeSubstitution* thisSubst)
@@ -3926,7 +3959,7 @@ SubstitutionSet lowerSubstitutions(IRGenContext* context, SubstitutionSet subst)
SubstitutionSet rs;
rs.genericSubstitutions = lowerGenericSubstitutions(context, subst.genericSubstitutions);
rs.thisTypeSubstitution = lowerThisTypeSubstitution(context, subst.thisTypeSubstitution);
- rs.globalGenParamSubstitutions = subst.globalGenParamSubstitutions;
+ rs.globalGenParamSubstitutions = lowerGlobalGenericSubstitutions(context, subst.globalGenParamSubstitutions);
return rs;
}
@@ -3973,10 +4006,10 @@ LoweredValInfo maybeEmitSpecializeInst(IRGenContext* context,
// need to walk through those and replace things in
// cases where the `Val`s used for substitution should
// lower to something other than their original form.
- auto lowedNewSubst = lowerGenericSubstitutions(context, newSubst);
- DeclRef<Decl> newDeclRef = DeclRef<Decl>(declRef.decl,
- SubstitutionSet(lowedNewSubst, declRef.substitutions.thisTypeSubstitution,
- declRef.substitutions.globalGenParamSubstitutions));
+ SubstitutionSet oldSubst = declRef.substitutions;
+ oldSubst.genericSubstitutions = newSubst;
+ auto lowedNewSubst = lowerSubstitutions(context, oldSubst);
+ DeclRef<Decl> newDeclRef = DeclRef<Decl>(declRef.decl, lowedNewSubst);
RefPtr<Type> type;
if (auto declType = val->getType())
@@ -4014,9 +4047,9 @@ static void lowerEntryPointToIR(
return;
}
// we need to lower all global type arguments as well
+ auto loweredEntryPointFunc = ensureDecl(context, entryPointFuncDecl);
for (auto arg : entryPointRequest->genericParameterTypes)
lowerType(context, arg);
- auto loweredEntryPointFunc = ensureDecl(context, entryPointFuncDecl);
}
#if 0
diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp
index c9de75d6e..b0be58274 100644
--- a/source/slang/reflection.cpp
+++ b/source/slang/reflection.cpp
@@ -433,20 +433,8 @@ SLANG_API SlangReflectionType * spReflection_FindTypeByName(SlangReflection * re
auto context = convert(reflection);
auto compileRequest = context->targetRequest->compileRequest;
- RefPtr<Type> result;
- if (compileRequest->types.TryGetValue(name, result))
- return (SlangReflectionType*)result.Ptr();
-
- auto nameObj = compileRequest->getNamePool()->getName(name);
- Decl* resultDecl = compileRequest->lookupGlobalDecl(nameObj);
- if (resultDecl)
- {
- RefPtr<DeclRefType> declRefType = new DeclRefType();
- declRefType->declRef.decl = resultDecl;
- compileRequest->types[name] = declRefType;
- return (SlangReflectionType*)declRefType.Ptr();
- }
- return nullptr;
+ RefPtr<Type> result = compileRequest->getTypeFromString(name);
+ return (SlangReflectionType*)result.Ptr();
}
SLANG_API SlangReflectionTypeLayout* spReflection_GetTypeLayout(
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index d907e7614..4c9ecf8a8 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -131,6 +131,7 @@ RefPtr<Expr> CompileRequest::parseTypeString(TranslationUnitRequest * translatio
Slang::SourceFile srcFile;
srcFile.content = typeStr;
DiagnosticSink sink;
+ sink.sourceManager = sourceManager;
auto tokens = preprocessSource(
&srcFile,
&sink,
@@ -140,6 +141,34 @@ RefPtr<Expr> CompileRequest::parseTypeString(TranslationUnitRequest * translatio
return parseTypeFromSourceFile(translationUnit, tokens, &sink, scope);
}
+RefPtr<Type> checkProperType(TranslationUnitRequest * tu, TypeExp typeExp);
+Type* CompileRequest::getTypeFromString(String typeStr)
+{
+ RefPtr<Type> type;
+ if (types.TryGetValue(typeStr, type))
+ return type;
+ auto translationUnit = translationUnits.First();
+ List<RefPtr<Scope>> scopesToTry;
+ for (auto tu : translationUnits)
+ scopesToTry.Add(tu->SyntaxNode->scope);
+ for (auto & module : loadedModulesList)
+ scopesToTry.Add(module->moduleDecl->scope);
+ // parse type name
+ for (auto & s : scopesToTry)
+ {
+ RefPtr<Expr> typeExpr = parseTypeString(translationUnit,
+ typeStr, s);
+ type = checkProperType(translationUnit, TypeExp(typeExpr));
+ if (type)
+ break;
+ }
+ if (type)
+ {
+ types[typeStr] = type;
+ }
+ return type.Ptr();
+}
+
void CompileRequest::parseTranslationUnit(
TranslationUnitRequest* translationUnit)
{
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index 85a702726..ab4a5f94c 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -362,12 +362,14 @@ void Type::accept(IValVisitor* visitor, void* extra)
{
int diff = 0;
auto elementType = baseType->SubstituteImpl(subst, &diff).As<Type>();
+ auto arrlen = ArrayLength->SubstituteImpl(subst, &diff).As<IntVal>();
+ SLANG_ASSERT(arrlen);
if (diff)
{
*ioDiff = 1;
auto rsType = getArrayType(
elementType,
- ArrayLength);
+ arrlen);
return rsType;
}
return this;