Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1814,9 +1814,15 @@ HelpText<"Generate source-level debug information with dwarf version 4">; def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group, HelpText<"Generate source-level debug information with dwarf version 5">; + def gcodeview : Flag<["-"], "gcodeview">, HelpText<"Generate CodeView debug information">, Flags<[CC1Option, CC1AsOption, CoreOption]>; +def gcodeview_ghash : Flag<["-"], "gcodeview-ghash">, + HelpText<"Emit type record hashes in a .debug$H section">, + Flags<[CC1Option, CoreOption]>; +def gno_codeview_ghash : Flag<["-"], "gno-codeview-ghash">, Flags<[CoreOption]>; + // Equivalent to our default dwarf version. Forces usual dwarf emission when // CodeView is enabled. def gdwarf : Flag<["-"], "gdwarf">, Alias, Flags<[CoreOption]>; Index: clang/include/clang/Frontend/CodeGenOptions.def =================================================================== --- clang/include/clang/Frontend/CodeGenOptions.def +++ clang/include/clang/Frontend/CodeGenOptions.def @@ -295,6 +295,9 @@ /// CodeView and DWARF into the same object. CODEGENOPT(EmitCodeView, 1, 0) +/// Whether to emit the .debug$H section containing hashes of CodeView types. +CODEGENOPT(CodeViewGHash, 1, 0) + /// The kind of inlining to perform. ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining) Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -458,6 +458,9 @@ // Indicate that we want CodeView in the metadata. getModule().addModuleFlag(llvm::Module::Warning, "CodeView", 1); } + if (CodeGenOpts.CodeViewGHash) { + getModule().addModuleFlag(llvm::Module::Warning, "CodeViewGHash", 1); + } if (CodeGenOpts.ControlFlowGuard) { // We want function ID tables for Control Flow Guard. getModule().addModuleFlag(llvm::Module::Warning, "cfguardtable", 1); Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -3085,6 +3085,12 @@ CmdArgs.push_back("-gcodeview"); } } + + // Emit codeview type hashes if requested. + if (Args.hasFlag(options::OPT_gcodeview_ghash, + options::OPT_gno_codeview_ghash, false)) { + CmdArgs.push_back("-gcodeview-ghash"); + } } if (!EmitCodeView && DWARFVersion == 0 && Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -593,6 +593,7 @@ Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags); Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info); Opts.EmitCodeView = Args.hasArg(OPT_gcodeview); + Opts.CodeViewGHash = Args.hasArg(OPT_gcodeview_ghash); Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro); Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables); Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std); Index: clang/test/CodeGenCXX/debug-info-ms-abi.cpp =================================================================== --- clang/test/CodeGenCXX/debug-info-ms-abi.cpp +++ clang/test/CodeGenCXX/debug-info-ms-abi.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -gcodeview-ghash -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,GHASH // Tests that certain miscellaneous features work in the MS ABI. @@ -45,3 +46,6 @@ // CHECK-NEXT: ![[dummy:[0-9]+]] = !DISubroutineType(types: ![[Signature:[0-9]+]]) // CHECK: ![[Signature]] = !{null, ![[BasicInt:[0-9]+]], ![[BasicInt]]} // CHECK: ![[BasicInt]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) + +// CHECK: !{{[0-9]+}} = !{i32 2, !"CodeView", i32 1} +// GHASH: !{{[0-9]+}} = !{i32 2, !"CodeViewGHash", i32 1} Index: clang/test/Driver/gcodeview-ghash.c =================================================================== --- /dev/null +++ clang/test/Driver/gcodeview-ghash.c @@ -0,0 +1,19 @@ +// Note: %s must be preceded by --, otherwise it may be interpreted as a +// command-line option, e.g. on Mac where %s is commonly under /Users. + +// GHASH: "-gcodeview-ghash" +// NO_GHASH-NOT: "-gcodeview-ghash" + +// default +// RUN: %clang_cl /Z7 -### -- %s 2>&1 | FileCheck -check-prefix=NO_GHASH %s +// enabled +// RUN: %clang_cl /Z7 -gcodeview-ghash -### -- %s 2>&1 | FileCheck -check-prefix=GHASH %s +// disabled +// RUN: %clang_cl /Z7 -gcodeview-ghash -gno-codeview-ghash -### -- %s 2>&1 | FileCheck -check-prefix=NO_GHASH %s + +// enabled, no /Z7 +// RUN: %clang_cl -gcodeview-ghash -### -- %s 2>&1 | FileCheck -check-prefix=NO_GHASH %s + +// GCC-style driver +// RUN: %clang -g -gcodeview -gcodeview-ghash -### -- %s 2>&1 | FileCheck -check-prefix=GHASH %s +// RUN: %clang -g -gcodeview -gcodeview-ghash -gno-codeview-ghash -### -- %s 2>&1 | FileCheck -check-prefix=NO_GHASH %s Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -54,6 +54,9 @@ BumpPtrAllocator Allocator; codeview::GlobalTypeTableBuilder TypeTable; + /// Whether to emit type record hashes into .debug$H. + bool EmitDebugGlobalHashes = false; + /// The codeview CPU type used by the translation unit. codeview::CPUType TheCPU; Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -92,9 +92,6 @@ using namespace llvm; using namespace llvm::codeview; -static cl::opt EmitDebugGlobalHashes("emit-codeview-ghash-section", - cl::ReallyHidden, cl::init(false)); - static CPUType mapArchToCVCPUType(Triple::ArchType Type) { switch (Type) { case Triple::ArchType::x86: @@ -125,6 +122,11 @@ TheCPU = mapArchToCVCPUType(Triple(MMI->getModule()->getTargetTriple()).getArch()); + + // Check if we should emit type record hashes. + ConstantInt *GH = mdconst::extract_or_null( + MMI->getModule()->getModuleFlag("CodeViewGHash")); + EmitDebugGlobalHashes = GH && !GH->isZero(); } StringRef CodeViewDebug::getFullFilepath(const DIFile *File) { Index: llvm/test/DebugInfo/COFF/global-type-hashes.ll =================================================================== --- llvm/test/DebugInfo/COFF/global-type-hashes.ll +++ llvm/test/DebugInfo/COFF/global-type-hashes.ll @@ -1,7 +1,6 @@ -; RUN: llc -filetype=obj -emit-codeview-ghash-section < %s > %t.obj +; RUN: llc -filetype=obj < %s > %t.obj ; RUN: obj2yaml %t.obj | FileCheck %s --check-prefix=YAML -; RUN: llc -filetype=asm -emit-codeview-ghash-section < %s \ -; RUN: | FileCheck %s --check-prefix=ASM +; RUN: llc -filetype=asm < %s | FileCheck %s --check-prefix=ASM ; C++ source to regenerate: ; $ cat t.cpp @@ -96,14 +95,16 @@ attributes #2 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.module.flags = !{!3, !4, !5, !6, !100} !llvm.ident = !{!7} + !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) !1 = !DIFile(filename: "", directory: "D:\5Csrc\5Cllvmbuild\5Cclang\5CDebug\5Cx86", checksumkind: CSK_MD5, checksum: "6279449503d9075c38e615e8387667c3") !2 = !{} !3 = !{i32 1, !"NumRegisterParameters", i32 0} !4 = !{i32 2, !"CodeView", i32 1} +!100 = !{i32 2, !"CodeViewGHash", i32 1} !5 = !{i32 2, !"Debug Info Version", i32 3} !6 = !{i32 1, !"wchar_size", i32 2} !7 = !{!"clang version 6.0.0 "}