]> granicus.if.org Git - clang/commitdiff
[DEBUG INFO] Emit debug info for type used in explicit cast only.
authorAlexey Bataev <a.bataev@hotmail.com>
Tue, 20 Oct 2015 04:24:12 +0000 (04:24 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Tue, 20 Oct 2015 04:24:12 +0000 (04:24 +0000)
Currently debug info for types used in explicit cast only is not emitted. It happened after a patch for better alignment handling. This patch fixes this bug.
Differential Revision: http://reviews.llvm.org/D13582

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@250795 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprCXX.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CodeGenModule.h
test/CodeGenCXX/debug-info-explicit-cast.cpp [new file with mode: 0644]

index ece83371db9473ab8e8e292fcfcddcc05a4b265c..f61f63470c7ab0486b8f4b31869001451ec59f8f 100644 (file)
@@ -780,6 +780,16 @@ EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
   return isPre ? IncVal : InVal;
 }
 
+void CodeGenModule::EmitExplicitCastExprType(const ExplicitCastExpr *E,
+                                             CodeGenFunction *CGF) {
+  // Bind VLAs in the cast type.
+  if (CGF && E->getType()->isVariablyModifiedType())
+    CGF->EmitVariablyModifiedType(E->getType());
+
+  if (CGDebugInfo *DI = getModuleDebugInfo())
+    DI->EmitExplicitCastType(E->getType());
+}
+
 //===----------------------------------------------------------------------===//
 //                         LValue Expression Emission
 //===----------------------------------------------------------------------===//
@@ -795,9 +805,8 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
 
   // Casts:
   if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
-    // Bind VLAs in the cast type.
-    if (E->getType()->isVariablyModifiedType())
-      EmitVariablyModifiedType(E->getType());
+    if (const auto *ECE = dyn_cast<ExplicitCastExpr>(CE))
+      CGM.EmitExplicitCastExprType(ECE, this);
 
     switch (CE->getCastKind()) {
     // Non-converting casts (but not C's implicit conversion from void*).
@@ -3427,6 +3436,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
     // This must be a reinterpret_cast (or c-style equivalent).
     const auto *CE = cast<ExplicitCastExpr>(E);
 
+    CGM.EmitExplicitCastExprType(CE, this);
     LValue LV = EmitLValue(E->getSubExpr());
     Address V = Builder.CreateBitCast(LV.getAddress(),
                                       ConvertType(CE->getTypeAsWritten()));
index a229d94ad9e1c0a3a37ad716b8158da27ad3d41d..906ffa4fb5402a39d17fed5de942c0d667650342 100644 (file)
@@ -571,6 +571,8 @@ static Expr *findPeephole(Expr *op, CastKind kind) {
 }
 
 void AggExprEmitter::VisitCastExpr(CastExpr *E) {
+  if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
+    CGF.CGM.EmitExplicitCastExprType(ECE, &CGF);
   switch (E->getCastKind()) {
   case CK_Dynamic: {
     // FIXME: Can this actually happen? We have no test coverage for it.
index 599dc9a8dbc3d211f2f50d07a6c746d54a352b18..ae4e02d53f057305302971a642c9fd720b499bc6 100644 (file)
@@ -1806,6 +1806,7 @@ static llvm::Value *EmitDynamicCastToNull(CodeGenFunction &CGF,
 
 llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
                                               const CXXDynamicCastExpr *DCE) {
+  CGM.EmitExplicitCastExprType(DCE, this);
   QualType DestTy = DCE->getTypeAsWritten();
 
   if (DCE->isAlwaysNull())
index 2f9d0cab249fcff484cb6f4edf80a4b87f568392..4b45bce098a864c37af15ac64b3318fdf648205a 100644 (file)
@@ -154,6 +154,8 @@ public:
     return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
   }
   ComplexPairTy VisitCastExpr(CastExpr *E) {
+    if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
+      CGF.CGM.EmitExplicitCastExprType(ECE, &CGF);
     return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
   }
   ComplexPairTy VisitCallExpr(const CallExpr *E);
index 1f4b1dcbe02fa2703090d0f4a033e95151bd75f1..bbd04dd751485a61129778d2502550200bc00347 100644 (file)
@@ -636,6 +636,8 @@ public:
   }
 
   llvm::Constant *VisitCastExpr(CastExpr* E) {
+    if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
+      CGM.EmitExplicitCastExprType(ECE, CGF);
     Expr *subExpr = E->getSubExpr();
     llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF);
     if (!C) return nullptr;
index 6a40e4ed86f682078b603a40dc77ac9096022027..602ce4bf5ef9702c2e85624d4c97f8c257c15f80 100644 (file)
@@ -314,12 +314,7 @@ public:
     return EmitNullValue(E->getType());
   }
   Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
-    if (E->getType()->isVariablyModifiedType())
-      CGF.EmitVariablyModifiedType(E->getType());
-
-    if (CGDebugInfo *DI = CGF.getDebugInfo())
-      DI->EmitExplicitCastType(E->getType());
-
+    CGF.CGM.EmitExplicitCastExprType(E, &CGF);
     return VisitCastExpr(E);
   }
   Value *VisitCastExpr(CastExpr *E);
index c188789a502ae9bebcd865e4522de07a07cd348a..eac5c8ee8d1a335e446bbb1636d98f6d3d76a090 100644 (file)
@@ -921,6 +921,11 @@ public:
                                              QualType DestType,
                                              CodeGenFunction *CGF = nullptr);
 
+  /// \brief Emit type info if type of an expression is a variably modified
+  /// type. Also emit proper debug info for cast types.
+  void EmitExplicitCastExprType(const ExplicitCastExpr *E,
+                                CodeGenFunction *CGF = nullptr);
+
   /// Return the result of value-initializing the given type, i.e. a null
   /// expression of the given type.  This is usually, but not always, an LLVM
   /// null constant.
diff --git a/test/CodeGenCXX/debug-info-explicit-cast.cpp b/test/CodeGenCXX/debug-info-explicit-cast.cpp
new file mode 100644 (file)
index 0000000..028a776
--- /dev/null
@@ -0,0 +1,46 @@
+// RUN: %clangxx -c -target %itanium_abi_triple -g %s -emit-llvm -S -o - | FileCheck %s
+// RUN: %clangxx -c -target %ms_abi_triple -g %s -emit-llvm -S -o - | FileCheck %s
+
+struct Foo {
+  int A;
+  Foo() : A(1){};
+};
+
+struct Bar {
+  int B;
+  Bar() : B(2){};
+};
+
+struct Baz {
+  int C;
+  Baz() : C(3){};
+};
+
+struct Qux {
+  int d() { return 4; }
+  Qux() {};
+};
+
+struct Quux {
+  int E;
+  Quux() : E(5){};
+};
+
+typedef int(Qux::*TD)();
+typedef int(Qux::*TD1)();
+int Val = reinterpret_cast<Baz *>(0)->C;
+int main() {
+  Bar *PB = new Bar;
+  TD d = &Qux::d;
+  (void)reinterpret_cast<TD1>(d);
+
+  return reinterpret_cast<Foo *>(PB)->A + reinterpret_cast<Quux *>(0)->E;
+}
+
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Foo",
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Bar",
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Baz",
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Qux",
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Quux",
+// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "TD",
+// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "TD1",