22
33using namespace codeql ;
44
5+ #include < swift/AST/ASTContext.h>
6+ #include < swift/AST/ClangModuleLoader.h>
7+ #include < clang/Basic/Module.h>
8+
9+ namespace {
10+ const swift::ModuleDecl* getRealModuleOf (const swift::Decl* decl) {
11+ auto * swiftModule = decl->getModuleContext ();
12+ auto * clangModule = swiftModule->findUnderlyingClangModule ();
13+
14+ if (!clangModule) {
15+ return swiftModule;
16+ }
17+
18+ auto * clangModuleLoader = decl->getASTContext ().getClangModuleLoader ();
19+
20+ if (!clangModuleLoader) {
21+ return swiftModule;
22+ }
23+
24+ static std::unordered_map<const swift::Decl*, const swift::ModuleDecl*> cache;
25+
26+ if (auto result = cache.find (decl); result != cache.end ()) {
27+ return result->second ;
28+ }
29+
30+ for (const auto & submodule : clangModule->submodules ()) {
31+ if (auto * swiftSubmodule = clangModuleLoader->getWrapperForModule (submodule)) {
32+ llvm::SmallVector<swift::Decl*> children;
33+ swiftSubmodule->getTopLevelDecls (children);
34+ for (const auto child : children) {
35+ cache[child] = swiftSubmodule;
36+ }
37+ }
38+ }
39+
40+ if (auto result = cache.find (decl); result != cache.end ()) {
41+ return result->second ;
42+ } else {
43+ return swiftModule;
44+ }
45+ }
46+ } // namespace
47+
548// In order to not emit duplicated entries for declarations, we restrict emission to only
649// Decls declared within the current "scope".
750// Depending on the whether we are extracting a primary source file or not the scope is defined as
@@ -12,7 +55,7 @@ using namespace codeql;
1255// same module one by one. In this mode, we restrict emission only to the same file ignoring
1356// all the other files.
1457bool SwiftBodyEmissionStrategy::shouldEmitDeclBody (const swift::Decl& decl) {
15- auto module = decl. getModuleContext ( );
58+ auto module = getRealModuleOf (&decl );
1659 if (module != ¤tModule) {
1760 return false ;
1861 }
0 commit comments