diff --git a/include/swift/Basic/FileTypes.def b/include/swift/Basic/FileTypes.def index 158c891df3103..071365f224bb7 100644 --- a/include/swift/Basic/FileTypes.def +++ b/include/swift/Basic/FileTypes.def @@ -83,6 +83,8 @@ TYPE("index-unit-output-path", IndexUnitOutputPath, "", "") TYPE("yaml-opt-record", YAMLOptRecord, "opt.yaml", "") TYPE("bitstream-opt-record",BitstreamOptRecord, "opt.bitstream", "") +TYPE("symbol-graph-output-path", SymbolGraphOutputPath, "", "") + // Overlay files declare wrapper modules, called "separately-imported overlays", // that should be automatically imported when a particular module is imported. // Cross-import directories conditionalize overlay files so they only take diff --git a/include/swift/Basic/SupplementaryOutputPaths.h b/include/swift/Basic/SupplementaryOutputPaths.h index e72f0ecb02b10..7e19f80a01a7c 100644 --- a/include/swift/Basic/SupplementaryOutputPaths.h +++ b/include/swift/Basic/SupplementaryOutputPaths.h @@ -152,6 +152,9 @@ struct SupplementaryOutputPaths { /// The path to which we should emit module summary file. std::string ModuleSummaryOutputPath; + + /// The directory to which we should emit symbol graphs for the current module. + std::string SymbolGraphOutputDir; SupplementaryOutputPaths() = default; SupplementaryOutputPaths(const SupplementaryOutputPaths &) = default; @@ -186,6 +189,8 @@ struct SupplementaryOutputPaths { fn(LdAddCFilePath); if (!ModuleSummaryOutputPath.empty()) fn(ModuleSummaryOutputPath); + if (!SymbolGraphOutputDir.empty()) + fn(SymbolGraphOutputDir); } bool empty() const { @@ -194,7 +199,8 @@ struct SupplementaryOutputPaths { ReferenceDependenciesFilePath.empty() && SerializedDiagnosticsPath.empty() && LoadedModuleTracePath.empty() && TBDPath.empty() && ModuleInterfaceOutputPath.empty() && - ModuleSourceInfoOutputPath.empty() && LdAddCFilePath.empty(); + ModuleSourceInfoOutputPath.empty() && LdAddCFilePath.empty() && + SymbolGraphOutputDir.empty(); } }; } // namespace swift diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h index 8e0849ebbcd56..5d49fb71e2e36 100644 --- a/include/swift/Driver/Driver.h +++ b/include/swift/Driver/Driver.h @@ -416,6 +416,11 @@ class Driver { const TypeToPathMap *OutputMap, StringRef workingDirectory, CommandOutput *Output) const; + + void chooseSymbolGraphOutputPath(Compilation &C, + const TypeToPathMap *OutputMap, + StringRef workingDirectory, + CommandOutput *Output) const; void chooseLoadedModuleTracePath(Compilation &C, StringRef workingDirectory, diff --git a/lib/Basic/FileTypes.cpp b/lib/Basic/FileTypes.cpp index 3d6151940a832..5930f063e4a69 100644 --- a/lib/Basic/FileTypes.cpp +++ b/lib/Basic/FileTypes.cpp @@ -106,6 +106,7 @@ bool file_types::isTextual(ID Id) { case file_types::TY_IndexData: case file_types::TY_BitstreamOptRecord: case file_types::TY_IndexUnitOutputPath: + case file_types::TY_SymbolGraphOutputPath: return false; case file_types::TY_INVALID: llvm_unreachable("Invalid type ID."); @@ -157,6 +158,7 @@ bool file_types::isAfterLLVM(ID Id) { case file_types::TY_JSONDependencies: case file_types::TY_JSONFeatures: case file_types::TY_IndexUnitOutputPath: + case file_types::TY_SymbolGraphOutputPath: return false; case file_types::TY_INVALID: llvm_unreachable("Invalid type ID."); @@ -208,6 +210,7 @@ bool file_types::isPartOfSwiftCompilation(ID Id) { case file_types::TY_JSONDependencies: case file_types::TY_JSONFeatures: case file_types::TY_IndexUnitOutputPath: + case file_types::TY_SymbolGraphOutputPath: return false; case file_types::TY_INVALID: llvm_unreachable("Invalid type ID."); diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index f8d8bd6d709e2..950862fccbbd4 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -2044,6 +2044,7 @@ void Driver::buildActions(SmallVectorImpl &TopLevelActions, case file_types::TY_RawSIL: case file_types::TY_Nothing: case file_types::TY_IndexUnitOutputPath: + case file_types::TY_SymbolGraphOutputPath: case file_types::TY_INVALID: llvm_unreachable("these types should never be inferred"); } @@ -2943,6 +2944,9 @@ Job *Driver::buildJobsForAction(Compilation &C, const JobAction *JA, options::OPT_emit_objc_header_path)) chooseObjectiveCHeaderOutputPath(C, OutputMap, workingDirectory, Output.get()); + + if (C.getArgs().hasArg(options::OPT_emit_symbol_graph)) + chooseSymbolGraphOutputPath(C, OutputMap, workingDirectory, Output.get()); // 4. Construct a Job which produces the right CommandOutput. std::unique_ptr ownedJob = TC.constructJob(*JA, C, std::move(InputJobs), @@ -3413,6 +3417,31 @@ void Driver::chooseOptimizationRecordPath(Compilation &C, Diags.diagnose({}, diag::warn_opt_remark_disabled); } +void Driver::chooseSymbolGraphOutputPath(Compilation &C, + const TypeToPathMap *OutputMap, + StringRef workingDirectory, + CommandOutput *Output) const { + StringRef optionOutput = C.getArgs().getLastArgValue(options::OPT_emit_symbol_graph_dir); + if (hasExistingAdditionalOutput(*Output, file_types::TY_SymbolGraphOutputPath, optionOutput)) { + return; + } + + StringRef SymbolGraphDir; + if (OutputMap) { + auto iter = OutputMap->find(file_types::TY_SymbolGraphOutputPath); + if (iter != OutputMap->end()) + SymbolGraphDir = iter->second; + } + + if (SymbolGraphDir.empty() && !optionOutput.empty()) { + SymbolGraphDir = optionOutput; + } + + if (!SymbolGraphDir.empty()) { + Output->setAdditionalOutputForType(file_types::TY_SymbolGraphOutputPath, SymbolGraphDir); + } +} + void Driver::chooseObjectiveCHeaderOutputPath(Compilation &C, const TypeToPathMap *OutputMap, StringRef workingDirectory, diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 34b3756aaedbb..1775a7f66d829 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -574,11 +574,6 @@ ToolChain::constructInvocation(const CompileJobAction &job, options:: OPT_disable_autolinking_runtime_compatibility_dynamic_replacements); - if (context.OI.CompilerMode == OutputInfo::Mode::SingleCompile) { - context.Args.AddLastArg(Arguments, options::OPT_emit_symbol_graph); - context.Args.AddLastArg(Arguments, options::OPT_emit_symbol_graph_dir); - } - return II; } @@ -656,6 +651,7 @@ const char *ToolChain::JobContext::computeFrontendModeForCompile() const { case file_types::TY_SwiftCrossImportDir: case file_types::TY_SwiftOverlayFile: case file_types::TY_IndexUnitOutputPath: + case file_types::TY_SymbolGraphOutputPath: llvm_unreachable("Output type can never be primary output."); case file_types::TY_INVALID: llvm_unreachable("Invalid type ID"); @@ -797,6 +793,8 @@ void ToolChain::JobContext::addFrontendSupplementaryOutputArguments( addOutputsOfType(arguments, Output, Args, file_types::TY_SwiftModuleSummaryFile, "-emit-module-summary-path"); + addOutputsOfType(arguments, Output, Args, file_types::TY_SymbolGraphOutputPath, + "-emit-symbol-graph-dir"); } ToolChain::InvocationInfo @@ -914,6 +912,7 @@ ToolChain::constructInvocation(const BackendJobAction &job, case file_types::TY_SwiftCrossImportDir: case file_types::TY_SwiftOverlayFile: case file_types::TY_IndexUnitOutputPath: + case file_types::TY_SymbolGraphOutputPath: llvm_unreachable("Output type can never be primary output."); case file_types::TY_INVALID: llvm_unreachable("Invalid type ID"); diff --git a/lib/Frontend/ArgsToFrontendOutputsConverter.cpp b/lib/Frontend/ArgsToFrontendOutputsConverter.cpp index 0c042e7a12d05..1fb50acfc7ca1 100644 --- a/lib/Frontend/ArgsToFrontendOutputsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOutputsConverter.cpp @@ -341,11 +341,14 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments() options::OPT_emit_ldadd_cfile_path); auto moduleSummaryOutput = getSupplementaryFilenamesFromArguments( options::OPT_emit_module_summary_path); + auto symbolGraphOutput = getSupplementaryFilenamesFromArguments( + options::OPT_emit_symbol_graph_dir); if (!objCHeaderOutput || !moduleOutput || !moduleDocOutput || !dependenciesFile || !referenceDependenciesFile || !serializedDiagnostics || !fixItsOutput || !loadedModuleTrace || !TBD || !moduleInterfaceOutput || !privateModuleInterfaceOutput || - !moduleSourceInfoOutput || !ldAddCFileOutput || !moduleSummaryOutput) { + !moduleSourceInfoOutput || !ldAddCFileOutput || !moduleSummaryOutput || + !symbolGraphOutput) { return None; } std::vector result; @@ -368,6 +371,7 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments() sop.ModuleSourceInfoOutputPath = (*moduleSourceInfoOutput)[i]; sop.LdAddCFilePath = (*ldAddCFileOutput)[i]; sop.ModuleSummaryOutputPath = (*moduleSummaryOutput)[i]; + sop.SymbolGraphOutputDir = (*symbolGraphOutput)[i]; result.push_back(sop); } return result; @@ -459,6 +463,11 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput( OPT_emit_module_summary, pathsFromArguments.ModuleSummaryOutputPath, file_types::TY_SwiftModuleSummaryFile, "", defaultSupplementaryOutputPathExcludingExtension); + + auto symbolGraphOutputDir = determineSupplementaryOutputFilename( + OPT_emit_symbol_graph_dir, pathsFromArguments.SymbolGraphOutputDir, + file_types::TY_SymbolGraphOutputPath, "", + defaultSupplementaryOutputPathExcludingExtension); // There is no non-path form of -emit-interface-path auto ModuleInterfaceOutputPath = @@ -492,6 +501,7 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput( sop.ModuleSourceInfoOutputPath = moduleSourceInfoOutputPath; sop.LdAddCFilePath = pathsFromArguments.LdAddCFilePath; sop.ModuleSummaryOutputPath = moduleSummaryOutputPath; + sop.SymbolGraphOutputDir = symbolGraphOutputDir; return sop; } @@ -574,6 +584,7 @@ createFromTypeToPathMap(const TypeToPathMap *map) { {file_types::TY_SwiftModuleSummaryFile, paths.ModuleSummaryOutputPath}, {file_types::TY_PrivateSwiftModuleInterfaceFile, paths.PrivateModuleInterfaceOutputPath}, + {file_types::TY_SymbolGraphOutputPath, paths.SymbolGraphOutputDir}, }; for (const std::pair &typeAndString : typesAndStrings) { @@ -597,7 +608,8 @@ SupplementaryOutputPathsComputer::readSupplementaryOutputFileMap() const { options::OPT_emit_private_module_interface_path, options::OPT_emit_module_source_info_path, options::OPT_emit_tbd_path, - options::OPT_emit_ldadd_cfile_path)) { + options::OPT_emit_ldadd_cfile_path, + options::OPT_emit_symbol_graph_dir)) { Diags.diagnose(SourceLoc(), diag::error_cannot_have_supplementary_outputs, A->getSpelling(), "-supplementary-output-file-map"); diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index aaf06db1e365e..084767d032548 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -156,7 +156,9 @@ SerializationOptions CompilerInvocation::computeSerializationOptions( serializationOpts.ModuleLinkName = opts.ModuleLinkName; serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs; - if (opts.EmitSymbolGraph) { + if (!outs.SymbolGraphOutputDir.empty()) { + serializationOpts.SymbolGraphOutputDir = outs.SymbolGraphOutputDir; + } else if (opts.EmitSymbolGraph) { if (!opts.SymbolGraphOutputDir.empty()) { serializationOpts.SymbolGraphOutputDir = opts.SymbolGraphOutputDir; } else { diff --git a/test/Driver/filelists.swift b/test/Driver/filelists.swift index 732f4914e580b..296e6b06a9da4 100644 --- a/test/Driver/filelists.swift +++ b/test/Driver/filelists.swift @@ -35,6 +35,16 @@ // CHECK-WMO-NOT: Handled +// RUN: %swiftc_driver -save-temps -driver-print-jobs -c %S/Inputs/lib.swift -module-name lib -target x86_64-apple-macosx10.9 -driver-filelist-threshold=0 -whole-module-optimization -emit-module -emit-symbol-graph -emit-symbol-graph-dir %t 2>&1 | tee %t/forWMOFilelistCapture | %FileCheck -check-prefix=CHECK-WMO-SYM-FILELIST %s +// RUN: grep -e ' -supplementary-output-file-map ' %t/forWMOFilelistCapture | tail -1 | sed 's/.*-supplementary-output-file-map //' | sed 's/ .*//' > %t/supplementary-output +// RUN: cat $(cat %t/supplementary-output) | %FileCheck -check-prefix CHECK-WMO-SYM-SUPP %s + +// CHECK-WMO-SYM-FILELIST: swift +// CHECK-WMO-SYM-FILELIST-DAG: -supplementary-output-file-map + +// CHECK-WMO-SYM-SUPP: symbol-graph-output-path + + // RUN: %empty-directory(%t/bin) // RUN: ln -s %S/Inputs/filelists/fake-ld.py %t/bin/ld @@ -77,8 +87,8 @@ // RUN: echo "int dummy;" >%t/a.cpp // RUN: %target-clang -c %t/a.cpp -o %t/a.o // RUN: %swiftc_driver -save-temps -driver-print-jobs %S/../Inputs/empty.swift %t/a.o -lto=llvm-full -target x86_64-apple-macosx10.9 -driver-filelist-threshold=0 -o filelist 2>&1 | tee %t/forFilelistCapture | %FileCheck -check-prefix FILELIST %s -// RUN: tail -2 %t/forFilelistCapture | head -1 | sed 's/.*-output-filelist //' | sed 's/ .*//' > %t/output-filelist -// RUN: tail -1 %t/forFilelistCapture | sed 's/.*-filelist //' | sed 's/ .*//' > %t/input-filelist +// RUN: grep -e ' -output-filelist ' %t/forFilelistCapture | tail -1 | sed 's/.*-output-filelist //' | sed 's/ .*//' > %t/output-filelist +// RUN: grep -e ' -filelist ' %t/forFilelistCapture | tail -1 | sed 's/.*-filelist //' | sed 's/ .*//' > %t/input-filelist // RUN: cat $(cat %t/output-filelist) | %FileCheck -check-prefix OUTPUT-FILELIST-CONTENTS %s // RUN: cat $(cat %t/input-filelist) | %FileCheck -check-prefix INPUT-FILELIST-CONTENTS %s