66#include < sstream>
77#include < memory>
88#include < unistd.h>
9+ #include < unordered_set>
910
1011#include < swift/AST/SourceFile.h>
12+ #include < swift/Basic/FileTypes.h>
1113#include < llvm/ADT/SmallString.h>
1214#include < llvm/Support/FileSystem.h>
1315#include < llvm/Support/Path.h>
@@ -124,6 +126,17 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config,
124126
125127void codeql::extractSwiftFiles (const SwiftExtractorConfiguration& config,
126128 swift::CompilerInstance& compiler) {
129+ // The frontend can be called in many different ways.
130+ // At each invocation we only extract system and builtin modules and any input source files that
131+ // have an output associated with them.
132+ std::unordered_set<std::string> sourceFiles;
133+ auto inputFiles = compiler.getInvocation ().getFrontendOptions ().InputsAndOutputs .getAllInputs ();
134+ for (auto & input : inputFiles) {
135+ if (input.getType () == swift::file_types::TY_Swift && !input.outputFilename ().empty ()) {
136+ sourceFiles.insert (input.getFileName ());
137+ }
138+ }
139+
127140 for (auto & [_, module ] : compiler.getASTContext ().getLoadedModules ()) {
128141 // We only extract system and builtin modules here as the other "user" modules can be built
129142 // during the build process and then re-used at a later stage. In this case, we extract the
@@ -135,12 +148,16 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config,
135148 // TODO: pass ModuleDecl directly when we have module extraction in place?
136149 extractDeclarations (config, decls, compiler, *module );
137150 } else {
138- // The extraction will only work if one (or more) `-primary-file` CLI option is provided,
139- // which is what always happens in case of `swift build` and `xcodebuild`
140- for (auto primaryFile : module ->getPrimarySourceFiles ()) {
141- archiveFile (config, *primaryFile);
142- extractDeclarations (config, primaryFile->getTopLevelDecls (), compiler, *module ,
143- primaryFile);
151+ for (auto file : module ->getFiles ()) {
152+ if (!llvm::isa<swift::SourceFile>(file)) {
153+ continue ;
154+ }
155+ auto sourceFile = llvm::cast<swift::SourceFile>(file);
156+ if (sourceFiles.count (sourceFile->getFilename ().str ()) == 0 ) {
157+ continue ;
158+ }
159+ archiveFile (config, *sourceFile);
160+ extractDeclarations (config, sourceFile->getTopLevelDecls (), compiler, *module , sourceFile);
144161 }
145162 }
146163 }
0 commit comments