diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -1509,6 +1509,21 @@ llvm::ConstantInt *CaseVal = Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext())); + + // Emit debuginfo for the case value if it is an enum value. + const ConstantExpr *CE; + if (auto ICE = dyn_cast(S.getLHS())) + CE = dyn_cast(ICE->getSubExpr()); + else + CE = dyn_cast(S.getLHS()); + if (CE) { + if (auto DE = dyn_cast(CE->getSubExpr())) + if (CGDebugInfo *Dbg = getDebugInfo()) + if (CGM.getCodeGenOpts().hasReducedDebugInfo()) + Dbg->EmitGlobalVariable(DE->getDecl(), + APValue(llvm::APSInt(CaseVal->getValue()))); + } + if (SwitchLikelihood) SwitchLikelihood->push_back(Stmt::getLikelihood(Attrs)); diff --git a/clang/test/CodeGen/debug-info-enum-case-val.c b/clang/test/CodeGen/debug-info-enum-case-val.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/debug-info-enum-case-val.c @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s + +enum { A = 1 }; +int func1(int a) { + switch(a) { + case A: return 10; + default: break; + } + return 0; +} +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type +// CHECK-SAME: elements: [[TEST1_ENUMS:![0-9]*]] +// CHECK: [[TEST1_ENUMS]] = !{[[TEST1_E:![0-9]*]]} +// CHECK: [[TEST1_E]] = !DIEnumerator(name: "A", value: 1) + +// Test ImplicitCast of switch case enum value +enum { B = 2 }; +typedef unsigned long long __t1; +typedef __t1 __t2; +int func2(__t2 a) { + switch(a) { + case B: return 10; + default: break; + } + return 0; +} +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type +// CHECK-SAME: elements: [[TEST2_ENUMS:![0-9]*]] +// CHECK: [[TEST2_ENUMS]] = !{[[TEST2_E:![0-9]*]]} +// CHECK: [[TEST2_E]] = !DIEnumerator(name: "B", value: 2)