summaryrefslogtreecommitdiffstats
path: root/source/slang/ir.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2017-11-07 19:09:40 -0500
committerTim Foley <tfoleyNV@users.noreply.github.com>2017-11-07 16:09:40 -0800
commit6e591ada0eb652c320bba4bd8a46cd579946df01 (patch)
tree768229fb26204b6b0a89201d9b14c32e9203c098 /source/slang/ir.cpp
parent939688e963fde7a0485f210ef2674c27692021a4 (diff)
Support generic interface methods (#251)
* improve diagnostic messages and prevent fatal errors from crashing the compiler. * fix top level exception catching. * spelling fix * change wording of invalidSwizzleExpr diagnostic * add speculative GenericsApp expr parsing * add new test case of cascading generics call. * Fixing bugs in compiling cascaded generic function calls. Add implementation of DeclaredSubTypeWitness::SubstituteImpl() This is not needed by the type checker, but needed by IR specialization. When input source contains cascading generic function call, the arguments to `specialize` instruction is currently represented as a substitution. The arg values of this subsittution can be a `DeclaredSubTypeWitness` when a generic function uses one of its generic parameter to specialize another generic function. When the top level generics function is being specialized, this substitution argument, which is a `DeclaredSubTypeWitness`, needs to be substituted with the witness that used to specialize the top level function in the specialized specialize instruction as well. * add a test case for cascading generic function call. * parser bug fix * fixes #255 * add test case for issue #255 * Generate missing `specialize` instruction when calling a generic method from an interface constraint. When calling a generic method via an interface, we should be generating the following ir: ... f = lookup_interface_method(...) f_s = specailize(f, declRef) ... This commit fixes this `emitFuncRef` function to emit the needed `specialize` instruction. * fixes #260 This fix follows the second apporach in the disucssion. It generated mangled name for specialized functions by appending new substitution type names to the original mangled name. * Disabling removing and re-inserting specailized functions in getSpecalizeFunc() I am not sure why it is needed, it seems HLSL and GLSL backends are generating forward declarations anyways, so the order of functions in IRModule shouldn't matter. * cleanup and complete test cases. * fix warnings
Diffstat (limited to 'source/slang/ir.cpp')
-rw-r--r--source/slang/ir.cpp36
1 files changed, 24 insertions, 12 deletions
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 439bc7797..b1af6521c 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -55,15 +55,15 @@ namespace Slang
}
}
- void IRUse::set(IRValue* usedValue)
+ void IRUse::set(IRValue* usedVal)
{
// clear out the old value
- if (usedValue)
+ if (usedVal)
{
*prevLink = nextUse;
}
- init(user, usedValue);
+ init(user, usedVal);
}
void IRUse::clear()
@@ -3750,8 +3750,6 @@ namespace Slang
{
if( auto subtypeWitness = dynamic_cast<SubtypeWitness*>(val) )
{
- // We need to look up the IR value that represents the
- // given subtype witness.
String mangledName = getMangledNameForConformanceWitness(
subtypeWitness->sub,
subtypeWitness->sup);
@@ -3948,8 +3946,11 @@ 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 = getMangledName(specDeclRef);
+ String specMangledName;
+ if (genericFunc->genericDecl == specDeclRef.decl)
+ specMangledName = getMangledName(specDeclRef);
+ else
+ specMangledName = mangleSpecializedFuncName(genericFunc->mangledName, specDeclRef.substitutions);
// TODO: This is a terrible linear search, and we should
// avoid it by building a dictionary ahead of time,
@@ -3992,8 +3993,8 @@ namespace Slang
//
// TODO: This shouldn't be needed, if we introduce a sorting
// step before we emit code.
- specFunc->removeFromParent();
- specFunc->insertAfter(genericFunc);
+ //specFunc->removeFromParent();
+ //specFunc->insertAfter(genericFunc);
// At this point we've created a new non-generic function,
// which means we should add it to our work list for
@@ -4026,8 +4027,20 @@ namespace Slang
auto keyDeclRef = ((IRDeclRef*) requirementKey)->declRef;
// If the keys don't match, continue with the next entry.
- if(!keyDeclRef.Equals(requirementDeclRef))
- continue;
+ if (!keyDeclRef.Equals(requirementDeclRef))
+ {
+ // requirementDeclRef may be pointing to the inner decl of a generic decl
+ // in this case we compare keyDeclRef against the parent decl of requiredDeclRef
+ if (auto genRequiredDeclRef = requirementDeclRef.GetParent().As<GenericDecl>())
+ {
+ if (!keyDeclRef.Equals(genRequiredDeclRef))
+ {
+ continue;
+ }
+ }
+ else
+ continue;
+ }
// If the keys matched, then we use the value from
// this entry.
@@ -4178,7 +4191,6 @@ namespace Slang
// Use the witness table to look up the value that
// satisfies the requirement.
auto satisfyingVal = findWitnessVal(witnessTable, requirementDeclRef);
-
// We expect to always find something, but lets just
// be careful here.
if(!satisfyingVal)