]> granicus.if.org Git - clang/commitdiff
[DebugInfo] Emit DW_TAG_enumeration_type for referenced global enumerator.
authorYuanfang Chen <yuanfang.chen@sony.com>
Wed, 4 Sep 2019 20:58:15 +0000 (20:58 +0000)
committerYuanfang Chen <yuanfang.chen@sony.com>
Wed, 4 Sep 2019 20:58:15 +0000 (20:58 +0000)
This essentially reverts changes from r361400 while keeping behavior for
CodeView.

Reviewers: akhuang, rnk, probinson

Reviewed by: rnk

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67141

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@370981 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDebugInfo.cpp
test/CodeGen/enum2.c

index b1f82d47d4456191a2ee27debcdf074b9748ee02..e36f6932f86e79740d66add602b916b59ac2473e 100644 (file)
@@ -4438,19 +4438,27 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
   StringRef Name = VD->getName();
   llvm::DIType *Ty = getOrCreateType(VD->getType(), Unit);
 
-  // Do not use global variables for enums, unless in CodeView.
   if (const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
     const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
     assert(isa<EnumType>(ED->getTypeForDecl()) && "Enum without EnumType?");
-    (void)ED;
-
-    // If CodeView, emit enums as global variables, unless they are defined
-    // inside a class. We do this because MSVC doesn't emit S_CONSTANTs for
-    // enums in classes, and because it is difficult to attach this scope
-    // information to the global variable.
-    if (!CGM.getCodeGenOpts().EmitCodeView ||
-        isa<RecordDecl>(ED->getDeclContext()))
+
+    if (CGM.getCodeGenOpts().EmitCodeView) {
+      // If CodeView, emit enums as global variables, unless they are defined
+      // inside a class. We do this because MSVC doesn't emit S_CONSTANTs for
+      // enums in classes, and because it is difficult to attach this scope
+      // information to the global variable.
+      if (isa<RecordDecl>(ED->getDeclContext()))
+        return;
+    } else {
+      // If not CodeView, emit DW_TAG_enumeration_type if necessary. For
+      // example: for "enum { ZERO };", a DW_TAG_enumeration_type is created the
+      // first time `ZERO` is referenced in a function.
+      llvm::DIType *EDTy =
+          getOrCreateType(QualType(ED->getTypeForDecl(), 0), Unit);
+      assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
+      (void)EDTy;
       return;
+    }
   }
 
   llvm::DIScope *DContext = nullptr;
index 9729ad0b4b063d8345760ca4d8d1e73babc482b8..f41d5a18d027ae1c544eb49cc391ab84e3f06f35 100644 (file)
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown %s -debug-info-kind=limited -emit-llvm -o /dev/null
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -debug-info-kind=limited -emit-llvm -o - | FileCheck %s
+
 int v;
 enum e { MAX };
 
@@ -6,3 +7,9 @@ void foo (void)
 {
   v = MAX;
 }
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
+// CHECK-SAME: baseType: ![[LONG:[0-9]+]]
+// CHECK-SAME: elements: ![[ELTS:[0-9]+]]
+// CHECK: ![[LONG]] = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
+// CHECK: ![[ELTS]] = !{![[MAX:[0-9]+]]}
+// CHECK: ![[MAX]] = !DIEnumerator(name: "MAX", value: 0, isUnsigned: true)