akhuang created this revision.
akhuang added reviewers: rnk, dblaikie.
Herald added a subscriber: hiraditya.
akhuang requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.

Previously we emitted the fully qualified name when using
line-tables-only; this change adds the function arguments for
the current function (as opposed to only the functions in the
scope), and lambda id.

This increases the object file and PDB sizes by quite a bit, partly
because we're storing longer names and partly because there are more
LF_FUNC_IDs now.

This change also removes a bit of code that truncates the display name
at the first '<', because it truncates qualified names too early.

  Obj files | PDB

--------------------------

Before |  833 MB | 397 MB
After  | 1074 MB | 538 MB

Bug: https://bugs.llvm.org/show_bug.cgi?id=48432


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94325

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/MicrosoftMangle.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp
  llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
  llvm/test/DebugInfo/COFF/function-display-name.ll

Index: llvm/test/DebugInfo/COFF/function-display-name.ll
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/COFF/function-display-name.ll
@@ -0,0 +1,51 @@
+; RUN: llc -mtriple=i686-pc-win32 -o - -O0 -filetype=obj < %s \
+; RUN:   | llvm-readobj --codeview - | FileCheck %s
+
+; Check that we removed templated args from the display name in full debug mode
+; but not with line tables only.
+
+; CHECK:       FuncId (0x1002) {
+; CHECK-NEXT:    TypeLeafKind: LF_FUNC_ID ({{.*}})
+; CHECK-NEXT:    ParentScope: 0x0
+; CHECK-NEXT:    FunctionType: void () ({{.*}})
+; CHECK-NEXT:    Name: Test()<int>
+
+; CHECK:       FuncId (0x1003) {
+; CHECK-NEXT:    TypeLeafKind: LF_FUNC_ID ({{.*}})
+; CHECK-NEXT:    ParentScope: 0x0
+; CHECK-NEXT:    FunctionType: void () ({{.*}})
+; CHECK-NEXT:    Name: Test
+
+; ModuleID = 't.cpp'
+source_filename = "t.cpp"
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define i32 @"?Test1"() !dbg !7 {
+entry:
+  ret i32 0, !dbg !10
+}
+
+define i32 @"?Test2"() !dbg !13 {
+entry:
+  ret i32 0, !dbg !12
+}
+
+!llvm.dbg.cu = !{!0, !11}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git b93410cbeaa48fec9a15a23e4770be10abc04d4e)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "<stdin>", directory: "C:\\src\\tests", checksumkind: CSK_MD5, checksum: "a28f11090424d4b37acdde65a98985a1")
+!2 = !{}
+!3 = !{i32 2, !"CodeView", i32 1}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 2}
+!6 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git b93410cbeaa48fec9a15a23e4770be10abc04d4e)"}
+!7 = distinct !DISubprogram(name: "Test()<int>", scope: !8, file: !8, line: 19, type: !9, scopeLine: 19, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+!8 = !DIFile(filename: "t.cpp", directory: "C:\\src\\tests", checksumkind: CSK_MD5, checksum: "a28f11090424d4b37acdde65a98985a1")
+!9 = !DISubroutineType(types: !2)
+!10 = !DILocation(line: 25, column: 3, scope: !7)
+!11 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!12 = !DILocation(line: 0, column: 0, scope: !13)
+!13 = distinct !DISubprogram(name: "Test<int>", scope: !8, file: !8, line: 1, type: !9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !11, retainedNodes: !2)
Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -366,9 +366,12 @@
   if (I != TypeIndices.end())
     return I->second;
 
+  StringRef DisplayName = SP->getName();
+
   // The display name includes function template arguments. Drop them to match
-  // MSVC.
-  StringRef DisplayName = SP->getName().split('<').first;
+  // MSVC, if we're not using line tables only.
+  if (SP->getUnit()->getEmissionKind() != DICompileUnit::LineTablesOnly)
+    DisplayName = SP->getName().split('<').first;
 
   const DIScope *Scope = SP->getScope();
   TypeIndex TI;
Index: clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp
+++ clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp
@@ -1,59 +1,64 @@
 // RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s \
 // RUN:       -o - -triple=x86_64-pc-win32 -Wno-new-returns-null -std=c++98 | \
 // RUN:    grep -E 'DISubprogram|DICompositeType' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
-// RUN:    FileCheck %s --check-prefix=CHECK --check-prefix=UNQUAL
+// RUN:    FileCheck %s --check-prefixes=CHECK,UNQUAL
 // RUN: %clang_cc1 -fblocks -debug-info-kind=line-tables-only -gcodeview -emit-llvm %s \
 // RUN:       -o - -triple=x86_64-pc-win32 -Wno-new-returns-null -std=c++98 | \
 // RUN:    grep 'DISubprogram' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
-// RUN:    FileCheck %s --check-prefix=CHECK --check-prefix=QUAL
+// RUN:    FileCheck %s --check-prefixes=CHECK,QUAL
 // RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s \
 // RUN:       -o - -triple=x86_64-pc-win32 -Wno-new-returns-null -std=c++11 | \
 // RUN:    grep -E 'DISubprogram|DICompositeType' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
-// RUN:    FileCheck %s --check-prefix=CHECK --check-prefix=UNQUAL
+// RUN:    FileCheck %s --check-prefixes=CHECK,UNQUAL,UNQUAL11
+// RUN: %clang_cc1 -fblocks -debug-info-kind=line-tables-only -gcodeview -emit-llvm %s \
+// RUN:       -o - -triple=x86_64-pc-win32 -Wno-new-returns-null -std=c++11 | \
+// RUN:    grep -E 'DISubprogram|DICompositeType' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
+// RUN:    FileCheck %s --check-prefixes=CHECK,QUAL,QUAL11
 // RUN: %clang_cc1 -fblocks -debug-info-kind=limited -gcodeview -emit-llvm %s \
 // RUN:       -o - -triple=x86_64-pc-win32 -Wno-new-returns-null | \
 // RUN:    grep -E 'DISubprogram|DICompositeType' | sed -e 's/.*name: "\([^"]*\)".*/"\1"/' | \
-// RUN:    FileCheck %s --check-prefix=CHECK --check-prefix=UNQUAL
+// RUN:    FileCheck %s --check-prefixes=CHECK,UNQUAL
 
 void freefunc() { }
-// CHECK-DAG: "freefunc"
+// UNQUAL-DAG: "freefunc"
+// QUAL-DAG: "freefunc()"
 
 namespace N {
   int b() { return 0; }
-// UNQUAL-DAG: "b"
-// QUAL-DAG: "N::b"
+  // UNQUAL-DAG: "b"
+  // QUAL-DAG: "N::b()"
   namespace { void func() { } }
-// UNQUAL-DAG: "func"
-// QUAL-DAG: "N::`anonymous namespace'::func"
+  // UNQUAL-DAG: "func"
+  // QUAL-DAG: "N::`anonymous namespace'::func()"
 }
 
 void _c(void) {
   N::func();
 }
-// CHECK-DAG: "_c"
+// UNQUAL-DAG: "_c"
+// QUAL-DAG: "_c()"
 
 struct foo {
   int operator+(int);
   foo(){}
-// UNQUAL-DAG: "foo"
-// QUAL-DAG: "foo::foo"
+  // UNQUAL-DAG: "foo"
+  // QUAL-DAG: "foo::foo()"
 
   ~foo(){}
-// UNQUAL-DAG: "~foo"
-// QUAL-DAG: "foo::~foo"
+  // UNQUAL-DAG: "~foo"
+  // QUAL-DAG: "foo::~foo()"
 
   foo(int i){}
-// UNQUAL-DAG: "foo"
-// QUAL-DAG: "foo::foo"
+  // UNQUAL-DAG: "foo"
+  // QUAL-DAG: "foo::foo(int)"
 
   foo(char *q){}
-// UNQUAL-DAG: "foo"
-// QUAL-DAG: "foo::foo"
+  // UNQUAL-DAG: "foo"
+  // QUAL-DAG: "foo::foo(char *)"
 
   static foo* static_method() { return 0; }
-// UNQUAL-DAG: "static_method"
-// QUAL-DAG: "foo::static_method"
-
+  // UNQUAL-DAG: "static_method"
+  // QUAL-DAG: "foo::static_method()"
 };
 
 void use_foo() {
@@ -62,7 +67,7 @@
 }
 
 // UNQUAL-DAG: "operator+"
-// QUAL-DAG: "foo::operator+"
+// QUAL-DAG: "foo::operator+(int)"
 int foo::operator+(int a) { return a; }
 
 // PR17371
@@ -87,18 +92,18 @@
 // UNQUAL-DAG: "operator delete"
 // UNQUAL-DAG: "operator delete[]"
 // UNQUAL-DAG: "operator+"
-// QUAL-DAG: "OverloadedNewDelete::operator new"
-// QUAL-DAG: "OverloadedNewDelete::operator new[]"
-// QUAL-DAG: "OverloadedNewDelete::operator delete"
-// QUAL-DAG: "OverloadedNewDelete::operator delete[]"
-// QUAL-DAG: "OverloadedNewDelete::operator+"
-
+// QUAL-DAG: "OverloadedNewDelete::operator new(unsigned long long)"
+// QUAL-DAG: "OverloadedNewDelete::operator new[](unsigned long long)"
+// QUAL-DAG: "OverloadedNewDelete::operator delete(void *)"
+// QUAL-DAG: "OverloadedNewDelete::operator delete[](void *)"
+// QUAL-DAG: "OverloadedNewDelete::operator+(int)"
 
 template <typename T, void (*)(void)>
 void fn_tmpl() {}
 
 template void fn_tmpl<int, freefunc>();
-// CHECK-DAG: "fn_tmpl<int,&freefunc>"
+// UNQUAL-DAG: "fn_tmpl<int,&freefunc>"
+// QUAL-DAG: "fn_tmpl()<int,&freefunc>"
 
 template <typename A, typename B, typename C> struct ClassTemplate { A a; B b; C c; };
 ClassTemplate<char, short, ClassTemplate<int, int, int> > f;
@@ -106,3 +111,15 @@
 // important for compatibility with Windows debuggers, so it should always be
 // there when generating CodeView.
 // UNQUAL-DAG: "ClassTemplate<char,short,ClassTemplate<int,int,int> >"
+
+#if __cplusplus >= 201103L
+void test_lambda() {
+  int a = [](int x) { return x + 1; }(0);
+  int b = [](int x) { return x * 2; }(0);
+}
+
+// UNQUAL11-DAG: "operator()"
+// UNQUAL11-DAG: "operator()"
+// QUAL11-DAG: "test_lambda()::(anonymous class)::operator()::<lambda_0>
+// QUAL11-DAG: "test_lambda()::(anonymous class)::operator()::<lambda_1>
+#endif
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -262,7 +262,6 @@
   // evaluating the size impact.
   bool UseQualifiedName = DebugKind == codegenoptions::DebugLineTablesOnly &&
                           CGM.getCodeGenOpts().EmitCodeView;
-
   if (!Info && FII && !UseQualifiedName)
     return FII->getName();
 
@@ -270,8 +269,32 @@
   llvm::raw_svector_ostream OS(NS);
   if (!UseQualifiedName)
     FD->printName(OS);
-  else
+  else {
     FD->printQualifiedName(OS, getPrintingPolicy());
+    const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD);
+    bool isLambda = false;
+    if (Method && Method->getParent()->isLambda()) {
+      MangleContext &MC = CGM.getCXXABI().getMangleContext();
+      if (auto *MMC = dyn_cast<MicrosoftMangleContext>(&MC)) {
+        unsigned LambdaNumber = MMC->getLambdaNumber(Method->getParent());
+        OS << "::<lambda_" << LambdaNumber << ">";
+        isLambda = true;
+      }
+    } else {
+      OS << '(';
+      unsigned NumParams = FD->getNumParams();
+      for (unsigned i = 0; i < NumParams; ++i) {
+        if (i)
+          OS << ", ";
+        OS << FD->getParamDecl(i)->getType().stream(getPrintingPolicy());
+      }
+      OS << ')';
+
+      if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD))
+        if (Method->isConst())
+          OS << " const";
+    }
+  }
 
   // Add any template specialization args.
   if (Info) {
Index: clang/lib/AST/MicrosoftMangle.cpp
===================================================================
--- clang/lib/AST/MicrosoftMangle.cpp
+++ clang/lib/AST/MicrosoftMangle.cpp
@@ -228,6 +228,18 @@
     return true;
   }
 
+  unsigned getLambdaNumber(const CXXRecordDecl *Lambda) override {
+    unsigned LambdaManglingNumber = Lambda->getLambdaManglingNumber();
+    unsigned LambdaId;
+
+    if (LambdaManglingNumber)
+      LambdaId = LambdaManglingNumber;
+    else
+      LambdaId = getLambdaId(Lambda);
+
+    return LambdaId;
+  }
+
   unsigned getLambdaId(const CXXRecordDecl *RD) {
     assert(RD->isLambda() && "RD must be a lambda!");
     assert(!RD->isExternallyVisible() && "RD must not be visible!");
Index: clang/include/clang/AST/Mangle.h
===================================================================
--- clang/include/clang/AST/Mangle.h
+++ clang/include/clang/AST/Mangle.h
@@ -241,6 +241,8 @@
                                      ArrayRef<const CXXRecordDecl *> BasePath,
                                      raw_ostream &Out) = 0;
 
+  virtual unsigned getLambdaNumber(const CXXRecordDecl *Lambda) = 0;
+
   static bool classof(const MangleContext *C) {
     return C->getKind() == MK_Microsoft;
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D94325: [DebugInfo][... Amy Huang via Phabricator via cfe-commits

Reply via email to