2
2
3
3
using namespace codeql ;
4
4
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
+
5
48
// In order to not emit duplicated entries for declarations, we restrict emission to only
6
49
// Decls declared within the current "scope".
7
50
// 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;
12
55
// same module one by one. In this mode, we restrict emission only to the same file ignoring
13
56
// all the other files.
14
57
bool SwiftBodyEmissionStrategy::shouldEmitDeclBody (const swift::Decl& decl) {
15
- auto module = decl. getModuleContext ( );
58
+ auto module = getRealModuleOf (&decl );
16
59
if (module != ¤tModule) {
17
60
return false ;
18
61
}
0 commit comments