Skip to content

Commit 67ac047

Browse files
yonghong-songtru
authored andcommitted
[clang][DebugInfo] Emit debuginfo for non-constant case value
Currently, clang does not emit debuginfo for the switch stmt case value if it is an enum value. For example, $ cat test.c enum { AA = 1, BB = 2 }; int func1(int a) { switch(a) { case AA: return 10; case BB: return 11; default: break; } return 0; } $ llvm-dwarfdump test.o | grep AA $ Note that gcc does emit debuginfo for the same test case. This patch added such a support with similar implementation to CodeGenFunction::EmitDeclRefExprDbgValue(). With this patch, $ clang -g -c test.c $ llvm-dwarfdump test.o | grep AA DW_AT_name ("AA") $ Differential Revision: https://reviews.llvm.org/D134705 (cherry picked from commit 75be048)
1 parent 541ea23 commit 67ac047

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,21 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S,
15091509

15101510
llvm::ConstantInt *CaseVal =
15111511
Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext()));
1512+
1513+
// Emit debuginfo for the case value if it is an enum value.
1514+
const ConstantExpr *CE;
1515+
if (auto ICE = dyn_cast<ImplicitCastExpr>(S.getLHS()))
1516+
CE = dyn_cast<ConstantExpr>(ICE->getSubExpr());
1517+
else
1518+
CE = dyn_cast<ConstantExpr>(S.getLHS());
1519+
if (CE) {
1520+
if (auto DE = dyn_cast<DeclRefExpr>(CE->getSubExpr()))
1521+
if (CGDebugInfo *Dbg = getDebugInfo())
1522+
if (CGM.getCodeGenOpts().hasReducedDebugInfo())
1523+
Dbg->EmitGlobalVariable(DE->getDecl(),
1524+
APValue(llvm::APSInt(CaseVal->getValue())));
1525+
}
1526+
15121527
if (SwitchLikelihood)
15131528
SwitchLikelihood->push_back(Stmt::getLikelihood(Attrs));
15141529

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
2+
3+
enum { A = 1 };
4+
int func1(int a) {
5+
switch(a) {
6+
case A: return 10;
7+
default: break;
8+
}
9+
return 0;
10+
}
11+
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type
12+
// CHECK-SAME: elements: [[TEST1_ENUMS:![0-9]*]]
13+
// CHECK: [[TEST1_ENUMS]] = !{[[TEST1_E:![0-9]*]]}
14+
// CHECK: [[TEST1_E]] = !DIEnumerator(name: "A", value: 1)
15+
16+
// Test ImplicitCast of switch case enum value
17+
enum { B = 2 };
18+
typedef unsigned long long __t1;
19+
typedef __t1 __t2;
20+
int func2(__t2 a) {
21+
switch(a) {
22+
case B: return 10;
23+
default: break;
24+
}
25+
return 0;
26+
}
27+
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type
28+
// CHECK-SAME: elements: [[TEST2_ENUMS:![0-9]*]]
29+
// CHECK: [[TEST2_ENUMS]] = !{[[TEST2_E:![0-9]*]]}
30+
// CHECK: [[TEST2_E]] = !DIEnumerator(name: "B", value: 2)

0 commit comments

Comments
 (0)