[clang] 75be048 - [clang][DebugInfo] Emit debuginfo for non-constant case value

Yonghong Song via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 28 12:11:18 PDT 2022


Author: Yonghong Song
Date: 2022-09-28T12:10:48-07:00
New Revision: 75be0482a2e2a78fae83f1ca604f4ee20d673796

URL: https://github.com/llvm/llvm-project/commit/75be0482a2e2a78fae83f1ca604f4ee20d673796
DIFF: https://github.com/llvm/llvm-project/commit/75be0482a2e2a78fae83f1ca604f4ee20d673796.diff

LOG: [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

Added: 
    clang/test/CodeGen/debug-info-enum-case-val.c

Modified: 
    clang/lib/CodeGen/CGStmt.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 481438de0e53a..9935fcc0d3ea2 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1509,6 +1509,21 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S,
 
   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<ImplicitCastExpr>(S.getLHS()))
+    CE = dyn_cast<ConstantExpr>(ICE->getSubExpr());
+  else
+    CE = dyn_cast<ConstantExpr>(S.getLHS());
+  if (CE) {
+    if (auto DE = dyn_cast<DeclRefExpr>(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
index 0000000000000..f39de0d732375
--- /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)


        


More information about the cfe-commits mailing list