|
4 | 4 | #include "../compiler-core/slang-artifact-desc-util.h"
|
5 | 5 | #include "slang-check-impl.h"
|
6 | 6 | #include "slang-ir-insts.h"
|
| 7 | +#include "slang-mangle.h" |
7 | 8 | #include "slang-syntax.h"
|
8 | 9 |
|
9 | 10 | #include <assert.h>
|
@@ -5015,6 +5016,20 @@ static TypeLayoutResult _createTypeLayout(TypeLayoutContext& context, Type* type
|
5015 | 5016 | {
|
5016 | 5017 | auto declRef = declRefType->getDeclRef();
|
5017 | 5018 |
|
| 5019 | + // If we are trying to get the layout of some extern type, do our best |
| 5020 | + // to look it up in other loaded modules and generate the type layout |
| 5021 | + // based on that. |
| 5022 | + const auto isExtern = declRef.getDecl()->hasModifier<ExternAttribute>() || |
| 5023 | + declRef.getDecl()->hasModifier<ExternModifier>(); |
| 5024 | + if (isExtern) |
| 5025 | + { |
| 5026 | + if (const auto declDef = context.lookupExternDecl(declRef.getDecl())) |
| 5027 | + { |
| 5028 | + declRefType = declDef; |
| 5029 | + declRef = declRefType->getDeclRef(); |
| 5030 | + } |
| 5031 | + } |
| 5032 | + |
5018 | 5033 | if (auto structDeclRef = declRef.as<StructDecl>())
|
5019 | 5034 | {
|
5020 | 5035 | StructTypeLayoutBuilder typeLayoutBuilder;
|
@@ -5694,4 +5709,71 @@ GlobalGenericParamDecl* GenericParamTypeLayout::getGlobalGenericParamDecl()
|
5694 | 5709 | return rsDeclRef.getDecl();
|
5695 | 5710 | }
|
5696 | 5711 |
|
| 5712 | +DeclRefType* TypeLayoutContext::lookupExternDecl(Decl* decl) |
| 5713 | +{ |
| 5714 | + if (!externTypeMap) |
| 5715 | + buildExternTypeMap(); |
| 5716 | + DeclRefType* ret = nullptr; |
| 5717 | + const auto mangledName = getMangledName(targetReq->getLinkage()->getASTBuilder(), decl); |
| 5718 | + externTypeMap->tryGetValue(mangledName, ret); |
| 5719 | + return ret; |
| 5720 | +} |
| 5721 | + |
| 5722 | +void TypeLayoutContext::buildExternTypeMap() |
| 5723 | +{ |
| 5724 | + externTypeMap.emplace(); |
| 5725 | + const auto linkage = targetReq->getLinkage(); |
| 5726 | + |
| 5727 | + HashSet<String> externNames; |
| 5728 | + Dictionary<String, DeclRefType*> allTypes; |
| 5729 | + |
| 5730 | + // Traverse the AST and keep track of all extern names and all type definitions |
| 5731 | + // We'll match them up later |
| 5732 | + auto processDecl = [&](auto&& go, Decl* decl) -> void |
| 5733 | + { |
| 5734 | + const auto isExtern = |
| 5735 | + decl->hasModifier<ExternAttribute>() || decl->hasModifier<ExternModifier>(); |
| 5736 | + |
| 5737 | + if (auto declRefType = as<DeclRefType>(DeclRefType::create(astBuilder, decl))) |
| 5738 | + { |
| 5739 | + String mangledName = getMangledName(astBuilder, decl); |
| 5740 | + |
| 5741 | + if (isExtern) |
| 5742 | + { |
| 5743 | + externNames.add(mangledName); |
| 5744 | + } |
| 5745 | + else |
| 5746 | + { |
| 5747 | + allTypes[mangledName] = declRefType; |
| 5748 | + } |
| 5749 | + } |
| 5750 | + |
| 5751 | + if (auto scopeDecl = as<ScopeDecl>(decl)) |
| 5752 | + { |
| 5753 | + for (auto member : scopeDecl->members) |
| 5754 | + { |
| 5755 | + go(go, member); |
| 5756 | + } |
| 5757 | + } |
| 5758 | + }; |
| 5759 | + |
| 5760 | + for (const auto& m : linkage->loadedModulesList) |
| 5761 | + { |
| 5762 | + const auto& ast = m->getModuleDecl(); |
| 5763 | + for (auto member : ast->members) |
| 5764 | + { |
| 5765 | + processDecl(processDecl, member); |
| 5766 | + } |
| 5767 | + } |
| 5768 | + |
| 5769 | + // Only keep the types that have matching extern declarations |
| 5770 | + for (const auto& externName : externNames) |
| 5771 | + { |
| 5772 | + if (allTypes.containsKey(externName)) |
| 5773 | + { |
| 5774 | + externTypeMap.value()[externName] = allTypes[externName]; |
| 5775 | + } |
| 5776 | + } |
| 5777 | +} |
| 5778 | + |
5697 | 5779 | } // namespace Slang
|
0 commit comments