|
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>
|
@@ -5694,4 +5695,72 @@ GlobalGenericParamDecl* GenericParamTypeLayout::getGlobalGenericParamDecl()
|
5694 | 5695 | return rsDeclRef.getDecl();
|
5695 | 5696 | }
|
5696 | 5697 |
|
| 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 | + |
5697 | 5766 | } // namespace Slang
|
0 commit comments