[clang] 5159732 - [CodeView] Emit static data members as S_CONSTANTs.

Amy Huang via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 26 15:30:51 PDT 2020


Author: Amy Huang
Date: 2020-10-26T15:30:35-07:00
New Revision: 515973222ed29abe49f241e89edb6854f44162d4

URL: https://github.com/llvm/llvm-project/commit/515973222ed29abe49f241e89edb6854f44162d4
DIFF: https://github.com/llvm/llvm-project/commit/515973222ed29abe49f241e89edb6854f44162d4.diff

LOG: [CodeView] Emit static data members as S_CONSTANTs.

We used to only emit static const data members in CodeView as
S_CONSTANTS when they were used; this patch makes it so they are always emitted.

I changed CodeViewDebug.cpp to find the static const members from the
class debug info instead of creating DIGlobalVariables in the IR
whenever a static const data member is used.

Bug: https://bugs.llvm.org/show_bug.cgi?id=47580

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

Added: 
    

Modified: 
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/test/CodeGenCXX/debug-info-static-member.cpp
    llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
    llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
    llvm/test/DebugInfo/COFF/global-constants.ll
    llvm/test/DebugInfo/COFF/types-array-unsized.ll

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 8280fe718f26..96689c1b38ec 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4729,13 +4729,10 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
     }
   }
 
-  llvm::DIScope *DContext = nullptr;
-
   // Do not emit separate definitions for function local consts.
   if (isa<FunctionDecl>(VD->getDeclContext()))
     return;
 
-  // Emit definition for static members in CodeView.
   VD = cast<ValueDecl>(VD->getCanonicalDecl());
   auto *VarD = dyn_cast<VarDecl>(VD);
   if (VarD && VarD->isStaticDataMember()) {
@@ -4748,15 +4745,9 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
     RetainedTypes.push_back(
         CGM.getContext().getRecordType(RD).getAsOpaquePtr());
 
-    if (!CGM.getCodeGenOpts().EmitCodeView)
-      return;
-
-    // Use the global scope for static members.
-    DContext = getContextDescriptor(
-        cast<Decl>(CGM.getContext().getTranslationUnitDecl()), TheCU);
-  } else {
-    DContext = getDeclContextDescriptor(VD);
+    return;
   }
+  llvm::DIScope *DContext = getDeclContextDescriptor(VD);
 
   auto &GV = DeclCache[VD];
   if (GV)

diff  --git a/clang/test/CodeGenCXX/debug-info-static-member.cpp b/clang/test/CodeGenCXX/debug-info-static-member.cpp
index 8ad86843f4e9..260a3afdd652 100644
--- a/clang/test/CodeGenCXX/debug-info-static-member.cpp
+++ b/clang/test/CodeGenCXX/debug-info-static-member.cpp
@@ -1,12 +1,12 @@
-// RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck %s
-// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++98 %s -emit-llvm -S -o - | FileCheck %s
-// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-windows-msvc -gcodeview -debug-info-kind=limited %s -emit-llvm -o - | FileCheck --check-prefix MSVC %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++98 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s
+// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s
+// RUN: %clangxx -target x86_64-windows-msvc -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s
 // PR14471
 
-// CHECK: @_ZN1C1aE = dso_local global i32 4, align 4, !dbg [[A:![0-9]+]]
-// CHECK: @_ZN1C1bE = dso_local global i32 2, align 4, !dbg [[B:![0-9]+]]
-// CHECK: @_ZN1C1cE = dso_local global i32 1, align 4, !dbg [[C:![0-9]+]]
+// CHECK: @{{.*}}a{{.*}} = dso_local global i32 4, align 4, !dbg [[A:![0-9]+]]
+// CHECK: @{{.*}}b{{.*}} = dso_local global i32 2, align 4, !dbg [[B:![0-9]+]]
+// CHECK: @{{.*}}c{{.*}} = dso_local global i32 1, align 4, !dbg [[C:![0-9]+]]
 
 enum X {
   Y
@@ -36,9 +36,8 @@ class C
 // CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]], expr: !DIExpression())
 // CHECK: [[AV]] = distinct !DIGlobalVariable(name: "a",
 // CHECK-SAME:                                declaration: ![[DECL_A:[0-9]+]])
-// MSVC: distinct !DIGlobalVariable(name: "a"
 //
-// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}, identifier: "_ZTS1X")
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}})
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct"
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var"
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "static_decl_templ<int>"
@@ -50,14 +49,13 @@ int C::a = 4;
 // CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]], expr: !DIExpression())
 // CHECK: [[BV]] = distinct !DIGlobalVariable(name: "b",
 // CHECK-SAME:                                declaration: ![[DECL_B:[0-9]+]])
-// MSVC: distinct !DIGlobalVariable(name: "b"
 // CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
 // CHECK-NOT:                                 size:
 // CHECK-NOT:                                 align:
 // CHECK-NOT:                                 offset:
 // CHECK-SAME:                                flags: DIFlagProtected | DIFlagStaticMember)
 //
-// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "C"{{.*}}, identifier: "_ZTS1C")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "C"{{.*}})
 //
 // CHECK: ![[DECL_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a"
 // CHECK-NOT:                                 size:
@@ -98,7 +96,6 @@ int C::a = 4;
 int C::b = 2;
 // CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]], expr: !DIExpression())
 // CHECK: [[CV]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]])
-// MSVC: distinct !DIGlobalVariable(name: "c"
 int C::c = 1;
 
 int main()
@@ -122,14 +119,6 @@ int ref() {
   return anon_static_decl_struct::anon_static_decl_var;
 }
 
-// In MSVC, static data members should be emitted as global variables when used.
-// MSVC: !DIGlobalVariableExpression(var: [[ANON_STATIC_DECL:![0-9]+]],
-// MSVC-SAME: !DIExpression(DW_OP_constu, 117, DW_OP_stack_value)
-// MSVC: [[ANON_STATIC_DECL]] = distinct !DIGlobalVariable(name: "anon_static_decl_var"
-// MSVC: !DIGlobalVariableExpression(var: [[STATIC_DECL_TEMPL:![0-9]+]]
-// MSVC-SAME: !DIExpression(DW_OP_constu, 7, DW_OP_stack_value)
-// MSVC: [[STATIC_DECL_TEMPL]] = distinct !DIGlobalVariable(name: "static_decl_templ_var"
-
 template<typename T>
 struct static_decl_templ {
   static const int static_decl_templ_var = 7;
@@ -151,9 +140,11 @@ struct V {
   virtual ~V(); // cause the definition of 'V' to be omitted by no-standalone-debug optimization
   static const int const_va = 42;
 };
-// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_va",
-// CHECK-SAME:           line: [[@LINE-3]]
-// CHECK-SAME:           extraData: i32 42
+
+// const_va is not emitted for MS targets.
+// NOT-MS: !DIDerivedType(tag: DW_TAG_member, name: "const_va",
+// NOT-MS-SAME:           line: [[@LINE-5]]
+// NOT-MS-SAME:           extraData: i32 42
 const int V::const_va;
 
 namespace x {

diff  --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 98fccf009338..3ad00f05d3ef 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -588,13 +588,18 @@ void CodeViewDebug::endModule() {
     if (!P.first->isDeclarationForLinker())
       emitDebugInfoForFunction(P.first, *P.second);
 
-  // Emit global variable debug information.
-  setCurrentSubprogram(nullptr);
-  emitDebugInfoForGlobals();
+  // Get types used by globals without emitting anything.
+  // This is meant to collect all static const data members so they can be
+  // emitted as globals.
+  collectDebugInfoForGlobals();
 
   // Emit retained types.
   emitDebugInfoForRetainedTypes();
 
+  // Emit global variable debug information.
+  setCurrentSubprogram(nullptr);
+  emitDebugInfoForGlobals();
+
   // Switch back to the generic .debug$S section after potentially processing
   // comdat symbol sections.
   switchToDebugSectionForSymbol(nullptr);
@@ -2143,6 +2148,12 @@ void CodeViewDebug::collectMemberInfo(ClassInfo &Info,
                                       const DIDerivedType *DDTy) {
   if (!DDTy->getName().empty()) {
     Info.Members.push_back({DDTy, 0});
+
+    // Collect static const data members.
+    if ((DDTy->getFlags() & DINode::FlagStaticMember) ==
+        DINode::FlagStaticMember)
+      StaticConstMembers.push_back(DDTy);
+
     return;
   }
 
@@ -3045,15 +3056,32 @@ void CodeViewDebug::collectGlobalVariableInfo() {
   }
 }
 
+void CodeViewDebug::collectDebugInfoForGlobals() {
+  for (const CVGlobalVariable &CVGV : GlobalVariables) {
+    const DIGlobalVariable *DIGV = CVGV.DIGV;
+    const DIScope *Scope = DIGV->getScope();
+    getCompleteTypeIndex(DIGV->getType());
+    getFullyQualifiedName(Scope, DIGV->getName());
+  }
+
+  for (const CVGlobalVariable &CVGV : ComdatVariables) {
+    const DIGlobalVariable *DIGV = CVGV.DIGV;
+    const DIScope *Scope = DIGV->getScope();
+    getCompleteTypeIndex(DIGV->getType());
+    getFullyQualifiedName(Scope, DIGV->getName());
+  }
+}
+
 void CodeViewDebug::emitDebugInfoForGlobals() {
   // First, emit all globals that are not in a comdat in a single symbol
   // substream. MSVC doesn't like it if the substream is empty, so only open
   // it if we have at least one global to emit.
   switchToDebugSectionForSymbol(nullptr);
-  if (!GlobalVariables.empty()) {
+  if (!GlobalVariables.empty() || !StaticConstMembers.empty()) {
     OS.AddComment("Symbol subsection for globals");
     MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
     emitGlobalVariableList(GlobalVariables);
+    emitStaticConstMemberList();
     endCVSubsection(EndLabel);
   }
 
@@ -3092,6 +3120,64 @@ void CodeViewDebug::emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals) {
   }
 }
 
+// Return true if type encoding is unsigned.
+static bool isStaticConstUnsigned(const DIType *Ty) {
+  if (const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
+    if (CTy->getTag() == dwarf::DW_TAG_enumeration_type) {
+      assert(CTy->getBaseType() && "Expected valid base type");
+      return isStaticConstUnsigned(CTy->getBaseType());
+    }
+
+    return true;
+  }
+  if (const auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
+    assert(DTy->getBaseType() && "Expected valid base type");
+    return isStaticConstUnsigned(DTy->getBaseType());
+  }
+
+  const auto *BTy = cast<DIBasicType>(Ty);
+  unsigned Encoding = BTy->getEncoding();
+  return Encoding == dwarf::DW_ATE_unsigned ||
+         Encoding == dwarf::DW_ATE_unsigned_char ||
+         Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
+         Ty->getTag() == dwarf::DW_TAG_unspecified_type;
+}
+
+void CodeViewDebug::emitStaticConstMemberList() {
+  for (const DIDerivedType *DTy : StaticConstMembers) {
+    const DIScope *Scope = DTy->getScope();
+
+    APSInt Value;
+    if (const ConstantInt *CI =
+            dyn_cast_or_null<ConstantInt>(DTy->getConstant()))
+      Value = APSInt(CI->getValue(), isStaticConstUnsigned(DTy->getBaseType()));
+    else if (const ConstantFP *CFP =
+                 dyn_cast_or_null<ConstantFP>(DTy->getConstant()))
+      Value = APSInt(CFP->getValueAPF().bitcastToAPInt(), true);
+    else
+      continue;
+
+    std::string QualifiedName = getFullyQualifiedName(Scope, DTy->getName());
+
+    MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
+    OS.AddComment("Type");
+    OS.emitInt32(getTypeIndex(DTy->getBaseType()).getIndex());
+    OS.AddComment("Value");
+
+    // Encoded integers shouldn't need more than 10 bytes.
+    uint8_t Data[10];
+    BinaryStreamWriter Writer(Data, llvm::support::endianness::little);
+    CodeViewRecordIO IO(Writer);
+    cantFail(IO.mapEncodedInteger(Value));
+    StringRef SRef((char *)Data, Writer.getOffset());
+    OS.emitBinaryData(SRef);
+
+    OS.AddComment("Name");
+    emitNullTerminatedSymbolName(OS, QualifiedName);
+    endSymbolRecord(SConstantEnd);
+  }
+}
+
 void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
   const DIGlobalVariable *DIGV = CVGV.DIGV;
 

diff  --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 82f0293874d0..0e4fd534ea07 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -203,6 +203,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
   // Array of non-COMDAT global variables.
   SmallVector<CVGlobalVariable, 1> GlobalVariables;
 
+  /// List of static const data members to be emitted as S_CONSTANTs.
+  SmallVector<const DIDerivedType *, 4> StaticConstMembers;
+
   /// The set of comdat .debug$S sections that we've seen so far. Each section
   /// must start with a magic version number that must only be emitted once.
   /// This set tracks which sections we've already opened.
@@ -313,9 +316,11 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
   void emitDebugInfoForUDTs(
       const std::vector<std::pair<std::string, const DIType *>> &UDTs);
 
+  void collectDebugInfoForGlobals();
   void emitDebugInfoForGlobals();
   void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals);
   void emitDebugInfoForGlobal(const CVGlobalVariable &CVGV);
+  void emitStaticConstMemberList();
 
   /// Opens a subsection of the given kind in a .debug$S codeview section.
   /// Returns an end label for use with endCVSubsection when the subsection is

diff  --git a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
index 49761b9dce88..c272985cf2d4 100644
--- a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
@@ -273,7 +273,6 @@ Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value,
 
 void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value,
                                                 const Twine &Comment) {
-  assert(Value < 0 && "Encoded integer is not signed!");
   if (Value >= std::numeric_limits<int8_t>::min()) {
     Streamer->emitIntValue(LF_CHAR, 2);
     emitComment(Comment);
@@ -322,7 +321,6 @@ void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value,
 }
 
 Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
-  assert(Value < 0 && "Encoded integer is not signed!");
   if (Value >= std::numeric_limits<int8_t>::min()) {
     if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
       return EC;

diff  --git a/llvm/test/DebugInfo/COFF/global-constants.ll b/llvm/test/DebugInfo/COFF/global-constants.ll
index f930df48be10..8276932925ac 100644
--- a/llvm/test/DebugInfo/COFF/global-constants.ll
+++ b/llvm/test/DebugInfo/COFF/global-constants.ll
@@ -7,6 +7,9 @@
 ; }
 ; struct S {
 ;   static const int TestConst2 = -10;
+;   // Unused static consts should still be emitted.
+;   static const int TestConst3 = 3;
+;   static constexpr int TestConst 4 = 4;
 ;   enum { SEnum = 42 };
 ; };
 ; enum TestEnum : int {
@@ -34,14 +37,6 @@
 
 ; ASM:	      .short	4359                    # Record kind: S_CONSTANT
 ; ASM-NEXT:	  .long	4101                    # Type
-; ASM-NEXT:	  .byte	0x0a, 0x80, 0xf6, 0xff  # Value
-; ASM-NEXT:	  .byte	0xff, 0xff, 0xff, 0xff
-; ASM-NEXT:	  .byte	0xff, 0xff
-; ASM-NEXT:	  .asciz	"S::TestConst2"         # Name
-; ASM-NEXT:	  .p2align	2
-
-; ASM:	      .short	4359                    # Record kind: S_CONSTANT
-; ASM-NEXT:	  .long	4110                    # Type
 ; ASM-NEXT:	  .byte	0x0a, 0x80, 0x40, 0x61  # Value
 ; ASM-NEXT:	  .byte	0x07, 0x80, 0xff, 0xff
 ; ASM-NEXT:	  .byte	0xff, 0xff
@@ -49,6 +44,12 @@
 ; ASM-NEXT:	  .p2align	2
 ; ASM-NOT:    .asciz "S::SEnum"             # Name
 
+; ASM:	      .short	4359                    # Record kind: S_CONSTANT
+; ASM-NEXT:	  .long	4105                    # Type
+; ASM-NEXT:	  .byte	0x00, 0x80, 0xf6        # Value
+; ASM-NEXT:	  .asciz	"S::TestConst2"         # Name
+; ASM-NEXT:	  .p2align	2
+
 ; OBJ:        CodeViewDebugInfo [
 ; OBJ:          Section: .debug$S
 ; OBJ:          Magic: 0x4
@@ -62,17 +63,17 @@
 ; OBJ-NEXT:       }
 ; OBJ-NEXT:       ConstantSym {
 ; OBJ-NEXT:         Kind: S_CONSTANT (0x1107)
-; OBJ-NEXT:         Type: const int (0x1005)
-; OBJ-NEXT:         Value: 18446744073709551606
-; OBJ-NEXT:         Name: S::TestConst2
-; OBJ-NEXT:       }
-; OBJ-NEXT:       ConstantSym {
-; OBJ-NEXT:         Kind: S_CONSTANT (0x1107)
-; OBJ-NEXT:         Type: TestEnum (0x100E)
+; OBJ-NEXT:         Type: TestEnum (0x1005)
 ; OBJ-NEXT:         Value: 18446744071562551616
 ; OBJ-NEXT:         Name: ENUM_B
 ; OBJ-NEXT:       }
 ; OBJ-NOT:          Name: S::SEnum
+; OBJ-NEXT:       ConstantSym {
+; OBJ-NEXT:         Kind: S_CONSTANT (0x1107)
+; OBJ-NEXT:         Type: const int (0x1009)
+; OBJ-NEXT:         Value: -10
+; OBJ-NEXT:         Name: S::TestConst2
+; OBJ-NEXT:       }
 
 ; ModuleID = 'a.cpp'
 source_filename = "a.cpp"
@@ -98,43 +99,43 @@ attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-
 !llvm.module.flags = !{!26, !27, !28, !29}
 !llvm.ident = !{!30}
 
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0 (https://github.com/llvm/llvm-project.git 202f144bffd0be254a829924195e1b8ebabcbb79)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !15, globals: !16, nameTableKind: None)
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git 34cd06a9b3bddaa7a989c606bbf1327ee651711c)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !17, globals: !18, nameTableKind: None)
 !1 = !DIFile(filename: "a.cpp", directory: "F:\\llvm-project\\__test", checksumkind: CSK_MD5, checksum: "a1dbf3aabea9e8f9d1be48f60287942f")
-!2 = !{!3, !11}
-!3 = !DICompositeType(tag: DW_TAG_enumeration_type, scope: !4, file: !1, line: 6, baseType: !8, size: 32, elements: !9, identifier: ".?AW4<unnamed-enum-SEnum>@S@@")
+!2 = !{!3, !13}
+!3 = !DICompositeType(tag: DW_TAG_enumeration_type, scope: !4, file: !1, line: 8, baseType: !8, size: 32, elements: !11, identifier: ".?AW4<unnamed-enum-SEnum>@S@@")
 !4 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !1, line: 4, size: 8, flags: DIFlagTypePassByValue, elements: !5, identifier: ".?AUS@@")
-!5 = !{!6, !3}
+!5 = !{!6, !9, !10, !3}
 !6 = !DIDerivedType(tag: DW_TAG_member, name: "TestConst2", scope: !4, file: !1, line: 5, baseType: !7, flags: DIFlagStaticMember, extraData: i32 -10)
 !7 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !8)
 !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!9 = !{!10}
-!10 = !DIEnumerator(name: "SEnum", value: 42)
-!11 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "TestEnum", file: !1, line: 8, baseType: !8, size: 32, elements: !12, identifier: ".?AW4TestEnum@@")
-!12 = !{!13, !14}
-!13 = !DIEnumerator(name: "ENUM_A", value: 2147000000)
-!14 = !DIEnumerator(name: "ENUM_B", value: -2147000000)
-!15 = !{!4}
-!16 = !{!17, !22, !24}
-!17 = !DIGlobalVariableExpression(var: !18, expr: !DIExpression(DW_OP_constu, 1078523331, DW_OP_stack_value))
-!18 = distinct !DIGlobalVariable(name: "TestConst1", scope: !19, file: !1, line: 2, type: !20, isLocal: true, isDefinition: true)
-!19 = !DINamespace(name: "Test1", scope: null)
-!20 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !21)
-!21 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
-!22 = !DIGlobalVariableExpression(var: !23, expr: !DIExpression(DW_OP_constu, 18446744073709551606, DW_OP_stack_value))
-!23 = distinct !DIGlobalVariable(name: "TestConst2", scope: !0, file: !1, line: 5, type: !7, isLocal: true, isDefinition: true, declaration: !6)
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "TestConst3", scope: !4, file: !1, line: 6, baseType: !7, flags: DIFlagStaticMember, extraData: i32 3)
+!10 = !DIDerivedType(tag: DW_TAG_member, name: "TestConst4", scope: !4, file: !1, line: 7, baseType: !7, flags: DIFlagStaticMember, extraData: i32 4)
+!11 = !{!12}
+!12 = !DIEnumerator(name: "SEnum", value: 42)
+!13 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "TestEnum", file: !1, line: 10, baseType: !8, size: 32, elements: !14, identifier: ".?AW4TestEnum@@")
+!14 = !{!15, !16}
+!15 = !DIEnumerator(name: "ENUM_A", value: 2147000000)
+!16 = !DIEnumerator(name: "ENUM_B", value: -2147000000)
+!17 = !{!4}
+!18 = !{!19, !24}
+!19 = !DIGlobalVariableExpression(var: !20, expr: !DIExpression(DW_OP_constu, 1078523331, DW_OP_stack_value))
+!20 = distinct !DIGlobalVariable(name: "TestConst1", scope: !21, file: !1, line: 2, type: !22, isLocal: true, isDefinition: true)
+!21 = !DINamespace(name: "Test1", scope: null)
+!22 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !23)
+!23 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
 !24 = !DIGlobalVariableExpression(var: !25, expr: !DIExpression(DW_OP_constu, 18446744071562551616, DW_OP_stack_value))
-!25 = distinct !DIGlobalVariable(name: "ENUM_B", scope: !0, file: !1, line: 10, type: !11, isLocal: true, isDefinition: true)
+!25 = distinct !DIGlobalVariable(name: "ENUM_B", scope: !0, file: !1, line: 12, type: !13, isLocal: true, isDefinition: true)
 !26 = !{i32 2, !"CodeView", i32 1}
 !27 = !{i32 2, !"Debug Info Version", i32 3}
 !28 = !{i32 1, !"wchar_size", i32 2}
 !29 = !{i32 7, !"PIC Level", i32 2}
-!30 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 202f144bffd0be254a829924195e1b8ebabcbb79)"}
-!31 = distinct !DISubprogram(name: "foo", linkageName: "?foo@@YAXXZ", scope: !1, file: !1, line: 13, type: !32, scopeLine: 13, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !34)
+!30 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git 34cd06a9b3bddaa7a989c606bbf1327ee651711c)"}
+!31 = distinct !DISubprogram(name: "foo", linkageName: "?foo@@YAXXZ", scope: !1, file: !1, line: 15, type: !32, scopeLine: 15, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !34)
 !32 = !DISubroutineType(types: !33)
 !33 = !{null}
 !34 = !{}
-!35 = !DILocation(line: 14, scope: !31)
-!36 = !DILocation(line: 15, scope: !31)
-!37 = !DILocation(line: 16, scope: !31)
-!38 = !DILocation(line: 17, scope: !31)
-!39 = !DILocation(line: 18, scope: !31)
+!35 = !DILocation(line: 16, scope: !31)
+!36 = !DILocation(line: 17, scope: !31)
+!37 = !DILocation(line: 18, scope: !31)
+!38 = !DILocation(line: 19, scope: !31)
+!39 = !DILocation(line: 20, scope: !31)

diff  --git a/llvm/test/DebugInfo/COFF/types-array-unsized.ll b/llvm/test/DebugInfo/COFF/types-array-unsized.ll
index 8bfb0c08ee39..bae5707c76e0 100644
--- a/llvm/test/DebugInfo/COFF/types-array-unsized.ll
+++ b/llvm/test/DebugInfo/COFF/types-array-unsized.ll
@@ -12,14 +12,22 @@
 ; Foo f; // FIXME: only needed to force emit 'Foo'
 
 ; CHECK:      CodeViewTypes [
+; CHECK:        Array ([[ARRAY_COMPLETE:0x.*]]) {
+; CHECK-NEXT:     TypeLeafKind: LF_ARRAY (0x1503)
+; CHECK-NEXT:     ElementType: const char ({{.*}})
+; CHECK-NEXT:     IndexType: unsigned __int64 (0x23)
+; CHECK-NEXT:     SizeOf: 5
+; CHECK-NEXT:     Name:
+; CHECK-NEXT:   }
+; CHECK:      ]
 ; CHECK:        Array ([[ARRAY_FWD:0x.*]]) {
 ; CHECK-NEXT:     TypeLeafKind: LF_ARRAY (0x1503)
 ; CHECK-NEXT:     ElementType: const char ({{.*}})
 ; CHECK-NEXT:     IndexType: unsigned __int64 (0x23)
 ; CHECK-NEXT:     SizeOf: 0
-; CHECK-NEXT:     Name: 
+; CHECK-NEXT:     Name:
 ; CHECK-NEXT:   }
-; CHECK:        FieldList (0x1003) {
+; CHECK:        FieldList (0x1004) {
 ; CHECK-NEXT:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK-NEXT:     StaticDataMember {
 ; CHECK-NEXT:       TypeLeafKind: LF_STMEMBER (0x150E)
@@ -28,14 +36,6 @@
 ; CHECK-NEXT:       Name: str
 ; CHECK-NEXT:     }
 ; CHECK-NEXT:   }
-; CHECK:        Array ([[ARRAY_COMPLETE:0x.*]]) {
-; CHECK-NEXT:     TypeLeafKind: LF_ARRAY (0x1503)
-; CHECK-NEXT:     ElementType: const char ({{.*}})
-; CHECK-NEXT:     IndexType: unsigned __int64 (0x23)
-; CHECK-NEXT:     SizeOf: 5
-; CHECK-NEXT:     Name: 
-; CHECK-NEXT:   }
-; CHECK:      ]
 
 ; CHECK:          GlobalData {
 ; CHECK-NEXT:       Kind: S_GDATA32 (0x110D)


        


More information about the cfe-commits mailing list