summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-type-layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-type-layout.cpp')
-rw-r--r--source/slang/slang-type-layout.cpp65
1 files changed, 57 insertions, 8 deletions
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index 0de6348bf..5bbcd2eb1 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -5191,9 +5191,11 @@ static TypeLayoutResult _createTypeLayout(TypeLayoutContext& context, Type* type
// If we are trying to get the layout of some extern type, do our best
// to look it up in other loaded modules and generate the type layout
// based on that.
- declRefType = context.lookupExternDeclRefType(declRefType);
- auto declRef = declRefType->getDeclRef();
+ auto resolvedType = context.lookupExternDeclRefType(declRefType);
+ if (resolvedType != type)
+ return _createTypeLayout(context, resolvedType);
+ auto declRef = declRefType->getDeclRef();
if (auto structDeclRef = declRef.as<StructDecl>())
{
@@ -5888,26 +5890,71 @@ GlobalGenericParamDecl* GenericParamTypeLayout::getGlobalGenericParamDecl()
return rsDeclRef.getDecl();
}
-DeclRefType* TypeLayoutContext::lookupExternDeclRefType(DeclRefType* declRefType)
+// Get the decl ref to the outer generic if the decl referenced by `declRef` is generic.
+DeclRef<GenericDecl> getOuterGeneric(DeclRef<Decl> declRef)
+{
+ if (auto directDeclRef = as<DirectDeclRef>(declRef.declRefBase))
+ {
+ if (as<GenericDecl>(directDeclRef->getDecl()))
+ return DeclRef<GenericDecl>(directDeclRef);
+ if (as<GenericDecl>(directDeclRef->getParent()->getDecl()))
+ return DeclRef<GenericDecl>(directDeclRef->getParent());
+ }
+ else if (auto genAppDeclRef = as<GenericAppDeclRef>(declRef.declRefBase))
+ {
+ return DeclRef<GenericDecl>(genAppDeclRef->getBase());
+ }
+ return DeclRef<GenericDecl>();
+}
+
+Type* TypeLayoutContext::lookupExternDeclRefType(DeclRefType* declRefType)
{
const auto declRef = declRefType->getDeclRef();
const auto decl = declRef.getDecl();
const auto isExtern =
decl->hasModifier<ExternAttribute>() || decl->hasModifier<ExternModifier>();
+ Type* resultType = declRefType;
if (isExtern)
{
if (!externTypeMap)
buildExternTypeMap();
const auto mangledName = getMangledName(targetReq->getLinkage()->getASTBuilder(), decl);
- externTypeMap->tryGetValue(mangledName, declRefType);
+ externTypeMap->tryGetValue(mangledName, resultType);
+ if (auto resolvedDeclRef = isDeclRefTypeOf<Decl>(resultType))
+ {
+ if (resolvedDeclRef != declRef)
+ {
+ // If declRef is a GenericApp, we should replace the generic base to
+ // resolveDeclRef's base.
+ if (auto originalGenericApp = as<GenericAppDeclRef>(declRef.declRefBase))
+ {
+ if (auto resolvedOuterGeneric = getOuterGeneric(resolvedDeclRef.getDecl()))
+ {
+ auto substGenericApp = astBuilder->getGenericAppDeclRef(
+ resolvedOuterGeneric,
+ originalGenericApp->getArgs());
+ resultType = DeclRefType::create(astBuilder, substGenericApp);
+ }
+ }
+ }
+ }
+ }
+
+ // If the type is an alias of another type, then we should create the type layout
+ // from the aliased type instead.
+ if (auto aggTypeDeclRef = isDeclRefTypeOf<AggTypeDecl>(resultType))
+ {
+ if (auto aliasedType = as<Type>(getAliasedType(astBuilder, aggTypeDeclRef)))
+ {
+ return aliasedType;
+ }
}
- return declRefType;
+ return resultType;
}
void TypeLayoutContext::buildExternTypeMap()
{
externTypeMap.emplace();
- const auto linkage = targetReq->getLinkage();
HashSet<String> externNames;
Dictionary<String, DeclRefType*> allTypes;
@@ -5916,6 +5963,8 @@ void TypeLayoutContext::buildExternTypeMap()
// We'll match them up later
auto processDecl = [&](auto&& go, Decl* decl) -> void
{
+ if (auto genericDecl = as<GenericDecl>(decl))
+ decl = genericDecl->inner;
const auto isExtern =
decl->hasModifier<ExternAttribute>() || decl->hasModifier<ExternModifier>();
@@ -5933,7 +5982,7 @@ void TypeLayoutContext::buildExternTypeMap()
}
}
- if (auto scopeDecl = as<ScopeDecl>(decl))
+ if (auto scopeDecl = isStaticScopeDecl(decl))
{
for (auto member : scopeDecl->getDirectMemberDecls())
{
@@ -5942,7 +5991,7 @@ void TypeLayoutContext::buildExternTypeMap()
}
};
- for (const auto& m : linkage->loadedModulesList)
+ for (const auto& m : programLayout->getProgram()->getModuleDependencies())
{
const auto& ast = m->getModuleDecl();
for (auto member : ast->getDirectMemberDecls())