[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

llvm-svn: 250795
This commit is contained in:
Alexey Bataev 2015-10-20 04:24:12 +00:00
parent 8f18917a90
commit 2bf9b4c0d1
8 changed files with 72 additions and 9 deletions

View File

@ -780,6 +780,16 @@ EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
return isPre ? IncVal : InVal; 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 // LValue Expression Emission
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -795,9 +805,8 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
// Casts: // Casts:
if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
// Bind VLAs in the cast type. if (const auto *ECE = dyn_cast<ExplicitCastExpr>(CE))
if (E->getType()->isVariablyModifiedType()) CGM.EmitExplicitCastExprType(ECE, this);
EmitVariablyModifiedType(E->getType());
switch (CE->getCastKind()) { switch (CE->getCastKind()) {
// Non-converting casts (but not C's implicit conversion from void*). // 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). // This must be a reinterpret_cast (or c-style equivalent).
const auto *CE = cast<ExplicitCastExpr>(E); const auto *CE = cast<ExplicitCastExpr>(E);
CGM.EmitExplicitCastExprType(CE, this);
LValue LV = EmitLValue(E->getSubExpr()); LValue LV = EmitLValue(E->getSubExpr());
Address V = Builder.CreateBitCast(LV.getAddress(), Address V = Builder.CreateBitCast(LV.getAddress(),
ConvertType(CE->getTypeAsWritten())); ConvertType(CE->getTypeAsWritten()));

View File

@ -571,6 +571,8 @@ static Expr *findPeephole(Expr *op, CastKind kind) {
} }
void AggExprEmitter::VisitCastExpr(CastExpr *E) { void AggExprEmitter::VisitCastExpr(CastExpr *E) {
if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
CGF.CGM.EmitExplicitCastExprType(ECE, &CGF);
switch (E->getCastKind()) { switch (E->getCastKind()) {
case CK_Dynamic: { case CK_Dynamic: {
// FIXME: Can this actually happen? We have no test coverage for it. // FIXME: Can this actually happen? We have no test coverage for it.

View File

@ -1806,6 +1806,7 @@ static llvm::Value *EmitDynamicCastToNull(CodeGenFunction &CGF,
llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr, llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
const CXXDynamicCastExpr *DCE) { const CXXDynamicCastExpr *DCE) {
CGM.EmitExplicitCastExprType(DCE, this);
QualType DestTy = DCE->getTypeAsWritten(); QualType DestTy = DCE->getTypeAsWritten();
if (DCE->isAlwaysNull()) if (DCE->isAlwaysNull())

View File

@ -154,6 +154,8 @@ public:
return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
} }
ComplexPairTy VisitCastExpr(CastExpr *E) { 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()); return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
} }
ComplexPairTy VisitCallExpr(const CallExpr *E); ComplexPairTy VisitCallExpr(const CallExpr *E);

View File

@ -636,6 +636,8 @@ public:
} }
llvm::Constant *VisitCastExpr(CastExpr* E) { llvm::Constant *VisitCastExpr(CastExpr* E) {
if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
CGM.EmitExplicitCastExprType(ECE, CGF);
Expr *subExpr = E->getSubExpr(); Expr *subExpr = E->getSubExpr();
llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF); llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF);
if (!C) return nullptr; if (!C) return nullptr;

View File

@ -314,12 +314,7 @@ public:
return EmitNullValue(E->getType()); return EmitNullValue(E->getType());
} }
Value *VisitExplicitCastExpr(ExplicitCastExpr *E) { Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
if (E->getType()->isVariablyModifiedType()) CGF.CGM.EmitExplicitCastExprType(E, &CGF);
CGF.EmitVariablyModifiedType(E->getType());
if (CGDebugInfo *DI = CGF.getDebugInfo())
DI->EmitExplicitCastType(E->getType());
return VisitCastExpr(E); return VisitCastExpr(E);
} }
Value *VisitCastExpr(CastExpr *E); Value *VisitCastExpr(CastExpr *E);

View File

@ -921,6 +921,11 @@ public:
QualType DestType, QualType DestType,
CodeGenFunction *CGF = nullptr); 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 /// 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 /// expression of the given type. This is usually, but not always, an LLVM
/// null constant. /// null constant.

View File

@ -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",