akhuang updated this revision to Diff 294149.
akhuang added a comment.

Add to comment for lambdas.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87808/new/

https://reviews.llvm.org/D87808

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/test/CodeGenCXX/debug-info-limited-ctor.cpp


Index: clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
+++ clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
@@ -20,14 +20,56 @@
 };
 D::D() {}
 
+// Test for constexpr constructor.
 // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"E"{{.*}}DIFlagTypePassByValue
 struct E {
   constexpr E(){};
 } TestE;
 
+// Test for trivial constructor.
 // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"F"{{.*}}DIFlagTypePassByValue
 struct F {
   F() = default;
   F(int) {}
   int i;
 } TestF;
+
+// Test for trivial constructor.
+// CHECK-DAG: ![[G:.*]] ={{.*}}!DICompositeType({{.*}}name: 
"G"{{.*}}DIFlagTypePassByValue
+// CHECK-DAG: !DICompositeType({{.*}}scope: ![[G]], {{.*}}DIFlagTypePassByValue
+struct G {
+  G() : g_(0) {}
+  struct {
+    int g_;
+  };
+} TestG;
+
+// Test for an aggregate class with an implicit non-trivial default constructor
+// that is not instantiated.
+// CHECK-DAG: !DICompositeType({{.*}}name: "H",{{.*}}DIFlagTypePassByValue
+struct H {
+  B b;
+};
+void f(H h) {}
+
+// Test for an aggregate class with an implicit non-trivial default constructor
+// that is instantiated.
+// CHECK-DAG: !DICompositeType({{.*}}name: "J",{{.*}}DIFlagTypePassByValue
+struct J {
+  B b;
+};
+void f(decltype(J()) j) {}
+
+// Test for a class with trivial default constructor that is not instantiated.
+// CHECK-DAG: !DICompositeType({{.*}}name: "K",{{.*}}DIFlagTypePassByValue
+class K {
+  int i;
+};
+void f(K k) {}
+
+// Test that we don't use constructor homing on lambdas.
+// CHECK-DAG: ![[L:.*]] ={{.*}}!DISubprogram({{.*}}name: "L"
+// CHECK-DAG: !DICompositeType({{.*}}scope: ![[L]], {{.*}}DIFlagTypePassByValue
+void L() {
+  auto func = [&]() {};
+}
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2281,22 +2281,20 @@
 }
 
 static bool canUseCtorHoming(const CXXRecordDecl *RD) {
-  // Constructor homing can be used for classes that have at least one
-  // constructor and have no trivial or constexpr constructors.
+  // Constructor homing can be used for classes that cannnot be constructed
+  // without emitting code for one of their constructors. This is classes that
+  // don't have trivial or constexpr constructors, or can be created from
+  // aggregate initialization. Also skip lambda objects because they don't call
+  // constructors.
+
   // Skip this optimization if the class or any of its methods are marked
   // dllimport.
-  if (RD->isLambda() || RD->hasConstexprNonCopyMoveConstructor() ||
-      isClassOrMethodDLLImport(RD))
-    return false;
-
-  if (RD->ctors().empty())
+  if (isClassOrMethodDLLImport(RD))
     return false;
 
-  for (const auto *Ctor : RD->ctors())
-    if (Ctor->isTrivial() && !Ctor->isCopyOrMoveConstructor())
-      return false;
-
-  return true;
+  return !RD->isLambda() && !RD->isAggregate() &&
+         !RD->hasTrivialDefaultConstructor() &&
+         !RD->hasConstexprNonCopyMoveConstructor();
 }
 
 static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,


Index: clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
+++ clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
@@ -20,14 +20,56 @@
 };
 D::D() {}
 
+// Test for constexpr constructor.
 // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "E"{{.*}}DIFlagTypePassByValue
 struct E {
   constexpr E(){};
 } TestE;
 
+// Test for trivial constructor.
 // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "F"{{.*}}DIFlagTypePassByValue
 struct F {
   F() = default;
   F(int) {}
   int i;
 } TestF;
+
+// Test for trivial constructor.
+// CHECK-DAG: ![[G:.*]] ={{.*}}!DICompositeType({{.*}}name: "G"{{.*}}DIFlagTypePassByValue
+// CHECK-DAG: !DICompositeType({{.*}}scope: ![[G]], {{.*}}DIFlagTypePassByValue
+struct G {
+  G() : g_(0) {}
+  struct {
+    int g_;
+  };
+} TestG;
+
+// Test for an aggregate class with an implicit non-trivial default constructor
+// that is not instantiated.
+// CHECK-DAG: !DICompositeType({{.*}}name: "H",{{.*}}DIFlagTypePassByValue
+struct H {
+  B b;
+};
+void f(H h) {}
+
+// Test for an aggregate class with an implicit non-trivial default constructor
+// that is instantiated.
+// CHECK-DAG: !DICompositeType({{.*}}name: "J",{{.*}}DIFlagTypePassByValue
+struct J {
+  B b;
+};
+void f(decltype(J()) j) {}
+
+// Test for a class with trivial default constructor that is not instantiated.
+// CHECK-DAG: !DICompositeType({{.*}}name: "K",{{.*}}DIFlagTypePassByValue
+class K {
+  int i;
+};
+void f(K k) {}
+
+// Test that we don't use constructor homing on lambdas.
+// CHECK-DAG: ![[L:.*]] ={{.*}}!DISubprogram({{.*}}name: "L"
+// CHECK-DAG: !DICompositeType({{.*}}scope: ![[L]], {{.*}}DIFlagTypePassByValue
+void L() {
+  auto func = [&]() {};
+}
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2281,22 +2281,20 @@
 }
 
 static bool canUseCtorHoming(const CXXRecordDecl *RD) {
-  // Constructor homing can be used for classes that have at least one
-  // constructor and have no trivial or constexpr constructors.
+  // Constructor homing can be used for classes that cannnot be constructed
+  // without emitting code for one of their constructors. This is classes that
+  // don't have trivial or constexpr constructors, or can be created from
+  // aggregate initialization. Also skip lambda objects because they don't call
+  // constructors.
+
   // Skip this optimization if the class or any of its methods are marked
   // dllimport.
-  if (RD->isLambda() || RD->hasConstexprNonCopyMoveConstructor() ||
-      isClassOrMethodDLLImport(RD))
-    return false;
-
-  if (RD->ctors().empty())
+  if (isClassOrMethodDLLImport(RD))
     return false;
 
-  for (const auto *Ctor : RD->ctors())
-    if (Ctor->isTrivial() && !Ctor->isCopyOrMoveConstructor())
-      return false;
-
-  return true;
+  return !RD->isLambda() && !RD->isAggregate() &&
+         !RD->hasTrivialDefaultConstructor() &&
+         !RD->hasConstexprNonCopyMoveConstructor();
 }
 
 static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to