From 512cf211489bd55da3e81206c4bdcc048f3af877 Mon Sep 17 00:00:00 2001 From: Allan Shortlidge Date: Mon, 11 Aug 2025 19:09:10 -0700 Subject: [PATCH 1/3] Frontend: Make -dump-availability-scopes an option instead of a mode. Allowing it to be specified in conjunction with any frontend mode makes it a more flexible debugging tool. --- include/swift/Frontend/FrontendOptions.h | 7 ++++--- include/swift/Option/FrontendOptions.td | 3 +++ include/swift/Option/Options.td | 6 +----- .../ArgsToFrontendOptionsConverter.cpp | 3 +-- .../ArgsToFrontendOutputsConverter.cpp | 1 - lib/Frontend/FrontendOptions.cpp | 21 ------------------- lib/FrontendTool/FrontendTool.cpp | 17 +++++++-------- 7 files changed, 17 insertions(+), 41 deletions(-) diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 01d889fb97379..a68d6fa409e1f 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -167,9 +167,6 @@ class FrontendOptions { /// Parse and dump scope map. DumpScopeMaps, - /// Parse, type-check, and dump availability scopes - DumpAvailabilityScopes, - EmitImportedModules, ///< Emit the modules that this one imports EmitPCH, ///< Emit PCH of imported bridging header @@ -313,6 +310,10 @@ class FrontendOptions { /// upon termination. bool DumpClangLookupTables = false; + /// Indicates whether or not availability scopes should be dumped upon + /// termination. + bool DumpAvailabilityScopes = false; + /// Indicates whether standard help should be shown. bool PrintHelp = false; diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index a032b6caeccf4..77322cbb18ef2 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -673,6 +673,9 @@ def dump_clang_lookup_tables : Flag<["-"], "dump-clang-lookup-tables">, HelpText<"Dump the importer's Swift-name-to-Clang-name lookup tables to " "stderr">; +def dump_availability_scopes : Flag<["-"], "dump-availability-scopes">, + HelpText<"Dump availability scopes to stderr">; + def disable_modules_validate_system_headers : Flag<["-"], "disable-modules-validate-system-headers">, HelpText<"Disable validating system headers in the Clang importer">; diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 3c9e8f1630115..e95b32310dcc9 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -1435,11 +1435,7 @@ def dump_scope_maps : Separate<["-"], "dump-scope-maps">, MetaVarName<"">, ModeOpt, Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>; -def dump_availability_scopes : - Flag<["-"], "dump-availability-scopes">, - HelpText<"Type-check input file(s) and dump availability scopes">, - ModeOpt, - Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>; + def dump_type_info : Flag<["-"], "dump-type-info">, HelpText<"Output YAML dump of fixed-size types from all imported modules">, ModeOpt, diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index e2ffe6511d64a..1fa65c581101b 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -198,6 +198,7 @@ bool ArgsToFrontendOptionsConverter::convert( computeTBDOptions(); Opts.DumpClangLookupTables |= Args.hasArg(OPT_dump_clang_lookup_tables); + Opts.DumpAvailabilityScopes |= Args.hasArg(OPT_dump_availability_scopes); Opts.CheckOnoneSupportCompleteness = Args.hasArg(OPT_check_onone_completeness); @@ -665,8 +666,6 @@ ArgsToFrontendOptionsConverter::determineRequestedAction(const ArgList &args) { return FrontendOptions::ActionType::MergeModules; if (Opt.matches(OPT_dump_scope_maps)) return FrontendOptions::ActionType::DumpScopeMaps; - if (Opt.matches(OPT_dump_availability_scopes)) - return FrontendOptions::ActionType::DumpAvailabilityScopes; if (Opt.matches(OPT_dump_interface_hash)) return FrontendOptions::ActionType::DumpInterfaceHash; if (Opt.matches(OPT_dump_type_info)) diff --git a/lib/Frontend/ArgsToFrontendOutputsConverter.cpp b/lib/Frontend/ArgsToFrontendOutputsConverter.cpp index 4a726c8fbd570..31cfd92649ebb 100644 --- a/lib/Frontend/ArgsToFrontendOutputsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOutputsConverter.cpp @@ -473,7 +473,6 @@ static bool shouldEmitFineModuleTrace(FrontendOptions::ActionType action) { case swift::FrontendOptions::ActionType::PrintAST: case swift::FrontendOptions::ActionType::PrintASTDecl: case swift::FrontendOptions::ActionType::DumpScopeMaps: - case swift::FrontendOptions::ActionType::DumpAvailabilityScopes: case swift::FrontendOptions::ActionType::EmitImportedModules: case swift::FrontendOptions::ActionType::EmitPCH: case swift::FrontendOptions::ActionType::EmitModuleOnly: diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp index bad0f40c23050..3cf4b1ece3fee 100644 --- a/lib/Frontend/FrontendOptions.cpp +++ b/lib/Frontend/FrontendOptions.cpp @@ -41,7 +41,6 @@ bool FrontendOptions::needsProperModuleName(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpPCM: case ActionType::EmitPCH: return false; @@ -111,7 +110,6 @@ bool FrontendOptions::doesActionRequireSwiftStandardLibrary(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::EmitSILGen: case ActionType::EmitSIL: case ActionType::EmitLoweredSIL: @@ -157,7 +155,6 @@ bool FrontendOptions::doesActionRequireInputs(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::EmitSILGen: case ActionType::EmitSIL: case ActionType::EmitLoweredSIL: @@ -200,7 +197,6 @@ bool FrontendOptions::doesActionPerformEndOfPipelineActions(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::EmitSILGen: case ActionType::EmitSIL: case ActionType::EmitLoweredSIL: @@ -239,7 +235,6 @@ bool FrontendOptions::supportCompilationCaching(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::MergeModules: case ActionType::Immediate: case ActionType::DumpTypeInfo: @@ -305,7 +300,6 @@ FrontendOptions::formatForPrincipalOutputFileForAction(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::DumpPCM: case ActionType::PrintVersion: @@ -378,7 +372,6 @@ bool FrontendOptions::canActionEmitDependencies(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::CompileModuleFromInterface: case ActionType::TypecheckModuleFromInterface: @@ -422,7 +415,6 @@ bool FrontendOptions::canActionEmitReferenceDependencies(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::CompileModuleFromInterface: case ActionType::TypecheckModuleFromInterface: @@ -467,7 +459,6 @@ bool FrontendOptions::canActionEmitModuleSummary(ActionType action) { case ActionType::EmitImportedModules: case ActionType::EmitPCH: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::EmitSILGen: case ActionType::EmitSIBGen: @@ -509,7 +500,6 @@ bool FrontendOptions::canActionEmitClangHeader(ActionType action) { case ActionType::PrintASTDecl: case ActionType::EmitPCH: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::CompileModuleFromInterface: case ActionType::TypecheckModuleFromInterface: @@ -550,7 +540,6 @@ bool FrontendOptions::canActionEmitLoadedModuleTrace(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::CompileModuleFromInterface: case ActionType::TypecheckModuleFromInterface: @@ -600,7 +589,6 @@ bool FrontendOptions::canActionEmitModuleSemanticInfo(ActionType action) { case ActionType::PrintASTDecl: case ActionType::EmitPCH: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::EmitSILGen: case ActionType::TypecheckModuleFromInterface: @@ -643,7 +631,6 @@ bool FrontendOptions::canActionEmitConstValues(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::CompileModuleFromInterface: case ActionType::TypecheckModuleFromInterface: @@ -687,7 +674,6 @@ bool FrontendOptions::canActionEmitModule(ActionType action) { case ActionType::PrintASTDecl: case ActionType::EmitPCH: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::EmitSILGen: case ActionType::CompileModuleFromInterface: @@ -733,7 +719,6 @@ bool FrontendOptions::canActionEmitInterface(ActionType action) { case ActionType::EmitImportedModules: case ActionType::EmitPCH: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::EmitSILGen: case ActionType::EmitSIBGen: @@ -776,7 +761,6 @@ bool FrontendOptions::canActionEmitAPIDescriptor(ActionType action) { case ActionType::EmitImportedModules: case ActionType::EmitPCH: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::EmitSILGen: case ActionType::EmitSIBGen: @@ -818,7 +802,6 @@ bool FrontendOptions::doesActionProduceOutput(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::EmitPCH: case ActionType::EmitSILGen: case ActionType::EmitSIL: @@ -877,7 +860,6 @@ bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::EmitImportedModules: case ActionType::EmitSILGen: case ActionType::EmitSIL: @@ -907,7 +889,6 @@ bool FrontendOptions::doesActionGenerateSIL(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::EmitImportedModules: case ActionType::EmitPCH: case ActionType::CompileModuleFromInterface: @@ -948,7 +929,6 @@ bool FrontendOptions::doesActionGenerateIR(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::CompileModuleFromInterface: case ActionType::TypecheckModuleFromInterface: @@ -994,7 +974,6 @@ bool FrontendOptions::doesActionBuildModuleFromInterface(ActionType action) { case ActionType::PrintAST: case ActionType::PrintASTDecl: case ActionType::DumpScopeMaps: - case ActionType::DumpAvailabilityScopes: case ActionType::DumpTypeInfo: case ActionType::Typecheck: case ActionType::ResolveImports: diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index 2d9798e7da123..3aff1718e5eb7 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -1040,6 +1040,10 @@ static void performEndOfPipelineActions(CompilerInstance &Instance) { if (opts.DumpClangLookupTables && ctx.getClangModuleLoader()) ctx.getClangModuleLoader()->dumpSwiftLookupTables(); + if (opts.DumpAvailabilityScopes) + getPrimaryOrMainSourceFile(Instance).getAvailabilityScope()->dump( + llvm::errs(), Instance.getASTContext().SourceMgr); + // Report mangling stats if there was no error. if (!ctx.hadError()) Mangle::printManglingStats(); @@ -1295,17 +1299,12 @@ static bool performAction(CompilerInstance &Instance, }); case FrontendOptions::ActionType::DumpScopeMaps: return withSemanticAnalysis( - Instance, observer, [](CompilerInstance &Instance) { + Instance, observer, + [](CompilerInstance &Instance) { return dumpAndPrintScopeMap(Instance, getPrimaryOrMainSourceFile(Instance)); - }, /*runDespiteErrors=*/true); - case FrontendOptions::ActionType::DumpAvailabilityScopes: - return withSemanticAnalysis( - Instance, observer, [](CompilerInstance &Instance) { - getPrimaryOrMainSourceFile(Instance).getAvailabilityScope()->dump( - llvm::errs(), Instance.getASTContext().SourceMgr); - return Instance.getASTContext().hadError(); - }, /*runDespiteErrors=*/true); + }, + /*runDespiteErrors=*/true); case FrontendOptions::ActionType::DumpInterfaceHash: getPrimaryOrMainSourceFile(Instance).dumpInterfaceHash(llvm::errs()); return Instance.getASTContext().hadError(); From 901e8becb2158a57ab25bb157439301c6aeed397 Mon Sep 17 00:00:00 2001 From: Allan Shortlidge Date: Tue, 12 Aug 2025 09:32:24 -0700 Subject: [PATCH 2/3] Frontend: Make getPrimaryOrMainSourceFile() a utility on CompilerInstance. --- include/swift/Frontend/Frontend.h | 6 ++++++ lib/FrontendTool/FrontendTool.cpp | 20 ++++++-------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index 029e296ab5d38..caeaf4d440301 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -710,6 +710,12 @@ class CompilerInstance { } } + SourceFile &getPrimaryOrMainSourceFile() const { + if (SourceFile *SF = getPrimarySourceFile()) + return *SF; + return getMainModule()->getMainSourceFile(); + } + /// Returns true if there was an error during setup. bool setup(const CompilerInvocation &Invocation, std::string &Error, ArrayRef Args = {}); diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index 3aff1718e5eb7..afa4b40087ae0 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -458,14 +458,6 @@ static bool dumpAndPrintScopeMap(const CompilerInstance &Instance, return Instance.getASTContext().hadError(); } -static SourceFile & -getPrimaryOrMainSourceFile(const CompilerInstance &Instance) { - if (SourceFile *SF = Instance.getPrimarySourceFile()) { - return *SF; - } - return Instance.getMainModule()->getMainSourceFile(); -} - /// Dumps the AST of all available primary source files. If corresponding output /// files were specified, use them; otherwise, dump the AST to stdout. static bool dumpAST(CompilerInstance &Instance, @@ -512,7 +504,7 @@ static bool dumpAST(CompilerInstance &Instance, } else { // Some invocations don't have primary files. In that case, we default to // looking for the main file and dumping it to `stdout`. - auto &SF = getPrimaryOrMainSourceFile(Instance); + auto &SF = Instance.getPrimaryOrMainSourceFile(); dumpAST(&SF, llvm::outs()); } return Instance.getASTContext().hadError(); @@ -1041,7 +1033,7 @@ static void performEndOfPipelineActions(CompilerInstance &Instance) { ctx.getClangModuleLoader()->dumpSwiftLookupTables(); if (opts.DumpAvailabilityScopes) - getPrimaryOrMainSourceFile(Instance).getAvailabilityScope()->dump( + Instance.getPrimaryOrMainSourceFile().getAvailabilityScope()->dump( llvm::errs(), Instance.getASTContext().SourceMgr); // Report mangling stats if there was no error. @@ -1286,14 +1278,14 @@ static bool performAction(CompilerInstance &Instance, case FrontendOptions::ActionType::PrintAST: return withSemanticAnalysis( Instance, observer, [](CompilerInstance &Instance) { - getPrimaryOrMainSourceFile(Instance).print( + Instance.getPrimaryOrMainSourceFile().print( llvm::outs(), PrintOptions::printEverything()); return Instance.getASTContext().hadError(); }); case FrontendOptions::ActionType::PrintASTDecl: return withSemanticAnalysis( Instance, observer, [](CompilerInstance &Instance) { - getPrimaryOrMainSourceFile(Instance).print( + Instance.getPrimaryOrMainSourceFile().print( llvm::outs(), PrintOptions::printDeclarations()); return Instance.getASTContext().hadError(); }); @@ -1302,11 +1294,11 @@ static bool performAction(CompilerInstance &Instance, Instance, observer, [](CompilerInstance &Instance) { return dumpAndPrintScopeMap(Instance, - getPrimaryOrMainSourceFile(Instance)); + Instance.getPrimaryOrMainSourceFile()); }, /*runDespiteErrors=*/true); case FrontendOptions::ActionType::DumpInterfaceHash: - getPrimaryOrMainSourceFile(Instance).dumpInterfaceHash(llvm::errs()); + Instance.getPrimaryOrMainSourceFile().dumpInterfaceHash(llvm::errs()); return Instance.getASTContext().hadError(); case FrontendOptions::ActionType::EmitImportedModules: return emitImportedModules(Instance.getMainModule(), opts, From 5d3d93478a08c9f420788a74f57dc816b20919e1 Mon Sep 17 00:00:00 2001 From: Allan Shortlidge Date: Tue, 12 Aug 2025 09:36:37 -0700 Subject: [PATCH 3/3] Frontend: Inherit compiler debugging options during module interface actions. When building a module interface for the -typecheck-module-from-interface or -compile-module-from-interface actions, inherit and honor compiler debugging options and emit debugging output at the end of the interface build. --- include/swift/Frontend/Frontend.h | 3 ++ include/swift/Frontend/FrontendOptions.h | 30 +++++++++++-------- .../swift/Frontend/ModuleInterfaceLoader.h | 28 ++++------------- .../ArgsToFrontendOptionsConverter.cpp | 10 +++++-- lib/Frontend/Frontend.cpp | 18 +++++++++++ lib/Frontend/ModuleInterfaceBuilder.cpp | 4 +++ lib/Frontend/ModuleInterfaceLoader.cpp | 29 ++++++++++++++++++ lib/FrontendTool/FrontendTool.cpp | 16 +++------- .../ModuleInterface/availability-scopes.swift | 10 +++++++ 9 files changed, 99 insertions(+), 49 deletions(-) create mode 100644 test/ModuleInterface/availability-scopes.swift diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index caeaf4d440301..7988413f57bfc 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -798,6 +798,9 @@ class CompilerInstance { /// \returns true if any errors occurred. bool performSILProcessing(SILModule *silModule); + /// Dumps any debugging output for the compilation, if requested. + void emitEndOfPipelineDebuggingOutput(); + private: /// Creates a new source file for the main module. SourceFile *createSourceFileForMainModule(ModuleDecl *mod, diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index a68d6fa409e1f..a120e58903263 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -35,6 +35,21 @@ namespace llvm { namespace swift { enum class IntermoduleDepTrackingMode; +/// Options for debugging the behavior of the frontend. +struct CompilerDebuggingOptions { + /// Indicates whether or not the Clang importer should print statistics upon + /// termination. + bool PrintClangStats = false; + + /// Indicates whether or not the availability scope trees built during + /// compilation should be dumped upon termination. + bool DumpAvailabilityScopes = false; + + /// Indicates whether or not the Clang importer should dump lookup tables + /// upon termination. + bool DumpClangLookupTables = false; +}; + /// Options for controlling the behavior of the frontend. class FrontendOptions { friend class ArgsToFrontendOptionsConverter; @@ -124,6 +139,9 @@ class FrontendOptions { /// A set of modules allowed to import this module. std::set AllowableClients; + /// Options for debugging the compiler. + CompilerDebuggingOptions CompilerDebuggingOpts; + /// Emit index data for imported serialized swift system modules. bool IndexSystemModules = false; @@ -302,18 +320,6 @@ class FrontendOptions { /// termination. bool PrintStats = false; - /// Indicates whether or not the Clang importer should print statistics upon - /// termination. - bool PrintClangStats = false; - - /// Indicates whether or not the Clang importer should dump lookup tables - /// upon termination. - bool DumpClangLookupTables = false; - - /// Indicates whether or not availability scopes should be dumped upon - /// termination. - bool DumpAvailabilityScopes = false; - /// Indicates whether standard help should be shown. bool PrintHelp = false; diff --git a/include/swift/Frontend/ModuleInterfaceLoader.h b/include/swift/Frontend/ModuleInterfaceLoader.h index 2aa2124b70441..a4148599e08cc 100644 --- a/include/swift/Frontend/ModuleInterfaceLoader.h +++ b/include/swift/Frontend/ModuleInterfaceLoader.h @@ -455,7 +455,8 @@ class ExplicitModuleMapParser { llvm::StringSaver Saver; }; -struct ModuleInterfaceLoaderOptions { +class ModuleInterfaceLoaderOptions { +public: FrontendOptions::ActionType requestedAction = FrontendOptions::ActionType::EmitModuleOnly; bool remarkOnRebuildFromInterface = false; @@ -464,28 +465,11 @@ struct ModuleInterfaceLoaderOptions { bool disableBuildingInterface = false; bool downgradeInterfaceVerificationError = false; bool strictImplicitModuleContext = false; + CompilerDebuggingOptions compilerDebuggingOptions; std::string mainExecutablePath; - ModuleInterfaceLoaderOptions(const FrontendOptions &Opts): - remarkOnRebuildFromInterface(Opts.RemarkOnRebuildFromModuleInterface), - disableInterfaceLock(Opts.DisableInterfaceFileLock), - disableImplicitSwiftModule(Opts.DisableImplicitModules), - disableBuildingInterface(Opts.DisableBuildingInterface), - downgradeInterfaceVerificationError(Opts.DowngradeInterfaceVerificationError), - strictImplicitModuleContext(Opts.StrictImplicitModuleContext), - mainExecutablePath(Opts.MainExecutablePath) - { - switch (Opts.RequestedAction) { - case FrontendOptions::ActionType::TypecheckModuleFromInterface: - requestedAction = FrontendOptions::ActionType::Typecheck; - break; - case FrontendOptions::ActionType::ScanDependencies: - requestedAction = Opts.RequestedAction; - break; - default: - requestedAction = FrontendOptions::ActionType::EmitModuleOnly; - break; - } - } + + ModuleInterfaceLoaderOptions(const FrontendOptions &Opts, + bool inheritDebuggingOpts = false); ModuleInterfaceLoaderOptions() = default; }; diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index 1fa65c581101b..22ed81daa6fe6 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -197,8 +197,11 @@ bool ArgsToFrontendOptionsConverter::convert( computeDebugTimeOptions(); computeTBDOptions(); - Opts.DumpClangLookupTables |= Args.hasArg(OPT_dump_clang_lookup_tables); - Opts.DumpAvailabilityScopes |= Args.hasArg(OPT_dump_availability_scopes); + Opts.CompilerDebuggingOpts.DumpAvailabilityScopes |= + Args.hasArg(OPT_dump_availability_scopes); + + Opts.CompilerDebuggingOpts.DumpClangLookupTables |= + Args.hasArg(OPT_dump_clang_lookup_tables); Opts.CheckOnoneSupportCompleteness = Args.hasArg(OPT_check_onone_completeness); @@ -472,7 +475,8 @@ void ArgsToFrontendOptionsConverter::handleDebugCrashGroupArguments() { void ArgsToFrontendOptionsConverter::computePrintStatsOptions() { using namespace options; Opts.PrintStats |= Args.hasArg(OPT_print_stats); - Opts.PrintClangStats |= Args.hasArg(OPT_print_clang_stats); + Opts.CompilerDebuggingOpts.PrintClangStats |= + Args.hasArg(OPT_print_clang_stats); Opts.PrintZeroStats |= Args.hasArg(OPT_print_zero_stats); #if defined(NDEBUG) && !LLVM_ENABLE_STATS if (Opts.PrintStats || Opts.PrintClangStats) diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 5cadb6afe4fe1..c79192c88c1dd 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -18,6 +18,7 @@ #include "swift/Frontend/Frontend.h" #include "swift/AST/ASTContext.h" #include "swift/AST/AvailabilityDomain.h" +#include "swift/AST/AvailabilityScope.h" #include "swift/AST/DiagnosticsFrontend.h" #include "swift/AST/DiagnosticsSema.h" #include "swift/AST/FileSystem.h" @@ -1867,6 +1868,23 @@ bool CompilerInstance::performSILProcessing(SILModule *silModule) { return false; } +void CompilerInstance::emitEndOfPipelineDebuggingOutput() { + assert(hasASTContext()); + auto &ctx = getASTContext(); + const auto &Invocation = getInvocation(); + const auto &opts = Invocation.getFrontendOptions().CompilerDebuggingOpts; + + if (opts.PrintClangStats && ctx.getClangModuleLoader()) + ctx.getClangModuleLoader()->printStatistics(); + + if (opts.DumpAvailabilityScopes) + getPrimaryOrMainSourceFile().getAvailabilityScope()->dump(llvm::errs(), + ctx.SourceMgr); + + if (opts.DumpClangLookupTables && ctx.getClangModuleLoader()) + ctx.getClangModuleLoader()->dumpSwiftLookupTables(); +} + bool CompilerInstance::isCancellationRequested() const { auto flag = getASTContext().CancellationFlag; return flag && flag->load(std::memory_order_relaxed); diff --git a/lib/Frontend/ModuleInterfaceBuilder.cpp b/lib/Frontend/ModuleInterfaceBuilder.cpp index ac50e5e7bfdfe..be3dd3520cfdd 100644 --- a/lib/Frontend/ModuleInterfaceBuilder.cpp +++ b/lib/Frontend/ModuleInterfaceBuilder.cpp @@ -203,6 +203,7 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface( ArrayRef CompiledCandidates, StringRef CompilerVersion) { auto Invocation = Instance.getInvocation(); + // Try building forwarding module first. If succeed, return. if (Instance.getASTContext() .getModuleInterfaceChecker() @@ -254,6 +255,9 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface( builtByCompiler); } } + + // If requested, dump debugging output before exiting. + Instance.emitEndOfPipelineDebuggingOutput(); }; Instance.performSema(); diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp index 98184ffc0d8d0..c2cc8dd445455 100644 --- a/lib/Frontend/ModuleInterfaceLoader.cpp +++ b/lib/Frontend/ModuleInterfaceLoader.cpp @@ -1294,6 +1294,34 @@ bool ModuleInterfaceCheckerImpl::isCached(StringRef DepPath) { return !PrebuiltCacheDir.empty() && DepPath.starts_with(PrebuiltCacheDir); } +static FrontendOptions::ActionType +reqestedModuleLoaderActionForFrontendOpts(const FrontendOptions &Opts) { + switch (Opts.RequestedAction) { + case FrontendOptions::ActionType::TypecheckModuleFromInterface: + return FrontendOptions::ActionType::Typecheck; + case FrontendOptions::ActionType::ScanDependencies: + return Opts.RequestedAction; + default: + return FrontendOptions::ActionType::EmitModuleOnly; + } +} + +ModuleInterfaceLoaderOptions::ModuleInterfaceLoaderOptions( + const FrontendOptions &Opts, bool inheritDebuggingOpts) + : requestedAction(reqestedModuleLoaderActionForFrontendOpts(Opts)), + remarkOnRebuildFromInterface(Opts.RemarkOnRebuildFromModuleInterface), + disableInterfaceLock(Opts.DisableInterfaceFileLock), + disableImplicitSwiftModule(Opts.DisableImplicitModules), + disableBuildingInterface(Opts.DisableBuildingInterface), + downgradeInterfaceVerificationError( + Opts.DowngradeInterfaceVerificationError), + strictImplicitModuleContext(Opts.StrictImplicitModuleContext), + mainExecutablePath(Opts.MainExecutablePath) { + if (inheritDebuggingOpts) { + compilerDebuggingOptions = Opts.CompilerDebuggingOpts; + } +} + bool ModuleInterfaceLoader::isCached(StringRef DepPath) { return InterfaceChecker.isCached(DepPath); } @@ -1870,6 +1898,7 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl( SubFEOpts.RequestedAction = LoaderOpts.requestedAction; SubFEOpts.StrictImplicitModuleContext = LoaderOpts.strictImplicitModuleContext; + SubFEOpts.CompilerDebuggingOpts = LoaderOpts.compilerDebuggingOptions; if (!moduleCachePath.empty()) { genericSubInvocation.setClangModuleCachePath(moduleCachePath); } diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index afa4b40087ae0..e9725e0de23e3 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -353,7 +353,8 @@ static bool buildModuleFromInterface(CompilerInstance &Instance) { assert(FEOpts.InputsAndOutputs.hasSingleInput()); StringRef InputPath = FEOpts.InputsAndOutputs.getFilenameOfFirstInput(); StringRef PrebuiltCachePath = FEOpts.PrebuiltModuleCachePath; - ModuleInterfaceLoaderOptions LoaderOpts(FEOpts); + ModuleInterfaceLoaderOptions LoaderOpts(FEOpts, + /*inheritDebuggingOpts=*/true); StringRef ABIPath = Instance.getPrimarySpecificPathsForAtMostOnePrimary() .SupplementaryOutputs.ABIDescriptorOutputPath; bool IgnoreAdjacentModules = Instance.hasASTContext() && @@ -1021,25 +1022,16 @@ static void performEndOfPipelineActions(CompilerInstance &Instance) { const auto &Invocation = Instance.getInvocation(); const auto &opts = Invocation.getFrontendOptions(); - // If we were asked to print Clang stats, do so. - if (opts.PrintClangStats && ctx.getClangModuleLoader()) - ctx.getClangModuleLoader()->printStatistics(); - // Report AST stats if needed. if (auto *stats = ctx.Stats) countASTStats(*stats, Instance); - if (opts.DumpClangLookupTables && ctx.getClangModuleLoader()) - ctx.getClangModuleLoader()->dumpSwiftLookupTables(); - - if (opts.DumpAvailabilityScopes) - Instance.getPrimaryOrMainSourceFile().getAvailabilityScope()->dump( - llvm::errs(), Instance.getASTContext().SourceMgr); - // Report mangling stats if there was no error. if (!ctx.hadError()) Mangle::printManglingStats(); + Instance.emitEndOfPipelineDebuggingOutput(); + // Make sure we didn't load a module during a parse-only invocation, unless // it's -emit-imported-modules, which can load modules. auto action = opts.RequestedAction; diff --git a/test/ModuleInterface/availability-scopes.swift b/test/ModuleInterface/availability-scopes.swift new file mode 100644 index 0000000000000..2985d88ada8e2 --- /dev/null +++ b/test/ModuleInterface/availability-scopes.swift @@ -0,0 +1,10 @@ +// RUN: %empty-directory(%t) + +// RUN: %target-swift-emit-module-interface(%t/Test.swiftinterface) %s -module-name Test +// RUN: %target-swift-typecheck-module-from-interface(%t/Test.swiftinterface) -module-name Test -dump-availability-scopes 2>&1 | %FileCheck --strict-whitespace %s +// RUN: %target-swift-frontend -compile-module-from-interface %t/Test.swiftinterface -o /dev/null -module-name Test -dump-availability-scopes 2>&1 | %FileCheck --strict-whitespace %s + +// CHECK: {{^}}(root {{.*}} file={{.*}}{{/|\\}}availability-scopes.swift.tmp{{/|\\}}Test.swiftinterface +// CHECK: {{^}} (decl {{.*}}unavailable=* decl=unavailable() +@available(*, unavailable) +public func unavailable() { }