diff options
| author | Yong He <yonghe@outlook.com> | 2017-11-07 19:09:40 -0500 |
|---|---|---|
| committer | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-11-07 16:09:40 -0800 |
| commit | 6e591ada0eb652c320bba4bd8a46cd579946df01 (patch) | |
| tree | 768229fb26204b6b0a89201d9b14c32e9203c098 /source/slang/ir.cpp | |
| parent | 939688e963fde7a0485f210ef2674c27692021a4 (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.cpp | 36 |
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) |
