Skip to content

Commit b9de52b

Browse files
committed
Swift: Work around assertion failures in mangler
1 parent dd128fb commit b9de52b

File tree

6 files changed

+67
-14
lines changed

6 files changed

+67
-14
lines changed

swift/extractor/SwiftExtractor.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,19 @@ static std::unordered_set<swift::ModuleDecl*> extractDeclarations(
138138
state.sourceFiles.push_back(filename);
139139
}
140140

141+
// fprintf(stderr, "\nXXX %p\n", primaryFile);
142+
// module.dump();
143+
// if (auto x = module.findUnderlyingClangModule()) {
144+
// x->dump();
145+
// if (x->Name == "NSInvocation") {
146+
// llvm::SmallVector<swift::Decl*> topLevelDecls;
147+
// module.getTopLevelDecls(topLevelDecls);
148+
// for (auto y : topLevelDecls) {
149+
// y->dump();
150+
// }
151+
// }
152+
// }
153+
141154
// The extractor can be called several times from different processes with
142155
// the same input file(s). Using `TargetFile` the first process will win, and the following
143156
// will just skip the work
@@ -170,9 +183,6 @@ static std::unordered_set<swift::ModuleDecl*> extractDeclarations(
170183
bodyEmissionStrategy);
171184
auto topLevelDecls = getTopLevelDecls(module, primaryFile, lazyDeclaration);
172185
for (auto decl : topLevelDecls) {
173-
if (decl->isUnavailable()) {
174-
continue;
175-
}
176186
visitor.extract(decl);
177187
}
178188
for (auto& comment : comments) {

swift/extractor/infra/SwiftBodyEmissionStrategy.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ using namespace codeql;
1212
// same module one by one. In this mode, we restrict emission only to the same file ignoring
1313
// all the other files.
1414
bool SwiftBodyEmissionStrategy::shouldEmitDeclBody(const swift::Decl& decl) {
15-
auto module = decl.getModuleContext();
16-
if (module != &currentModule) {
15+
if (!currentTopLevelDecls.contains(&decl) && decl.getModuleContext() != &currentModule) {
1716
return false;
1817
}
1918
if (currentLazyDeclaration && currentLazyDeclaration != &decl) {

swift/extractor/infra/SwiftBodyEmissionStrategy.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,19 @@ class SwiftBodyEmissionStrategy {
1212
const swift::Decl* currentLazyDeclaration)
1313
: currentModule(currentModule),
1414
currentPrimarySourceFile(currentPrimarySourceFile),
15-
currentLazyDeclaration(currentLazyDeclaration) {}
15+
currentLazyDeclaration(currentLazyDeclaration) {
16+
llvm::SmallVector<swift::Decl*> decls;
17+
currentModule.getTopLevelDecls(decls);
18+
currentTopLevelDecls.insert(decls.begin(), decls.end());
19+
}
20+
1621
bool shouldEmitDeclBody(const swift::Decl& decl);
1722

1823
private:
1924
swift::ModuleDecl& currentModule;
2025
swift::SourceFile* currentPrimarySourceFile;
2126
const swift::Decl* currentLazyDeclaration;
27+
std::unordered_set<const swift::Decl*> currentTopLevelDecls;
2228
};
2329

2430
} // namespace codeql

swift/extractor/infra/SwiftDispatcher.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
#include "swift/extractor/config/SwiftExtractorState.h"
1717
#include "swift/logging/SwiftAssert.h"
1818

19+
#include <swift/AST/ASTContext.h>
20+
#include <swift/AST/GenericEnvironment.h>
21+
#include <swift/AST/GenericParamList.h>
22+
#include <swift/AST/ClangModuleLoader.h>
23+
#include <clang/Basic/Module.h>
24+
1925
namespace codeql {
2026

2127
// The main responsibilities of the SwiftDispatcher are as follows:

swift/extractor/mangler/SwiftMangler.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <swift/AST/ASTContext.h>
99
#include <swift/AST/GenericEnvironment.h>
1010
#include <swift/AST/GenericParamList.h>
11+
#include <swift/AST/ClangModuleLoader.h>
12+
#include <clang/Basic/Module.h>
1113

1214
using namespace codeql;
1315

@@ -38,6 +40,8 @@ std::string_view getTypeKindStr(const swift::TypeBase* type) {
3840

3941
} // namespace
4042

43+
std::unordered_map<const swift::Decl*, unsigned> SwiftMangler::preloadedExtensionIndexes;
44+
4145
SwiftMangledName SwiftMangler::initMangled(const swift::TypeBase* type) {
4246
return {getTypeKindStr(type), '_'};
4347
}
@@ -109,32 +113,58 @@ unsigned SwiftMangler::getExtensionIndex(const swift::ExtensionDecl* decl,
109113
// indexes once for each encountered parent into the `preloadedExtensionIndexes` mapping.
110114
// Because we mangle declarations only once in a given trap/dispatcher context, we can safely
111115
// 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;
114119
}
115120
if (auto parentModule = llvm::dyn_cast<swift::ModuleDecl>(parent)) {
116121
llvm::SmallVector<swift::Decl*> siblings;
117122
parentModule->getTopLevelDecls(siblings);
118123
indexExtensions(siblings);
124+
if (auto clangModule = parentModule->findUnderlyingClangModule()) {
125+
indexClangExtensions(clangModule, decl->getASTContext().getClangModuleLoader());
126+
}
119127
} else if (auto iterableParent = llvm::dyn_cast<swift::IterableDeclContext>(parent)) {
120128
indexExtensions(iterableParent->getAllMembers());
121129
} else {
122130
// TODO use a generic logging handle for Swift entities here, once it's available
123131
CODEQL_ASSERT(false, "non-local context must be module or iterable decl context");
124132
}
125-
auto found = preloadedExtensionIndexes.extract(decl);
133+
auto found = SwiftMangler::preloadedExtensionIndexes.find(decl);
126134
// 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;
129138
}
130139

131140
void SwiftMangler::indexExtensions(llvm::ArrayRef<swift::Decl*> siblings) {
132141
auto index = 0u;
133142
for (auto sibling : siblings) {
134143
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+
}
136167
}
137-
++index;
138168
}
139169
}
140170

swift/extractor/mangler/SwiftMangler.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,15 @@ class SwiftMangler : private swift::TypeVisitor<SwiftMangler, SwiftMangledName>,
106106
SwiftMangledName visitPackExpansionType(const swift::PackExpansionType* type);
107107

108108
private:
109-
std::unordered_map<const swift::Decl*, unsigned> preloadedExtensionIndexes;
109+
static std::unordered_map<const swift::Decl*, unsigned> preloadedExtensionIndexes;
110110

111111
virtual SwiftMangledName fetch(const swift::Decl* decl) = 0;
112112
virtual SwiftMangledName fetch(const swift::TypeBase* type) = 0;
113113
SwiftMangledName fetch(swift::Type type) { return fetch(type.getPointer()); }
114114

115115
void indexExtensions(llvm::ArrayRef<swift::Decl*> siblings);
116+
void indexClangExtensions(const clang::Module* clangModule,
117+
swift::ClangModuleLoader* moduleLoader);
116118
unsigned int getExtensionIndex(const swift::ExtensionDecl* decl, const swift::Decl* parent);
117119
static SwiftMangledName initMangled(const swift::TypeBase* type);
118120
SwiftMangledName initMangled(const swift::Decl* decl);

0 commit comments

Comments
 (0)