Patch #1: Suppress debug info associated with the body of an
artificial method. We already suppress debug info for its declaration
inside the class description.
Fixes PR14097.

Patch #2: Suppress debug info for the declaration of a class method
marked __attribute__((nodebug)). We already suppress debug info for
the body of the method.

Here's the story:
r158009 suppressed debug-info entries for artificial (compiler
generated) methods, typically constructors and destructors, from the
debug info for a class. The idea is that these aren't interesting or
useful. Which is pretty much true.

Unfortunately, the method _definitions_ still get debug info, and if
there's no declaration in the class for it to refer to, Clang
spontaneously generates debug info for a declaration.  If a ctor has
multiple definitions, which they sometimes do (e.g. when there's a
virtual base class), each instance produces its own separate
declaration.  And so the total debug info size _increases_. Patch #1
suppresses debug-info on the definitions as well.

While finding the fix, I noticed that the 'nodebug' attribute will
suppress debug info for a method definition, but we don't suppress
debug info for the corresponding declaration inside a class. 
(Non-class functions don't have this problem because Clang doesn't
emit debug info for a function declaration anyway.)  Patch #2
addresses that oversight.

I renamed the Sema and CodeGen tests for the 'nodebug' attribute from
.c to .cpp and added test points for methods, rather than add whole
new test files. Hope that's okay.

--paulr
Index: clang/test/CodeGenCXX/debug-info-user-def.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-user-def.cpp       (revision 165971)
+++ clang/test/CodeGenCXX/debug-info-user-def.cpp       (working copy)
@@ -1,14 +1,23 @@
 // RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin -std=c++11 %s -o 
- | FileCheck %s
 
 class A {
+  virtual void foo(); // Force a nontrivial artificial constructor.
 };
 
 template <typename T> class B {
   T t;
 };
 
-A a;
-B<int> b;
+// Need to instantiate the ctors and prove the debug info is not there.
+int main() {
+  A a;
+  B<A> b;
+  return 0;
+}
 
-// Check that no subprograms are emitted into debug info.
-// CHECK-NOT: [ DW_TAG_subprogram ]
+// We should see subprogram entries for main() and foo() only.
+// CHECK-NOT: DW_TAG_subprogram
+// CHECK:     DW_TAG_subprogram {{.*}} [main]
+// CHECK-NOT: DW_TAG_subprogram
+// CHECK:     DW_TAG_subprogram {{.*}} [foo]
+// CHECK-NOT: DW_TAG_subprogram
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp       (revision 165971)
+++ clang/lib/CodeGen/CodeGenFunction.cpp       (working copy)
@@ -493,7 +493,9 @@
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
   
   // Check if we should generate debug info for this function.
-  if (CGM.getModuleDebugInfo() && !FD->hasAttr<NoDebugAttr>())
+  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
+  if (CGM.getModuleDebugInfo() && !FD->hasAttr<NoDebugAttr>() &&
+      (!MD || MD->isUserProvided()))
     DebugInfo = CGM.getModuleDebugInfo();
 
   FunctionArgList Args;
Index: clang/test/Sema/attr-nodebug.c
===================================================================
--- clang/test/Sema/attr-nodebug.c      (revision 165971)
+++ clang/test/Sema/attr-nodebug.c      (working copy)
@@ -1,11 +0,0 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
-
-int a __attribute__((nodebug));
-
-void b() {
-  int b __attribute__((nodebug)); // expected-warning {{'nodebug' only applies 
to variables with static storage duration and functions}}
-} 
-
-void t1() __attribute__((nodebug));
-
-void t2() __attribute__((nodebug(2))); // expected-error {{attribute takes no 
arguments}}
Index: clang/test/Sema/attr-nodebug.cpp
===================================================================
--- clang/test/Sema/attr-nodebug.cpp    (revision 165971)
+++ clang/test/Sema/attr-nodebug.cpp    (working copy)
@@ -9,3 +9,7 @@
 void t1() __attribute__((nodebug));
 
 void t2() __attribute__((nodebug(2))); // expected-error {{attribute takes no 
arguments}}
+
+class c {
+  void t3() __attribute__((nodebug));
+};
Index: clang/test/CodeGen/attr-nodebug.cpp
===================================================================
--- clang/test/CodeGen/attr-nodebug.cpp (revision 165971)
+++ clang/test/CodeGen/attr-nodebug.cpp (working copy)
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -g -emit-llvm -o %t %s
-// RUN: not grep 'call void @llvm.dbg.func.start' %t
+// RUN: %clang_cc1 -g -emit-llvm %s -o - | FileCheck %s
+// CHECK-NOT: call void @llvm.dbg.func.start
+// CHECK-NOT: DW_TAG_subprogram
 
 void t1() __attribute__((nodebug));
 
@@ -10,3 +11,14 @@
   a++;
 }
 
+class C {
+  void t2() __attribute__((nodebug));
+};
+
+void C::t2()
+{
+  int a = 10;
+  a++;
+}
+
+C obj;
Index: clang/test/CodeGen/attr-nodebug.c
===================================================================
--- clang/test/CodeGen/attr-nodebug.c   (revision 165971)
+++ clang/test/CodeGen/attr-nodebug.c   (working copy)
@@ -1,12 +0,0 @@
-// RUN: %clang_cc1 -g -emit-llvm -o %t %s
-// RUN: not grep 'call void @llvm.dbg.func.start' %t
-
-void t1() __attribute__((nodebug));
-
-void t1()
-{
-  int a = 10;
-  
-  a++;
-}
-
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp   (revision 165971)
+++ clang/lib/CodeGen/CGDebugInfo.cpp   (working copy)
@@ -1024,9 +1024,9 @@
       continue;
 
     if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
-      // Only emit debug information for user provided functions, we're
-      // unlikely to want info for artificial functions.
-      if (Method->isUserProvided())
+      // Only emit debug information for user provided functions
+      // not marked with 'nodebug'. No artificial functions.
+      if (Method->isUserProvided() && !Method->hasAttr<NoDebugAttr>())
         EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
     }
     else if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to