diff options
Diffstat (limited to 'source/slang/slang-type-layout.cpp')
| -rw-r--r-- | source/slang/slang-type-layout.cpp | 65 |
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()) |
