Index: cfe/trunk/include/clang/Driver/CLCompatOptions.td =================================================================== --- cfe/trunk/include/clang/Driver/CLCompatOptions.td +++ cfe/trunk/include/clang/Driver/CLCompatOptions.td @@ -157,9 +157,10 @@ HelpText<"Enable trigraphs">, Alias; def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">, HelpText<"Disable trigraphs (default)">, Alias; -def _SLASH_Z7 : CLFlag<"Z7">, Alias; -def _SLASH_Zi : CLFlag<"Zi">, HelpText<"Enable debug information">, - Alias; +def _SLASH_Z7 : CLFlag<"Z7">, + HelpText<"Enable CodeView debug information in object files">; +def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, + HelpText<"Alias for /Z7. Does not produce PDBs.">; def _SLASH_Zp : CLJoined<"Zp">, HelpText<"Specify the default maximum struct packing alignment">, Alias; Index: cfe/trunk/include/clang/Driver/Options.td =================================================================== --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -1096,6 +1096,13 @@ HelpText<"Generate source-level debug information with dwarf version 3">, Flags<[CC1Option,CC1AsOption]>; def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group, HelpText<"Generate source-level debug information with dwarf version 4">, Flags<[CC1Option,CC1AsOption]>; +def gcodeview : Flag<["-"], "gcodeview">, + HelpText<"Generate CodeView debug information">, + Flags<[CC1Option, CC1AsOption, CoreOption]>; +// Equivalent to our default dwarf version. Forces usual dwarf emission when +// CodeView is enabled. +def gdwarf : Flag<["-"], "gdwarf">, Alias, Flags<[CoreOption]>; + def gfull : Flag<["-"], "gfull">, Group; def gused : Flag<["-"], "gused">, Group; def gstabs : Joined<["-"], "gstabs">, Group, Flags<[Unsupported]>; Index: cfe/trunk/include/clang/Frontend/CodeGenOptions.def =================================================================== --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def @@ -173,9 +173,14 @@ /// The kind of generated debug info. ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 3, NoDebugInfo) -/// Dwarf version. +/// Dwarf version. Version zero indicates to LLVM that no DWARF should be +/// emitted. VALUE_CODEGENOPT(DwarfVersion, 3, 0) +/// Whether we should emit CodeView debug information. It's possible to emit +/// CodeView and DWARF into the same object. +CODEGENOPT(EmitCodeView, 1, 0) + /// The kind of inlining to perform. ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining) Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp @@ -369,11 +369,16 @@ (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) { EmitModuleLinkOptions(); } - if (CodeGenOpts.DwarfVersion) + if (CodeGenOpts.DwarfVersion) { // We actually want the latest version when there are conflicts. // We can change from Warning to Latest if such mode is supported. getModule().addModuleFlag(llvm::Module::Warning, "Dwarf Version", CodeGenOpts.DwarfVersion); + } + if (CodeGenOpts.EmitCodeView) { + // Indicate that we want CodeView in the metadata. + getModule().addModuleFlag(llvm::Module::Warning, "CodeView", 1); + } if (DebugInfo) // We support a single version in the linked module. The LLVM // parser will drop debug info with a different version number Index: cfe/trunk/lib/Driver/Tools.cpp =================================================================== --- cfe/trunk/lib/Driver/Tools.cpp +++ cfe/trunk/lib/Driver/Tools.cpp @@ -3678,6 +3678,9 @@ } } + // Forward -gcodeview. + Args.AddLastArg(CmdArgs, options::OPT_gcodeview); + // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now. Args.ClaimAllArgs(options::OPT_g_flags_Group); if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info, @@ -5270,6 +5273,16 @@ /*default=*/false)) CmdArgs.push_back("-fno-rtti-data"); + // Emit CodeView if -Z7 is present. + bool EmitCodeView = Args.hasArg(options::OPT__SLASH_Z7); + bool EmitDwarf = Args.hasArg(options::OPT_gdwarf); + // If we are emitting CV but not DWARF, don't build information that LLVM + // can't yet process. + if (EmitCodeView && !EmitDwarf) + CmdArgs.push_back("-gline-tables-only"); + if (EmitCodeView) + CmdArgs.push_back("-gcodeview"); + const Driver &D = getToolChain().getDriver(); EHFlags EH = parseClangCLEHFlags(D, Args); // FIXME: Do something with NoExceptC. @@ -8820,7 +8833,7 @@ CmdArgs.push_back("-nologo"); - if (Args.hasArg(options::OPT_g_Group)) + if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7)) CmdArgs.push_back("-debug"); bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd, @@ -8976,7 +8989,8 @@ A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-"); if (Args.hasArg(options::OPT_fsyntax_only)) CmdArgs.push_back("/Zs"); - if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only)) + if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only, + options::OPT__SLASH_Z7)) CmdArgs.push_back("/Z7"); std::vector Includes = Index: cfe/trunk/lib/Frontend/CompilerInvocation.cpp =================================================================== --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp @@ -410,6 +410,13 @@ Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo); } Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info); + if (Args.hasArg(OPT_gcodeview)) { + Opts.EmitCodeView = true; + Opts.DwarfVersion = 0; + } else if (Opts.getDebugInfo() != CodeGenOptions::NoDebugInfo) { + // Default Dwarf version is 4 if we are generating debug information. + Opts.DwarfVersion = 4; + } Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); if (Args.hasArg(OPT_gdwarf_2)) Opts.DwarfVersion = 2; @@ -417,9 +424,6 @@ Opts.DwarfVersion = 3; else if (Args.hasArg(OPT_gdwarf_4)) Opts.DwarfVersion = 4; - else if (Opts.getDebugInfo() != CodeGenOptions::NoDebugInfo) - // Default Dwarf version is 4 if we are generating debug information. - Opts.DwarfVersion = 4; if (const Arg *A = Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists)) Index: cfe/trunk/test/CodeGen/dwarf-version.c =================================================================== --- cfe/trunk/test/CodeGen/dwarf-version.c +++ cfe/trunk/test/CodeGen/dwarf-version.c @@ -2,10 +2,15 @@ // RUN: %clang -target x86_64-linux-gnu -gdwarf-3 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER3 // RUN: %clang -target x86_64-linux-gnu -gdwarf-4 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 // RUN: %clang -target x86_64-linux-gnu -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 +// RUN: %clang -target x86_64-linux-gnu -gdwarf -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 // RUN: %clang -target x86_64-apple-darwin -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2 // RUN: %clang -target powerpc-unknown-openbsd -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2 // RUN: %clang -target powerpc-unknown-freebsd -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2 // RUN: %clang -target i386-pc-solaris -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2 +// +// Test what -gcodeview and -gdwarf do on Windows. +// RUN: %clang -target i686-pc-windows-msvc -gcodeview -S -emit-llvm -o - %s | FileCheck %s --check-prefix=NODWARF --check-prefix=CODEVIEW +// RUN: %clang -target i686-pc-windows-msvc -gdwarf -gcodeview -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 --check-prefix=CODEVIEW int main (void) { return 0; } @@ -13,3 +18,7 @@ // VER2: !{i32 2, !"Dwarf Version", i32 2} // VER3: !{i32 2, !"Dwarf Version", i32 3} // VER4: !{i32 2, !"Dwarf Version", i32 4} + +// NODWARF-NOT: !"Dwarf Version" +// CODEVIEW: !{i32 2, !"CodeView", i32 1} +// NODWARF-NOT: !"Dwarf Version" Index: cfe/trunk/test/Driver/cl-options.c =================================================================== --- cfe/trunk/test/Driver/cl-options.c +++ cfe/trunk/test/Driver/cl-options.c @@ -360,6 +360,19 @@ // RUN: %clang_cl /Zc:threadSafeInit /c -### -- %s 2>&1 | FileCheck -check-prefix=ThreadSafeStatics %s // ThreadSafeStatics-NOT: "-fno-threadsafe-statics" +// RUN: %clang_cl /Zi /c -### -- %s 2>&1 | FileCheck -check-prefix=Zi %s +// Zi: "-gline-tables-only" +// Zi: "-gcodeview" + +// RUN: %clang_cl /Z7 /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7 %s +// Z7: "-gline-tables-only" +// Z7: "-gcodeview" + +// RUN: %clang_cl /Z7 -gdwarf /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7_gdwarf %s +// Z7_gdwarf: "-gline-tables-only" +// Z7_gdwarf: "-gcodeview" +// Z7_gdwarf: "-gdwarf-4" + // RUN: %clang_cl -fmsc-version=1800 -TP -### -- %s 2>&1 | FileCheck -check-prefix=CXX11 %s // CXX11: -std=c++11