summaryrefslogtreecommitdiffstats
path: root/source/slang/lookup.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2018-01-16 10:52:10 -0800
committerTim Foley <tfoleyNV@users.noreply.github.com>2018-01-16 10:52:10 -0800
commit59691aeeb013c5bb7cdaa31a6fc572eebd8be610 (patch)
tree310754847c4c83ffa8fd97fcaadc7cdf7b14c253 /source/slang/lookup.cpp
parent68fd4485708bf98c66e27e330692138f3eb6f289 (diff)
Allow extension on interface (#369)
This completes item 5 in issue #361. The interesting change is that when checking for interface conformance, we include the requirements (include transitive interfaces) defined in extensions as well. (check.cpp line 1946) All the other changes are for one thing: reoder the semantic checkings to two explicit stages: check header and check body. In check header phase, we check everything except function bodies, register all extensions with their target decls, then check interface conformances for all concrete types. In body checking phase, we look inside the function bodies and check concrete statements/expressions. This change ensures that we take extension into consideration in all places where it should be.
Diffstat (limited to 'source/slang/lookup.cpp')
-rw-r--r--source/slang/lookup.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/source/slang/lookup.cpp b/source/slang/lookup.cpp
index 0791c508b..5f925a1c2 100644
--- a/source/slang/lookup.cpp
+++ b/source/slang/lookup.cpp
@@ -302,15 +302,26 @@ void DoLocalLookupImpl(
// for interface decls, also lookup in the base interfaces
if (request.semantics)
{
- if (auto interfaceDeclRef = containerDeclRef.As<InterfaceDecl>())
+ bool isInterface = containerDeclRef.As<InterfaceDecl>() ? true : false;
+ // if we are looking at an extension, find the target decl that we are extending
+ if (auto extDeclRef = containerDeclRef.As<ExtensionDecl>())
{
- auto baseInterfaces = getMembersOfType<InheritanceDecl>(interfaceDeclRef);
+ auto targetDeclRefType = extDeclRef.getDecl()->targetType->AsDeclRefType();
+ SLANG_ASSERT(targetDeclRefType);
+ int diff = 0;
+ auto targetDeclRef = targetDeclRefType->declRef.As<ContainerDecl>().SubstituteImpl(containerDeclRef.substitutions, &diff);
+ isInterface = targetDeclRef.As<InterfaceDecl>() ? true : false;
+ }
+ // if we are looking inside an interface decl, try find in the interfaces it inherits from
+ if (isInterface)
+ {
+ auto baseInterfaces = getMembersOfType<InheritanceDecl>(containerDeclRef);
for (auto inheritanceDeclRef : baseInterfaces)
{
auto baseType = inheritanceDeclRef.getDecl()->base.type.As<DeclRefType>();
SLANG_ASSERT(baseType);
int diff = 0;
- auto baseInterfaceDeclRef = baseType->declRef.SubstituteImpl(interfaceDeclRef.substitutions, &diff);
+ auto baseInterfaceDeclRef = baseType->declRef.SubstituteImpl(containerDeclRef.substitutions, &diff);
DoLocalLookupImpl(session, name, baseInterfaceDeclRef.As<ContainerDecl>(), request, result, inBreadcrumbs);
}
}