Skip to content

Commit c0bc8ec

Browse files
authored
Merge pull request swiftlang#33522 from nkcsgexi/67269210
Frontend: add a new action -scan-clang-dependencies to scan a PCM's dependencies
2 parents 315df90 + 9988911 commit c0bc8ec

File tree

8 files changed

+99
-1
lines changed

8 files changed

+99
-1
lines changed

include/swift/Frontend/FrontendOptions.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ class FrontendOptions {
133133
EmitPCM, ///< Emit precompiled Clang module from a module map
134134
DumpPCM, ///< Dump information about a precompiled Clang module
135135

136-
ScanDependencies, ///< Scan dependencies of Swift source files
136+
ScanDependencies, ///< Scan dependencies of Swift source files
137+
ScanClangDependencies, ///< Scan dependencies of a Clang module
137138
PrintVersion, ///< Print version information.
138139
};
139140

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,10 @@ def scan_dependencies : Flag<["-"], "scan-dependencies">,
10941094
HelpText<"Scan dependencies of the given Swift sources">, ModeOpt,
10951095
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>;
10961096

1097+
def scan_clang_dependencies : Flag<["-"], "scan-clang-dependencies">,
1098+
HelpText<"Scan dependencies of the given Clang module">, ModeOpt,
1099+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>;
1100+
10971101
def enable_astscope_lookup : Flag<["-"], "enable-astscope-lookup">,
10981102
Flags<[FrontendOption]>,
10991103
HelpText<"Enable ASTScope-based unqualified name lookup">;

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,8 @@ ArgsToFrontendOptionsConverter::determineRequestedAction(const ArgList &args) {
354354
return FrontendOptions::ActionType::EmitImportedModules;
355355
if (Opt.matches(OPT_scan_dependencies))
356356
return FrontendOptions::ActionType::ScanDependencies;
357+
if (Opt.matches(OPT_scan_clang_dependencies))
358+
return FrontendOptions::ActionType::ScanClangDependencies;
357359
if (Opt.matches(OPT_parse))
358360
return FrontendOptions::ActionType::Parse;
359361
if (Opt.matches(OPT_resolve_imports))

lib/Frontend/FrontendOptions.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ bool FrontendOptions::needsProperModuleName(ActionType action) {
6464
case ActionType::DumpTypeInfo:
6565
case ActionType::EmitPCM:
6666
case ActionType::ScanDependencies:
67+
case ActionType::ScanClangDependencies:
6768
return true;
6869
}
6970
llvm_unreachable("Unknown ActionType");
@@ -77,6 +78,7 @@ bool FrontendOptions::shouldActionOnlyParse(ActionType action) {
7778
case FrontendOptions::ActionType::DumpInterfaceHash:
7879
case FrontendOptions::ActionType::EmitImportedModules:
7980
case FrontendOptions::ActionType::ScanDependencies:
81+
case FrontendOptions::ActionType::ScanClangDependencies:
8082
case FrontendOptions::ActionType::PrintVersion:
8183
return true;
8284
default:
@@ -174,6 +176,7 @@ FrontendOptions::formatForPrincipalOutputFileForAction(ActionType action) {
174176
return TY_ClangModuleFile;
175177

176178
case ActionType::ScanDependencies:
179+
case ActionType::ScanClangDependencies:
177180
return TY_JSONDependencies;
178181
}
179182
llvm_unreachable("unhandled action");
@@ -213,6 +216,7 @@ bool FrontendOptions::canActionEmitDependencies(ActionType action) {
213216
case ActionType::EmitImportedModules:
214217
case ActionType::EmitPCM:
215218
case ActionType::ScanDependencies:
219+
case ActionType::ScanClangDependencies:
216220
return true;
217221
}
218222
llvm_unreachable("unhandled action");
@@ -237,6 +241,7 @@ bool FrontendOptions::canActionEmitReferenceDependencies(ActionType action) {
237241
case ActionType::EmitPCM:
238242
case ActionType::DumpPCM:
239243
case ActionType::ScanDependencies:
244+
case ActionType::ScanClangDependencies:
240245
case ActionType::PrintVersion:
241246
return false;
242247
case ActionType::Typecheck:
@@ -285,6 +290,7 @@ bool FrontendOptions::canActionEmitObjCHeader(ActionType action) {
285290
case ActionType::EmitPCM:
286291
case ActionType::DumpPCM:
287292
case ActionType::ScanDependencies:
293+
case ActionType::ScanClangDependencies:
288294
case ActionType::PrintVersion:
289295
return false;
290296
case ActionType::Typecheck:
@@ -322,6 +328,7 @@ bool FrontendOptions::canActionEmitLoadedModuleTrace(ActionType action) {
322328
case ActionType::EmitPCM:
323329
case ActionType::DumpPCM:
324330
case ActionType::ScanDependencies:
331+
case ActionType::ScanClangDependencies:
325332
case ActionType::PrintVersion:
326333
return false;
327334
case ActionType::ResolveImports:
@@ -365,6 +372,7 @@ bool FrontendOptions::canActionEmitModule(ActionType action) {
365372
case ActionType::EmitPCM:
366373
case ActionType::DumpPCM:
367374
case ActionType::ScanDependencies:
375+
case ActionType::ScanClangDependencies:
368376
case ActionType::PrintVersion:
369377
return false;
370378
case ActionType::MergeModules:
@@ -409,6 +417,7 @@ bool FrontendOptions::canActionEmitInterface(ActionType action) {
409417
case ActionType::EmitPCM:
410418
case ActionType::DumpPCM:
411419
case ActionType::ScanDependencies:
420+
case ActionType::ScanClangDependencies:
412421
return false;
413422
case ActionType::Typecheck:
414423
case ActionType::MergeModules:
@@ -454,6 +463,7 @@ bool FrontendOptions::doesActionProduceOutput(ActionType action) {
454463
case ActionType::EmitPCM:
455464
case ActionType::DumpPCM:
456465
case ActionType::ScanDependencies:
466+
case ActionType::ScanClangDependencies:
457467
return true;
458468

459469
case ActionType::NoneAction:
@@ -499,6 +509,7 @@ bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) {
499509
case ActionType::DumpTypeInfo:
500510
case ActionType::DumpPCM:
501511
case ActionType::ScanDependencies:
512+
case ActionType::ScanClangDependencies:
502513
case ActionType::PrintVersion:
503514
return true;
504515
}
@@ -524,6 +535,7 @@ bool FrontendOptions::doesActionGenerateSIL(ActionType action) {
524535
case ActionType::EmitPCM:
525536
case ActionType::DumpPCM:
526537
case ActionType::ScanDependencies:
538+
case ActionType::ScanClangDependencies:
527539
case ActionType::PrintVersion:
528540
return false;
529541
case ActionType::EmitSILGen:
@@ -570,6 +582,7 @@ bool FrontendOptions::doesActionGenerateIR(ActionType action) {
570582
case ActionType::EmitPCM:
571583
case ActionType::DumpPCM:
572584
case ActionType::ScanDependencies:
585+
case ActionType::ScanClangDependencies:
573586
case ActionType::PrintVersion:
574587
return false;
575588
case ActionType::Immediate:

lib/FrontendTool/FrontendTool.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,9 @@ static bool performCompile(CompilerInstance &Instance,
18361836
if (Action == FrontendOptions::ActionType::ScanDependencies)
18371837
return finishPipeline(scanDependencies(Instance));
18381838

1839+
if (Action == FrontendOptions::ActionType::ScanClangDependencies)
1840+
return finishPipeline(scanClangDependencies(Instance));
1841+
18391842
if (observer)
18401843
observer->performedSemanticAnalysis(Instance);
18411844

lib/FrontendTool/ScanDependencies.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,56 @@ static bool diagnoseCycle(CompilerInstance &instance,
533533
return false;
534534
}
535535

536+
bool swift::scanClangDependencies(CompilerInstance &instance) {
537+
ASTContext &ctx = instance.getASTContext();
538+
ModuleDecl *mainModule = instance.getMainModule();
539+
auto &FEOpts = instance.getInvocation().getFrontendOptions();
540+
ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
541+
auto ModuleCachePath = getModuleCachePathFromClang(ctx
542+
.getClangModuleLoader()->getClangInstance());
543+
544+
StringRef mainModuleName = mainModule->getNameStr();
545+
llvm::SetVector<ModuleDependencyID, std::vector<ModuleDependencyID>,
546+
std::set<ModuleDependencyID>> allModules;
547+
// Create the module dependency cache.
548+
ModuleDependenciesCache cache;
549+
InterfaceSubContextDelegateImpl ASTDelegate(ctx.SourceMgr, ctx.Diags,
550+
ctx.SearchPathOpts, ctx.LangOpts,
551+
LoaderOpts,
552+
ctx.getClangModuleLoader(),
553+
/*buildModuleCacheDirIfAbsent*/false,
554+
ModuleCachePath,
555+
FEOpts.PrebuiltModuleCachePath,
556+
FEOpts.SerializeModuleInterfaceDependencyHashes,
557+
FEOpts.shouldTrackSystemDependencies());
558+
// Loading the clang module using Clang importer.
559+
// This action will populate the cache with the main module's dependencies.
560+
auto rootDeps = static_cast<ClangImporter*>(ctx.getClangModuleLoader())
561+
->getModuleDependencies(mainModuleName, cache, ASTDelegate);
562+
if (!rootDeps.hasValue()) {
563+
// We cannot find the clang module, abort.
564+
return true;
565+
}
566+
// Add the main module.
567+
allModules.insert({mainModuleName.str(), ModuleDependenciesKind::Clang});
568+
569+
// Explore the dependencies of every module.
570+
for (unsigned currentModuleIdx = 0;
571+
currentModuleIdx < allModules.size();
572+
++currentModuleIdx) {
573+
auto module = allModules[currentModuleIdx];
574+
auto discoveredModules =
575+
resolveDirectDependencies(instance, module, cache, ASTDelegate);
576+
allModules.insert(discoveredModules.begin(), discoveredModules.end());
577+
}
578+
// Write out the JSON description.
579+
std::string path = FEOpts.InputsAndOutputs.getSingleOutputFilename();
580+
std::error_code EC;
581+
llvm::raw_fd_ostream out(path, EC, llvm::sys::fs::F_None);
582+
writeJSON(out, instance, cache, ASTDelegate, allModules.getArrayRef());
583+
return false;
584+
}
585+
536586
bool swift::scanDependencies(CompilerInstance &instance) {
537587
ASTContext &Context = instance.getASTContext();
538588
ModuleDecl *mainModule = instance.getMainModule();

lib/FrontendTool/ScanDependencies.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ class CompilerInstance;
2020
/// Scans the dependencies of the main module of \c instance.
2121
bool scanDependencies(CompilerInstance &instance);
2222

23+
/// Scans the dependencies of the underlying clang module of the main module
24+
/// of \c instance.
25+
bool scanClangDependencies(CompilerInstance &instance);
26+
2327
} // end namespace swift
2428

2529
#endif
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: mkdir -p %t/clang-module-cache
3+
// RUN: %target-swift-frontend -scan-clang-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -disable-implicit-swift-modules -Xcc -Xclang -Xcc -fno-implicit-modules -module-name C
4+
5+
// Check the contents of the JSON output
6+
// RUN: %FileCheck %s < %t/deps.json
7+
8+
// CHECK: "mainModuleName": "C",
9+
// CHECK-NEXT: "modules": [
10+
// CHECK-NEXT: {
11+
// CHECK-NEXT: "clang": "C"
12+
// CHECK-NEXT: },
13+
// CHECK-NEXT: {
14+
// CHECK-NEXT: "modulePath": "C.pcm",
15+
// CHECK-NEXT: "sourceFiles": [
16+
17+
18+
// CHECK: "directDependencies": [
19+
// CHECK-NEXT: {
20+
// CHECK-NEXT: "clang": "B"
21+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)