From: Alexey Bataev Date: Tue, 20 Oct 2015 04:24:12 +0000 (+0000) Subject: [DEBUG INFO] Emit debug info for type used in explicit cast only. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3490ab8630d5643f71f1f04e46984f05b27b8d67;p=clang [DEBUG INFO] Emit debug info for type used in explicit cast only. 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 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index ece83371db..f61f63470c 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -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(E)) { - // Bind VLAs in the cast type. - if (E->getType()->isVariablyModifiedType()) - EmitVariablyModifiedType(E->getType()); + if (const auto *ECE = dyn_cast(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(E); + CGM.EmitExplicitCastExprType(CE, this); LValue LV = EmitLValue(E->getSubExpr()); Address V = Builder.CreateBitCast(LV.getAddress(), ConvertType(CE->getTypeAsWritten())); diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index a229d94ad9..906ffa4fb5 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -571,6 +571,8 @@ static Expr *findPeephole(Expr *op, CastKind kind) { } void AggExprEmitter::VisitCastExpr(CastExpr *E) { + if (const auto *ECE = dyn_cast(E)) + CGF.CGM.EmitExplicitCastExprType(ECE, &CGF); switch (E->getCastKind()) { case CK_Dynamic: { // FIXME: Can this actually happen? We have no test coverage for it. diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 599dc9a8db..ae4e02d53f 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -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()) diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 2f9d0cab24..4b45bce098 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -154,6 +154,8 @@ public: return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); } ComplexPairTy VisitCastExpr(CastExpr *E) { + if (const auto *ECE = dyn_cast(E)) + CGF.CGM.EmitExplicitCastExprType(ECE, &CGF); return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); } ComplexPairTy VisitCallExpr(const CallExpr *E); diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 1f4b1dcbe0..bbd04dd751 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -636,6 +636,8 @@ public: } llvm::Constant *VisitCastExpr(CastExpr* E) { + if (const auto *ECE = dyn_cast(E)) + CGM.EmitExplicitCastExprType(ECE, CGF); Expr *subExpr = E->getSubExpr(); llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF); if (!C) return nullptr; diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 6a40e4ed86..602ce4bf5e 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -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); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index c188789a50..eac5c8ee8d 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -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 index 0000000000..028a7760d8 --- /dev/null +++ b/test/CodeGenCXX/debug-info-explicit-cast.cpp @@ -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(0)->C; +int main() { + Bar *PB = new Bar; + TD d = &Qux::d; + (void)reinterpret_cast(d); + + return reinterpret_cast(PB)->A + reinterpret_cast(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",