Index: llvm/tools/clang/lib/CodeGen/CGDebugInfo.h =================================================================== --- llvm/tools/clang/lib/CodeGen/CGDebugInfo.h +++ llvm/tools/clang/lib/CodeGen/CGDebugInfo.h @@ -283,6 +283,9 @@ /// \brief - Emit C++ using directive. void EmitUsingDirective(const UsingDirectiveDecl &UD); + /// EmitExplicitCastType - Emit the type explicitly casted to. + void EmitExplicitCastType(QualType Ty); + /// \brief - Emit C++ using declaration. void EmitUsingDecl(const UsingDecl &UD); Index: llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp +++ llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3347,3 +3347,11 @@ DBuilder.finalize(); } + +void CGDebugInfo::EmitExplicitCastType(QualType Ty) { + if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) + return; + llvm::DIType DieTy = getOrCreateType(Ty, getOrCreateMainFile()); + // Don't ignore in case of explicit cast where it is referenced indirectly. + DBuilder.retainType(DieTy); +} Index: llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp =================================================================== --- llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp +++ llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp @@ -274,6 +274,10 @@ Value *VisitExplicitCastExpr(ExplicitCastExpr *E) { if (E->getType()->isVariablyModifiedType()) CGF.EmitVariablyModifiedType(E->getType()); + + if (CGDebugInfo *DI = CGF.getDebugInfo()) + DI->EmitExplicitCastType(E->getType()); + return VisitCastExpr(E); } Value *VisitCastExpr(CastExpr *E); Index: llvm/tools/clang/test/CodeGen/Debug-info-explicitcast.c =================================================================== --- llvm/tools/clang/test/CodeGen/Debug-info-explicitcast.c +++ llvm/tools/clang/test/CodeGen/Debug-info-explicitcast.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s + +typedef struct S { int i; } *T; + + +void foo(void *p) { ((T)(p))->i++; } +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, null, metadata !"T", i32 3, i64 0, i64 0, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_typedef ] [T] [line 3, size 0, align 0, offset 0] [from ] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, null, metadata !"S", i32 3, i64 32, i64 32, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, null, null} ; [ DW_TAG_structure_type ] [S] [line 3, size 32, align 32, offset 0] [def] [from ] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, metadata !{{.*}}, metadata !"i", i32 3, i64 32, i64 32, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_member ] [i] [line 3, size 32, align 32, offset 0] [from int] + +typedef struct S1 { int i; } T1; +void foo1(T1 *p) { p->i++; } + +struct S2 { + int i; +}; +void foo2(void *p) { ((struct S2 *)p)->i++; } + +struct S3 { + int i; +}; +void foo3(struct S3 *p) { p->i++; } + +union U4 { + int i; + char c; +}; +void foo4(void *p) { ((union U4 *)p)->i++; } + +typedef union U5 { + int i; + char c; +} T5; + +void foo5(void *p) { ((T5 *)p)->i++; } + +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, null, metadata !"S2", i32 14, i64 32, i64 32, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, null, null} ; [ DW_TAG_structure_type ] [S2] [line 14, size 32, align 32, offset 0] [def] [from ] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, metadata !{{.*}}, metadata !"i", i32 15, i64 32, i64 32, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_member ] [i] [line 15, size 32, align 32, offset 0] [from int] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, null, metadata !"U4", i32 24, i64 32, i64 32, i64 0, i32 0, null, metadata !{{.*}}, i32 0, null, null, null} ; [ DW_TAG_union_type ] [U4] [line 24, size 32, align 32, offset 0] [def] [from ] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, metadata !{{.*}}, metadata !"i", i32 25, i64 32, i64 32, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_member ] [i] [line 25, size 32, align 32, offset 0] [from int] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, metadata !{{.*}}, metadata !"c", i32 26, i64 8, i64 8, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_member ] [c] [line 26, size 8, align 8, offset 0] [from char] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, null, metadata !"T5", i32 33, i64 0, i64 0, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_typedef ] [T5] [line 33, size 0, align 0, offset 0] [from U5] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, null, metadata !"U5", i32 30, i64 32, i64 32, i64 0, i32 0, null, metadata !{{.*}}, i32 0, null, null, null} ; [ DW_TAG_union_type ] [U5] [line 30, size 32, align 32, offset 0] [def] [from ] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, metadata !{{.*}}, metadata !"i", i32 31, i64 32, i64 32, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_member ] [i] [line 31, size 32, align 32, offset 0] [from int] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, metadata !{{.*}}, metadata !"c", i32 32, i64 8, i64 8, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_member ] [c] [line 32, size 8, align 8, offset 0] [from char] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, null, metadata !"T1", i32 11, i64 0, i64 0, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_typedef ] [T1] [line 11, size 0, align 0, offset 0] [from S1] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, null, metadata !"S1", i32 11, i64 32, i64 32, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, null, null} ; [ DW_TAG_structure_type ] [S1] [line 11, size 32, align 32, offset 0] [def] [from ] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, metadata !{{.*}}, metadata !"i", i32 11, i64 32, i64 32, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_member ] [i] [line 11, size 32, align 32, offset 0] [from int] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, null, metadata !"S3", i32 19, i64 32, i64 32, i32 0, i32 0, null, metadata !{{.*}}, i32 0, null, null, null} ; [ DW_TAG_structure_type ] [S3] [line 19, size 32, align 32, offset 0] [def] [from ] +// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, metadata !{{.*}}, metadata !"i", i32 20, i64 32, i64 32, i64 0, i32 0, metadata !{{.*}}} ; [ DW_TAG_member ] [i] [line 20, size 32, align 32, offset 0] [from int]