Skip to content

Commit 7ef027d

Browse files
committed
Resolve 'extern' types during type layout generation if possible
Closes shader-slang#5994 Closes shader-slang#6437
1 parent f90a763 commit 7ef027d

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

source/slang/slang-parameter-binding.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -2383,6 +2383,21 @@ static RefPtr<TypeLayout> processEntryPointVaryingParameter(
23832383
else if (auto declRefType = as<DeclRefType>(type))
23842384
{
23852385
auto declRef = declRefType->getDeclRef();
2386+
2387+
// If we are trying to get the layout of some extern type, do our best
2388+
// to look it up in other loaded modules and generate the type layout
2389+
// based on that.
2390+
const auto isExtern = declRef.getDecl()->hasModifier<ExternAttribute>() ||
2391+
declRef.getDecl()->hasModifier<ExternModifier>();
2392+
if (isExtern)
2393+
{
2394+
if (const auto declDef = context->layoutContext.lookupExternDecl(declRef.getDecl()))
2395+
{
2396+
declRefType = declDef;
2397+
declRef = declRefType->getDeclRef();
2398+
}
2399+
}
2400+
23862401
if (auto structDeclRef = declRef.as<StructDecl>())
23872402
{
23882403
RefPtr<StructTypeLayout> structLayout = new StructTypeLayout();

source/slang/slang-type-layout.cpp

+69
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "../compiler-core/slang-artifact-desc-util.h"
55
#include "slang-check-impl.h"
66
#include "slang-ir-insts.h"
7+
#include "slang-mangle.h"
78
#include "slang-syntax.h"
89

910
#include <assert.h>
@@ -5694,4 +5695,72 @@ GlobalGenericParamDecl* GenericParamTypeLayout::getGlobalGenericParamDecl()
56945695
return rsDeclRef.getDecl();
56955696
}
56965697

5698+
DeclRefType* TypeLayoutContext::lookupExternDecl(Decl* decl)
5699+
{
5700+
if (!externTypeMap)
5701+
buildExternTypeMap();
5702+
DeclRefType* ret = nullptr;
5703+
const auto mangledName = getMangledName(targetReq->getLinkage()->getASTBuilder(), decl);
5704+
externTypeMap->tryGetValue(mangledName, ret);
5705+
return ret;
5706+
}
5707+
5708+
void TypeLayoutContext::buildExternTypeMap()
5709+
{
5710+
externTypeMap.emplace();
5711+
const auto linkage = targetReq->getLinkage();
5712+
auto astBuilder = linkage->getASTBuilder();
5713+
5714+
HashSet<String> externNames;
5715+
Dictionary<String, DeclRefType*> allTypes;
5716+
5717+
// Traverse the AST and keep track of all extern names and all type definitions
5718+
// We'll match them up later
5719+
auto processDecl = [&](auto&& go, Decl* decl) -> void
5720+
{
5721+
const auto isExtern =
5722+
decl->hasModifier<ExternAttribute>() || decl->hasModifier<ExternModifier>();
5723+
5724+
if (auto declRefType = as<DeclRefType>(DeclRefType::create(astBuilder, decl)))
5725+
{
5726+
String mangledName = getMangledName(astBuilder, decl);
5727+
5728+
if (isExtern)
5729+
{
5730+
externNames.add(mangledName);
5731+
}
5732+
else
5733+
{
5734+
allTypes[mangledName] = declRefType;
5735+
}
5736+
}
5737+
5738+
if (auto scopeDecl = as<ScopeDecl>(decl))
5739+
{
5740+
for (auto member : scopeDecl->members)
5741+
{
5742+
go(go, member);
5743+
}
5744+
}
5745+
};
5746+
5747+
for (const auto& m : linkage->loadedModulesList)
5748+
{
5749+
const auto& ast = m->getModuleDecl();
5750+
for (auto member : ast->members)
5751+
{
5752+
processDecl(processDecl, member);
5753+
}
5754+
}
5755+
5756+
// Only keep the types that have matching extern declarations
5757+
for (const auto& externName : externNames)
5758+
{
5759+
if (allTypes.containsKey(externName))
5760+
{
5761+
externTypeMap.value()[externName] = allTypes[externName];
5762+
}
5763+
}
5764+
}
5765+
56975766
} // namespace Slang

source/slang/slang-type-layout.h

+7
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,13 @@ struct TypeLayoutContext
11831183
// Options passed to object layout
11841184
ObjectLayoutRulesImpl::Options objectLayoutOptions;
11851185

1186+
// Mangled names to DeclRefType, this is used to match up 'extern' types to
1187+
// their linked in definitions during layout generation
1188+
std::optional<Dictionary<String, DeclRefType*>> externTypeMap;
1189+
1190+
DeclRefType* lookupExternDecl(Decl *decl);
1191+
void buildExternTypeMap();
1192+
11861193
LayoutRulesImpl* getRules() { return rules; }
11871194
LayoutRulesFamilyImpl* getRulesFamily() const { return rules->getLayoutRulesFamily(); }
11881195

0 commit comments

Comments
 (0)