Skip to content

Commit c93a5a5

Browse files
ellishgjrose-apple
authored andcommitted
Add -debug-info-format=[dwarf|codeview] option (#16888)
1 parent b7d0a79 commit c93a5a5

File tree

14 files changed

+180
-66
lines changed

14 files changed

+180
-66
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,18 @@ enum class IRGenOutputKind : unsigned {
4747
ObjectFile
4848
};
4949

50-
enum class IRGenDebugInfoKind : unsigned {
51-
None, /// No debug info.
52-
LineTables, /// Line tables only.
53-
ASTTypes, /// Line tables + AST type references.
54-
DwarfTypes, /// Line tables + AST type references + DWARF types.
55-
Normal = ASTTypes /// The setting LLDB prefers.
50+
enum class IRGenDebugInfoLevel : unsigned {
51+
None, ///< No debug info.
52+
LineTables, ///< Line tables only.
53+
ASTTypes, ///< Line tables + AST type references.
54+
DwarfTypes, ///< Line tables + AST type references + DWARF types.
55+
Normal = ASTTypes ///< The setting LLDB prefers.
56+
};
57+
58+
enum class IRGenDebugInfoFormat : unsigned {
59+
None,
60+
DWARF,
61+
CodeView
5662
};
5763

5864
enum class IRGenEmbedMode : unsigned {
@@ -72,8 +78,8 @@ class IRGenOptions {
7278
/// The DWARF version of debug info.
7379
unsigned DWARFVersion;
7480

75-
/// The command line string that is to be stored in the DWARF debug info.
76-
std::string DWARFDebugFlags;
81+
/// The command line string that is to be stored in the debug info.
82+
std::string DebugFlags;
7783

7884
/// List of -Xcc -D macro definitions.
7985
std::vector<std::string> ClangDefines;
@@ -97,8 +103,11 @@ class IRGenOptions {
97103
/// Which sanitizer is turned on.
98104
OptionSet<SanitizerKind> Sanitizers;
99105

100-
/// Whether we should emit debug info.
101-
IRGenDebugInfoKind DebugInfoKind : 2;
106+
/// What level of debug info to generate.
107+
IRGenDebugInfoLevel DebugInfoLevel : 2;
108+
109+
/// What type of debug info to generate.
110+
IRGenDebugInfoFormat DebugInfoFormat : 2;
102111

103112
/// \brief Whether we're generating IR for the JIT.
104113
unsigned UseJIT : 1;
@@ -184,8 +193,9 @@ class IRGenOptions {
184193
: DWARFVersion(2), OutputKind(IRGenOutputKind::LLVMAssembly),
185194
Verify(true), OptMode(OptimizationMode::NotSet),
186195
Sanitizers(OptionSet<SanitizerKind>()),
187-
DebugInfoKind(IRGenDebugInfoKind::None), UseJIT(false),
188-
IntegratedREPL(false),
196+
DebugInfoLevel(IRGenDebugInfoLevel::None),
197+
DebugInfoFormat(IRGenDebugInfoFormat::None),
198+
UseJIT(false), IntegratedREPL(false),
189199
DisableLLVMOptzns(false), DisableSwiftSpecificLLVMOptzns(false),
190200
DisableLLVMSLPVectorizer(false), DisableFPElim(true), Playground(false),
191201
EmitStackPromotionChecks(false), PrintInlineTree(false),

include/swift/Driver/Driver.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ class OutputInfo {
102102

103103
/// Whether or not the output should contain debug info.
104104
// FIXME: Eventually this should be replaced by dSYM generation.
105-
IRGenDebugInfoKind DebugInfoKind = IRGenDebugInfoKind::None;
105+
IRGenDebugInfoLevel DebugInfoLevel = IRGenDebugInfoLevel::None;
106+
107+
/// What kind of debug info to generate.
108+
IRGenDebugInfoFormat DebugInfoFormat = IRGenDebugInfoFormat::None;
106109

107110
/// Whether or not the driver should generate a module.
108111
bool ShouldGenerateModule = false;

include/swift/Frontend/Frontend.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,11 @@ class CompilerInvocation {
121121
serialization::Status loadFromSerializedAST(StringRef data);
122122

123123
/// Serialize the command line arguments for emitting them
124-
/// to DWARF and inject SDKPath if necessary.
125-
static void buildDWARFDebugFlags(std::string &Output,
126-
const ArrayRef<const char*> &Args,
127-
StringRef SDKPath,
128-
StringRef ResourceDir);
124+
/// to DWARF or CodeView and inject SDKPath if necessary.
125+
static void buildDebugFlags(std::string &Output,
126+
const ArrayRef<const char*> &Args,
127+
StringRef SDKPath,
128+
StringRef ResourceDir);
129129

130130
void setTargetTriple(StringRef Triple);
131131

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,10 @@ def gdwarf_types : Flag<["-"], "gdwarf-types">,
471471
Group<g_Group>, Flags<[FrontendOption]>,
472472
HelpText<"Emit full DWARF type info.">;
473473

474+
def debug_info_format : Joined<["-"], "debug-info-format=">,
475+
Flags<[FrontendOption]>,
476+
HelpText<"Specify the debug info format type to either 'dwarf' or 'codeview'">;
477+
474478
// Verify debug info
475479
def verify_debug_info : Flag<["-"], "verify-debug-info">,
476480
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>,

lib/Driver/Driver.cpp

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,22 +1369,51 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args,
13691369

13701370
if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
13711371
if (A->getOption().matches(options::OPT_g))
1372-
OI.DebugInfoKind = IRGenDebugInfoKind::Normal;
1372+
OI.DebugInfoLevel = IRGenDebugInfoLevel::Normal;
13731373
else if (A->getOption().matches(options::OPT_gline_tables_only))
1374-
OI.DebugInfoKind = IRGenDebugInfoKind::LineTables;
1374+
OI.DebugInfoLevel = IRGenDebugInfoLevel::LineTables;
13751375
else if (A->getOption().matches(options::OPT_gdwarf_types))
1376-
OI.DebugInfoKind = IRGenDebugInfoKind::DwarfTypes;
1376+
OI.DebugInfoLevel = IRGenDebugInfoLevel::DwarfTypes;
13771377
else
13781378
assert(A->getOption().matches(options::OPT_gnone) &&
13791379
"unknown -g<kind> option");
13801380
}
13811381

1382+
if (const Arg *A = Args.getLastArg(options::OPT_debug_info_format)) {
1383+
if (strcmp(A->getValue(), "dwarf") == 0)
1384+
OI.DebugInfoFormat = IRGenDebugInfoFormat::DWARF;
1385+
else if (strcmp(A->getValue(), "codeview") == 0)
1386+
OI.DebugInfoFormat = IRGenDebugInfoFormat::CodeView;
1387+
else
1388+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
1389+
A->getAsString(Args), A->getValue());
1390+
} else if (OI.DebugInfoLevel > IRGenDebugInfoLevel::None) {
1391+
// If -g was specified but not -debug-info-format, DWARF is assumed.
1392+
OI.DebugInfoFormat = IRGenDebugInfoFormat::DWARF;
1393+
}
1394+
if (Args.hasArg(options::OPT_debug_info_format) &&
1395+
!Args.hasArg(options::OPT_g_Group)) {
1396+
const Arg *debugFormatArg = Args.getLastArg(options::OPT_debug_info_format);
1397+
Diags.diagnose(SourceLoc(), diag::error_option_missing_required_argument,
1398+
debugFormatArg->getAsString(Args), "-g");
1399+
}
1400+
if (OI.DebugInfoFormat == IRGenDebugInfoFormat::CodeView &&
1401+
(OI.DebugInfoLevel == IRGenDebugInfoLevel::LineTables ||
1402+
OI.DebugInfoLevel == IRGenDebugInfoLevel::DwarfTypes)) {
1403+
const Arg *debugFormatArg = Args.getLastArg(options::OPT_debug_info_format);
1404+
Diags.diagnose(SourceLoc(), diag::error_argument_not_allowed_with,
1405+
debugFormatArg->getAsString(Args),
1406+
OI.DebugInfoLevel == IRGenDebugInfoLevel::LineTables
1407+
? "-gline-tables-only"
1408+
: "-gdwarf_types");
1409+
}
1410+
13821411
if (Args.hasArg(options::OPT_emit_module, options::OPT_emit_module_path)) {
13831412
// The user has requested a module, so generate one and treat it as
13841413
// top-level output.
13851414
OI.ShouldGenerateModule = true;
13861415
OI.ShouldTreatModuleAsTopLevelOutput = true;
1387-
} else if ((OI.DebugInfoKind > IRGenDebugInfoKind::LineTables &&
1416+
} else if ((OI.DebugInfoLevel > IRGenDebugInfoLevel::LineTables &&
13881417
OI.shouldLink()) ||
13891418
Args.hasArg(options::OPT_emit_objc_header,
13901419
options::OPT_emit_objc_header_path)) {
@@ -1806,7 +1835,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
18061835
}
18071836

18081837
if (MergeModuleAction) {
1809-
if (OI.DebugInfoKind == IRGenDebugInfoKind::Normal) {
1838+
if (OI.DebugInfoLevel == IRGenDebugInfoLevel::Normal) {
18101839
if (TC.getTriple().getObjectFormat() == llvm::Triple::ELF) {
18111840
auto *ModuleWrapAction =
18121841
C.createAction<ModuleWrapJobAction>(MergeModuleAction);
@@ -1823,7 +1852,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
18231852
TopLevelActions.push_back(LinkAction);
18241853

18251854
if (TC.getTriple().isOSDarwin() &&
1826-
OI.DebugInfoKind > IRGenDebugInfoKind::None) {
1855+
OI.DebugInfoLevel > IRGenDebugInfoLevel::None) {
18271856
auto *dSYMAction = C.createAction<GenerateDSYMJobAction>(LinkAction);
18281857
TopLevelActions.push_back(dSYMAction);
18291858
if (Args.hasArg(options::OPT_verify_debug_info)) {

lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI,
186186
inputArgs.AddLastArg(arguments, options::OPT_enable_app_extension);
187187
inputArgs.AddLastArg(arguments, options::OPT_enable_testing);
188188
inputArgs.AddLastArg(arguments, options::OPT_g_Group);
189+
inputArgs.AddLastArg(arguments, options::OPT_debug_info_format);
189190
inputArgs.AddLastArg(arguments, options::OPT_import_underlying_module);
190191
inputArgs.AddLastArg(arguments, options::OPT_module_cache_path);
191192
inputArgs.AddLastArg(arguments, options::OPT_module_link_name);

lib/Driver/WindowsToolChains.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ toolchains::Windows::constructInvocation(const LinkJobAction &job,
7272
if (!Linker.empty())
7373
Arguments.push_back(context.Args.MakeArgString("-fuse-ld=" + Linker));
7474

75+
if (context.OI.DebugInfoFormat == IRGenDebugInfoFormat::CodeView)
76+
Arguments.push_back("-Wl,/DEBUG");
77+
7578
// Configure the toolchain.
7679
// By default, use the system clang++ to link.
7780
const char *Clang = nullptr;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -717,10 +717,10 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
717717
return false;
718718
}
719719

720-
void CompilerInvocation::buildDWARFDebugFlags(std::string &Output,
721-
const ArrayRef<const char*> &Args,
722-
StringRef SDKPath,
723-
StringRef ResourceDir) {
720+
void CompilerInvocation::buildDebugFlags(std::string &Output,
721+
const ArrayRef<const char*> &Args,
722+
StringRef SDKPath,
723+
StringRef ResourceDir) {
724724
// This isn't guaranteed to be the same temp directory as what the driver
725725
// uses, but it's highly likely.
726726
llvm::SmallString<128> TDir;
@@ -762,26 +762,26 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
762762
using namespace options;
763763

764764
if (!SILOpts.SILOutputFileNameForDebugging.empty()) {
765-
Opts.DebugInfoKind = IRGenDebugInfoKind::LineTables;
765+
Opts.DebugInfoLevel = IRGenDebugInfoLevel::LineTables;
766766
} else if (const Arg *A = Args.getLastArg(OPT_g_Group)) {
767767
if (A->getOption().matches(OPT_g))
768-
Opts.DebugInfoKind = IRGenDebugInfoKind::Normal;
768+
Opts.DebugInfoLevel = IRGenDebugInfoLevel::Normal;
769769
else if (A->getOption().matches(options::OPT_gline_tables_only))
770-
Opts.DebugInfoKind = IRGenDebugInfoKind::LineTables;
770+
Opts.DebugInfoLevel = IRGenDebugInfoLevel::LineTables;
771771
else if (A->getOption().matches(options::OPT_gdwarf_types))
772-
Opts.DebugInfoKind = IRGenDebugInfoKind::DwarfTypes;
772+
Opts.DebugInfoLevel = IRGenDebugInfoLevel::DwarfTypes;
773773
else
774774
assert(A->getOption().matches(options::OPT_gnone) &&
775775
"unknown -g<kind> option");
776776

777-
if (Opts.DebugInfoKind > IRGenDebugInfoKind::LineTables) {
777+
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::LineTables) {
778778
if (Args.hasArg(options::OPT_debug_info_store_invocation)) {
779779
ArgStringList RenderedArgs;
780780
for (auto A : Args)
781781
A->render(Args, RenderedArgs);
782-
CompilerInvocation::buildDWARFDebugFlags(Opts.DWARFDebugFlags,
783-
RenderedArgs, SDKPath,
784-
ResourceDir);
782+
CompilerInvocation::buildDebugFlags(Opts.DebugFlags,
783+
RenderedArgs, SDKPath,
784+
ResourceDir);
785785
}
786786
// TODO: Should we support -fdebug-compilation-dir?
787787
llvm::SmallString<256> cwd;
@@ -790,6 +790,35 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
790790
}
791791
}
792792

793+
if (const Arg *A = Args.getLastArg(options::OPT_debug_info_format)) {
794+
if (A->containsValue("dwarf"))
795+
Opts.DebugInfoFormat = IRGenDebugInfoFormat::DWARF;
796+
else if (A->containsValue("codeview"))
797+
Opts.DebugInfoFormat = IRGenDebugInfoFormat::CodeView;
798+
else
799+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
800+
A->getAsString(Args), A->getValue());
801+
} else if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::None) {
802+
// If -g was specified but not -debug-info-format, DWARF is assumed.
803+
Opts.DebugInfoFormat = IRGenDebugInfoFormat::DWARF;
804+
}
805+
if (Args.hasArg(options::OPT_debug_info_format) &&
806+
!Args.hasArg(options::OPT_g_Group)) {
807+
const Arg *debugFormatArg = Args.getLastArg(options::OPT_debug_info_format);
808+
Diags.diagnose(SourceLoc(), diag::error_option_missing_required_argument,
809+
debugFormatArg->getAsString(Args), "-g");
810+
}
811+
if (Opts.DebugInfoFormat == IRGenDebugInfoFormat::CodeView &&
812+
(Opts.DebugInfoLevel == IRGenDebugInfoLevel::LineTables ||
813+
Opts.DebugInfoLevel == IRGenDebugInfoLevel::DwarfTypes)) {
814+
const Arg *debugFormatArg = Args.getLastArg(options::OPT_debug_info_format);
815+
Diags.diagnose(SourceLoc(), diag::error_argument_not_allowed_with,
816+
debugFormatArg->getAsString(Args),
817+
Opts.DebugInfoLevel == IRGenDebugInfoLevel::LineTables
818+
? "-gline-tables-only"
819+
: "-gdwarf_types");
820+
}
821+
793822
for (const Arg *A : Args.filtered(OPT_Xcc)) {
794823
StringRef Opt = A->getValue();
795824
if (Opt.startswith("-D") || Opt.startswith("-U"))

lib/FrontendTool/FrontendTool.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,14 +1070,14 @@ static void performSILOptimizations(CompilerInvocation &Invocation,
10701070
/// the compile unit's flags.
10711071
static void setPrivateDiscriminatorIfNeeded(IRGenOptions &IRGenOpts,
10721072
ModuleOrSourceFile MSF) {
1073-
if (IRGenOpts.DebugInfoKind == IRGenDebugInfoKind::None ||
1073+
if (IRGenOpts.DebugInfoLevel == IRGenDebugInfoLevel::None ||
10741074
!MSF.is<SourceFile *>())
10751075
return;
10761076
Identifier PD = MSF.get<SourceFile *>()->getPrivateDiscriminator();
10771077
if (!PD.empty()) {
1078-
if (!IRGenOpts.DWARFDebugFlags.empty())
1079-
IRGenOpts.DWARFDebugFlags += " ";
1080-
IRGenOpts.DWARFDebugFlags += ("-private-discriminator " + PD.str()).str();
1078+
if (!IRGenOpts.DebugFlags.empty())
1079+
IRGenOpts.DebugFlags += " ";
1080+
IRGenOpts.DebugFlags += ("-private-discriminator " + PD.str()).str();
10811081
}
10821082
}
10831083

@@ -1125,7 +1125,8 @@ static bool processCommandLineAndRunImmediately(CompilerInvocation &Invocation,
11251125
assert(!MSF.is<SourceFile *>() && "-i doesn't work in -primary-file mode");
11261126
IRGenOptions &IRGenOpts = Invocation.getIRGenOptions();
11271127
IRGenOpts.UseJIT = true;
1128-
IRGenOpts.DebugInfoKind = IRGenDebugInfoKind::Normal;
1128+
IRGenOpts.DebugInfoLevel = IRGenDebugInfoLevel::Normal;
1129+
IRGenOpts.DebugInfoFormat = IRGenDebugInfoFormat::DWARF;
11291130
const ProcessCmdLine &CmdLine =
11301131
ProcessCmdLine(opts.ImmediateArgv.begin(), opts.ImmediateArgv.end());
11311132
Instance.setSILModule(std::move(SM));

0 commit comments

Comments
 (0)