diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -358,6 +358,25 @@ return recordTypeIndexForDINode(Scope, TI); } +static StringRef removeTemplateArgs(StringRef Name) { + // Remove template args from the display name. Assume that the template args + // are the last thing in the name. + if (Name.empty() || Name.back() != '>') + return Name; + + int OpenBrackets = 0; + for (size_t i = Name.size() - 1; i >= 0; --i) { + if (Name[i] == '>') + ++OpenBrackets; + else if (Name[i] == '<') { + --OpenBrackets; + if (OpenBrackets == 0) + return Name.substr(0, i); + } + } + return Name; +} + TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) { assert(SP); @@ -367,8 +386,9 @@ return I->second; // The display name includes function template arguments. Drop them to match - // MSVC. - StringRef DisplayName = SP->getName().split('<').first; + // MSVC. We need to have the template arguments in the DISubprogram name + // because they are used in other symbol records, such as S_GPROC32_IDs. + StringRef DisplayName = removeTemplateArgs(SP->getName()); const DIScope *Scope = SP->getScope(); TypeIndex TI; diff --git a/llvm/test/DebugInfo/COFF/cpp-mangling.ll b/llvm/test/DebugInfo/COFF/cpp-mangling.ll --- a/llvm/test/DebugInfo/COFF/cpp-mangling.ll +++ b/llvm/test/DebugInfo/COFF/cpp-mangling.ll @@ -8,8 +8,11 @@ ; template ; void fn_tmpl() {} ; template void fn_tmpl(); +; struct S { void operator<<(int i) {} }; ; void f() { ; fn_tmpl(); +; S s; +; s << 3; ; } ; CHECK: {{.*}}Proc{{.*}}Sym { @@ -17,6 +20,11 @@ ; CHECK: DisplayName: foo::bar{{$}} ; CHECK-NEXT: LinkageName: ?bar@foo@@YAHH@Z +; CHECK: {{.*}}Proc{{.*}}Sym { +; CHECK: FunctionType: operator<< ({{.*}}) +; CHECK: DisplayName: S::operator<< +; CHECK-NEXT: LinkageName: ??6S@@QAEXH@Z + ; CHECK: {{.*}}Proc{{.*}}Sym { ; CHECK: FunctionType: fn_tmpl ({{.*}}) ; CHECK: DisplayName: foo::fn_tmpl @@ -27,8 +35,12 @@ target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" target triple = "i386-pc-windows-msvc19.0.23918" +%struct.S = type { i8 } + $"\01??$fn_tmpl@H$1?bar@foo@@YAHH@Z@foo@@YAXXZ" = comdat any +$"??6S@@QAEXH@Z" = comdat any + ; Function Attrs: nounwind define i32 @"\01?bar@foo@@YAHH@Z"(i32 %x) #0 !dbg !6 { entry: @@ -49,6 +61,17 @@ ret void, !dbg !24 } +; Function Attrs: nounwind +define linkonce_odr void @"??6S@@QAEXH@Z"(%struct.S* nonnull dereferenceable(1) %this, i32 %i) #0 !dbg !31 { +entry: + %i.addr = alloca i32, align 4 + %this.addr = alloca %struct.S*, align 4 + store i32 %i, i32* %i.addr, align 4 + store %struct.S* %this, %struct.S** %this.addr, align 4 + %this1 = load %struct.S*, %struct.S** %this.addr, align 4 + ret void, !dbg !32 +} + attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { nounwind readnone } @@ -81,3 +104,11 @@ !22 = !DITemplateValueParameter(type: !23, value: i32 (i32)* @"\01?bar@foo@@YAHH@Z") !23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 32, align: 32) !24 = !DILocation(line: 4, column: 17, scope: !17) +!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !1, line: 7, size: 8, flags: DIFlagTypePassByValue, elements: !26, identifier: ".?AUS@@") +!26 = !{!27} +!27 = !DISubprogram(name: "operator<<", linkageName: "??6S@@QAEXH@Z", scope: !25, file: !1, line: 8, type: !28, scopeLine: 8, flags: DIFlagPrototyped, spFlags: 0) +!28 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !29) +!29 = !{null, !30, !10} +!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer) +!31 = distinct !DISubprogram(name: "operator<<", linkageName: "??6S@@QAEXH@Z", scope: !25, file: !1, line: 8, type: !28, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, declaration: !27, retainedNodes: !2) +!32 = !DILocation(line: 8, column: 27, scope: !31) \ No newline at end of file