|
8 | 8 | #include <swift/AST/ASTContext.h>
|
9 | 9 | #include <swift/AST/GenericEnvironment.h>
|
10 | 10 | #include <swift/AST/GenericParamList.h>
|
| 11 | +#include <swift/AST/ClangModuleLoader.h> |
| 12 | +#include <clang/Basic/Module.h> |
11 | 13 |
|
12 | 14 | using namespace codeql;
|
13 | 15 |
|
@@ -38,6 +40,8 @@ std::string_view getTypeKindStr(const swift::TypeBase* type) {
|
38 | 40 |
|
39 | 41 | } // namespace
|
40 | 42 |
|
| 43 | +std::unordered_map<const swift::Decl*, unsigned> SwiftMangler::preloadedExtensionIndexes; |
| 44 | + |
41 | 45 | SwiftMangledName SwiftMangler::initMangled(const swift::TypeBase* type) {
|
42 | 46 | return {getTypeKindStr(type), '_'};
|
43 | 47 | }
|
@@ -109,32 +113,58 @@ unsigned SwiftMangler::getExtensionIndex(const swift::ExtensionDecl* decl,
|
109 | 113 | // indexes once for each encountered parent into the `preloadedExtensionIndexes` mapping.
|
110 | 114 | // Because we mangle declarations only once in a given trap/dispatcher context, we can safely
|
111 | 115 | // discard preloaded indexes on use
|
112 |
| - if (auto found = preloadedExtensionIndexes.extract(decl)) { |
113 |
| - return found.mapped(); |
| 116 | + if (auto found = SwiftMangler::preloadedExtensionIndexes.find(decl); |
| 117 | + found != SwiftMangler::preloadedExtensionIndexes.end()) { |
| 118 | + return found->second; |
114 | 119 | }
|
115 | 120 | if (auto parentModule = llvm::dyn_cast<swift::ModuleDecl>(parent)) {
|
116 | 121 | llvm::SmallVector<swift::Decl*> siblings;
|
117 | 122 | parentModule->getTopLevelDecls(siblings);
|
118 | 123 | indexExtensions(siblings);
|
| 124 | + if (auto clangModule = parentModule->findUnderlyingClangModule()) { |
| 125 | + indexClangExtensions(clangModule, decl->getASTContext().getClangModuleLoader()); |
| 126 | + } |
119 | 127 | } else if (auto iterableParent = llvm::dyn_cast<swift::IterableDeclContext>(parent)) {
|
120 | 128 | indexExtensions(iterableParent->getAllMembers());
|
121 | 129 | } else {
|
122 | 130 | // TODO use a generic logging handle for Swift entities here, once it's available
|
123 | 131 | CODEQL_ASSERT(false, "non-local context must be module or iterable decl context");
|
124 | 132 | }
|
125 |
| - auto found = preloadedExtensionIndexes.extract(decl); |
| 133 | + auto found = SwiftMangler::preloadedExtensionIndexes.find(decl); |
126 | 134 | // TODO use a generic logging handle for Swift entities here, once it's available
|
127 |
| - CODEQL_ASSERT(found, "extension not found within parent"); |
128 |
| - return found.mapped(); |
| 135 | + CODEQL_ASSERT(found != SwiftMangler::preloadedExtensionIndexes.end(), |
| 136 | + "extension not found within parent"); |
| 137 | + return found->second; |
129 | 138 | }
|
130 | 139 |
|
131 | 140 | void SwiftMangler::indexExtensions(llvm::ArrayRef<swift::Decl*> siblings) {
|
132 | 141 | auto index = 0u;
|
133 | 142 | for (auto sibling : siblings) {
|
134 | 143 | if (sibling->getKind() == swift::DeclKind::Extension) {
|
135 |
| - preloadedExtensionIndexes.emplace(sibling, index); |
| 144 | + SwiftMangler::preloadedExtensionIndexes.emplace(sibling, index); |
| 145 | + index += 2; |
| 146 | + } |
| 147 | + } |
| 148 | +} |
| 149 | + |
| 150 | +void SwiftMangler::indexClangExtensions(const clang::Module* clangModule, |
| 151 | + swift::ClangModuleLoader* moduleLoader) { |
| 152 | + if (!moduleLoader) { |
| 153 | + return; |
| 154 | + } |
| 155 | + |
| 156 | + auto index = 1u; |
| 157 | + for (const auto& submodule : clangModule->submodules()) { |
| 158 | + if (auto* swiftSubmodule = moduleLoader->getWrapperForModule(submodule)) { |
| 159 | + llvm::SmallVector<swift::Decl*> children; |
| 160 | + swiftSubmodule->getTopLevelDecls(children); |
| 161 | + for (const auto child : children) { |
| 162 | + if (child->getKind() == swift::DeclKind::Extension) { |
| 163 | + SwiftMangler::preloadedExtensionIndexes.emplace(child, index); |
| 164 | + index += 2; |
| 165 | + } |
| 166 | + } |
136 | 167 | }
|
137 |
| - ++index; |
138 | 168 | }
|
139 | 169 | }
|
140 | 170 |
|
|
0 commit comments