<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, Aug 28, 2017 at 5:08 PM Bob Haarman via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: inglorion<br>
Date: Mon Aug 28 17:06:59 2017<br>
New Revision: 311957<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=311957&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=311957&view=rev</a><br>
Log:<br>
[codeview] support more DW_OPs for more complete debug info<br>
<br>
Summary:<br>
Some variables show up in Visual Studio as "optimized out" even in -O0<br>
-Od builds. This change fixes two issues that would cause this to<br>
happen. The first issue is that not all DIExpressions we generate were<br>
recognized by the CodeView writer. This has been addressed by adding<br>
support for DW_OP_constu, DW_OP_minus, and DW_OP_plus. The second<br>
issue is that we had no way to encode DW_OP_deref in CodeView. We get<br>
around that by changinge the type we encode in the debug info to be<br>
a reference to the type in the source code.<br></blockquote><div><br>I've seen this done before & would really advise against it - this was originally how LLVM handled non-trivial pass-by-value (where the actual ABI parameter is a pointer - it would encode the parameter type as T& instead of T). That caused some problems.<br><br>What does MSVC do in this sort of situation?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
This fixes PR34261.<br>
<br>
Reviewers: aprantl, rnk, zturner<br>
<br>
Reviewed By: rnk<br>
<br>
Subscribers: mgorny, llvm-commits, aprantl, hiraditya<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D36907" rel="noreferrer" target="_blank">https://reviews.llvm.org/D36907</a><br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/MIR/X86/diexpr-win32.mir<br>
Modified:<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h<br>
    llvm/trunk/test/DebugInfo/COFF/pieces.ll<br>
    llvm/trunk/test/DebugInfo/COFF/types-array-advanced.ll<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=311957&r1=311956&r2=311957&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=311957&r1=311956&r2=311957&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Mon Aug 28 17:06:59 2017<br>
@@ -949,13 +949,103 @@ void CodeViewDebug::collectVariableInfoF<br>
   }<br>
 }<br>
<br>
+void CodeViewDebug::calculateRanges(<br>
+    LocalVariable &Var, const DbgValueHistoryMap::InstrRanges &Ranges) {<br>
+  const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo();<br>
+<br>
+  // calculate the definition ranges.<br>
+  for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {<br>
+    const InsnRange &Range = *I;<br>
+    const MachineInstr *DVInst = Range.first;<br>
+    assert(DVInst->isDebugValue() && "Invalid History entry");<br>
+    // FIXME: Find a way to represent constant variables, since they are<br>
+    // relatively common.<br>
+    DbgVariableLocation Location;<br>
+    bool Supported =<br>
+        DbgVariableLocation::extractFromMachineInstruction(Location, *DVInst);<br>
+<br>
+    // Because we cannot express DW_OP_deref in CodeView directly,<br>
+    // we use a trick: we encode the type as a reference to the<br>
+    // real type.<br>
+    if (Var.Deref) {<br>
+      // When we're encoding the type as a reference to the original type,<br>
+      // we need to remove a level of indirection from incoming locations.<br>
+      // E.g. [RSP+8] with DW_OP_deref becomes [RSP+8],<br>
+      // and [RCX+0] without DW_OP_deref becomes RCX.<br>
+      if (!Location.Deref) {<br>
+        if (Location.InMemory)<br>
+          Location.InMemory = false;<br>
+        else<br>
+          Supported = false;<br>
+      }<br>
+    } else if (Location.Deref) {<br>
+      // We've encountered a Deref range when we had not applied the<br>
+      // reference encoding. Start over using reference encoding.<br>
+      Var.Deref = true;<br>
+      Var.DefRanges.clear();<br>
+      calculateRanges(Var, Ranges);<br>
+      return;<br>
+    }<br>
+<br>
+    // If we don't know how to handle this range, skip past it.<br>
+    if (!Supported || (Location.Offset && !Location.InMemory))<br>
+      continue;<br>
+<br>
+    // Handle the two cases we can handle: indirect in memory and in register.<br>
+    {<br>
+      LocalVarDefRange DR;<br>
+      DR.CVRegister = TRI->getCodeViewRegNum(Location.Register);<br>
+      DR.InMemory = Location.InMemory;<br>
+      DR.DataOffset = Location.Offset;<br>
+      if (Location.FragmentInfo) {<br>
+        DR.IsSubfield = true;<br>
+        DR.StructOffset = Location.FragmentInfo->OffsetInBits / 8;<br>
+      } else {<br>
+        DR.IsSubfield = false;<br>
+        DR.StructOffset = 0;<br>
+      }<br>
+<br>
+      if (Var.DefRanges.empty() ||<br>
+          Var.DefRanges.back().isDifferentLocation(DR)) {<br>
+        Var.DefRanges.emplace_back(std::move(DR));<br>
+      }<br>
+    }<br>
+<br>
+    // Compute the label range.<br>
+    const MCSymbol *Begin = getLabelBeforeInsn(Range.first);<br>
+    const MCSymbol *End = getLabelAfterInsn(Range.second);<br>
+    if (!End) {<br>
+      // This range is valid until the next overlapping bitpiece. In the<br>
+      // common case, ranges will not be bitpieces, so they will overlap.<br>
+      auto J = std::next(I);<br>
+      const DIExpression *DIExpr = DVInst->getDebugExpression();<br>
+      while (J != E &&<br>
+             !fragmentsOverlap(DIExpr, J->first->getDebugExpression()))<br>
+        ++J;<br>
+      if (J != E)<br>
+        End = getLabelBeforeInsn(J->first);<br>
+      else<br>
+        End = Asm->getFunctionEnd();<br>
+    }<br>
+<br>
+    // If the last range end is our begin, just extend the last range.<br>
+    // Otherwise make a new range.<br>
+    SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &R =<br>
+        Var.DefRanges.back().Ranges;<br>
+    if (!R.empty() && R.back().second == Begin)<br>
+      R.back().second = End;<br>
+    else<br>
+      R.emplace_back(Begin, End);<br>
+<br>
+    // FIXME: Do more range combining.<br>
+  }<br>
+}<br>
+<br>
 void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {<br>
   DenseSet<InlinedVariable> Processed;<br>
   // Grab the variable info that was squirreled away in the MMI side-table.<br>
   collectVariableInfoFromMFTable(Processed);<br>
<br>
-  const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo();<br>
-<br>
   for (const auto &I : DbgValues) {<br>
     InlinedVariable IV = I.first;<br>
     if (Processed.count(IV))<br>
@@ -978,89 +1068,7 @@ void CodeViewDebug::collectVariableInfo(<br>
     LocalVariable Var;<br>
     Var.DIVar = DIVar;<br>
<br>
-    // Calculate the definition ranges.<br>
-    for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {<br>
-      const InsnRange &Range = *I;<br>
-      const MachineInstr *DVInst = Range.first;<br>
-      assert(DVInst->isDebugValue() && "Invalid History entry");<br>
-      const DIExpression *DIExpr = DVInst->getDebugExpression();<br>
-      bool InMemory = DVInst->getOperand(1).isImm();<br>
-      bool IsSubfield = false;<br>
-      unsigned StructOffset = 0;<br>
-      // Recognize a +Offset expression.<br>
-      int Offset = 0;<br>
-      DIExpressionCursor Ops(DIExpr);<br>
-      auto Op = Ops.peek();<br>
-      if (Op && Op->getOp() == dwarf::DW_OP_plus_uconst) {<br>
-        Offset = Op->getArg(0);<br>
-        Ops.take();<br>
-      }<br>
-<br>
-      // Handle fragments.<br>
-      auto Fragment = Ops.getFragmentInfo();<br>
-      if (Fragment) {<br>
-        IsSubfield = true;<br>
-        StructOffset = Fragment->OffsetInBits / 8;<br>
-      }<br>
-      // Ignore unrecognized exprs.<br>
-      if (Ops.peek() && Ops.peek()->getOp() != dwarf::DW_OP_LLVM_fragment)<br>
-        continue;<br>
-      if (!InMemory && Offset)<br>
-        continue;<br>
-<br>
-      // Bail if operand 0 is not a valid register. This means the variable is a<br>
-      // simple constant, or is described by a complex expression.<br>
-      // FIXME: Find a way to represent constant variables, since they are<br>
-      // relatively common.<br>
-      unsigned Reg =<br>
-          DVInst->getOperand(0).isReg() ? DVInst->getOperand(0).getReg() : 0;<br>
-      if (Reg == 0)<br>
-        continue;<br>
-<br>
-      // Handle the two cases we can handle: indirect in memory and in register.<br>
-      unsigned CVReg = TRI->getCodeViewRegNum(Reg);<br>
-      {<br>
-        LocalVarDefRange DR;<br>
-        DR.CVRegister = CVReg;<br>
-        DR.InMemory = InMemory;<br>
-        DR.DataOffset = Offset;<br>
-        DR.IsSubfield = IsSubfield;<br>
-        DR.StructOffset = StructOffset;<br>
-<br>
-        if (Var.DefRanges.empty() ||<br>
-            Var.DefRanges.back().isDifferentLocation(DR)) {<br>
-          Var.DefRanges.emplace_back(std::move(DR));<br>
-        }<br>
-      }<br>
-<br>
-      // Compute the label range.<br>
-      const MCSymbol *Begin = getLabelBeforeInsn(Range.first);<br>
-      const MCSymbol *End = getLabelAfterInsn(Range.second);<br>
-      if (!End) {<br>
-        // This range is valid until the next overlapping bitpiece. In the<br>
-        // common case, ranges will not be bitpieces, so they will overlap.<br>
-        auto J = std::next(I);<br>
-        while (J != E &&<br>
-               !fragmentsOverlap(DIExpr, J->first->getDebugExpression()))<br>
-          ++J;<br>
-        if (J != E)<br>
-          End = getLabelBeforeInsn(J->first);<br>
-        else<br>
-          End = Asm->getFunctionEnd();<br>
-      }<br>
-<br>
-      // If the last range end is our begin, just extend the last range.<br>
-      // Otherwise make a new range.<br>
-      SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &Ranges =<br>
-          Var.DefRanges.back().Ranges;<br>
-      if (!Ranges.empty() && Ranges.back().second == Begin)<br>
-        Ranges.back().second = End;<br>
-      else<br>
-        Ranges.emplace_back(Begin, End);<br>
-<br>
-      // FIXME: Do more range combining.<br>
-    }<br>
-<br>
+    calculateRanges(Var, Ranges);<br>
     recordLocalVariable(std::move(Var), InlinedAt);<br>
   }<br>
 }<br>
@@ -1987,6 +1995,16 @@ TypeIndex CodeViewDebug::getTypeIndex(DI<br>
   return recordTypeIndexForDINode(Ty, TI, ClassTy);<br>
 }<br>
<br>
+TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(DITypeRef TypeRef) {<br>
+  DIType *Ty = TypeRef.resolve();<br>
+  PointerRecord PR(getTypeIndex(Ty),<br>
+                   getPointerSizeInBytes() == 8 ? PointerKind::Near64<br>
+                                                : PointerKind::Near32,<br>
+                   PointerMode::LValueReference, PointerOptions::None,<br>
+                   Ty->getSizeInBits() / 8);<br>
+  return TypeTable.writeKnownType(PR);<br>
+}<br>
+<br>
 TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) {<br>
   const DIType *Ty = TypeRef.resolve();<br>
<br>
@@ -2094,7 +2112,8 @@ void CodeViewDebug::emitLocalVariable(co<br>
     Flags |= LocalSymFlags::IsOptimizedOut;<br>
<br>
   OS.AddComment("TypeIndex");<br>
-  TypeIndex TI = getCompleteTypeIndex(Var.DIVar->getType());<br>
+  TypeIndex TI = Var.Deref ? getTypeIndexForReferenceTo(Var.DIVar->getType())<br>
+                           : getCompleteTypeIndex(Var.DIVar->getType());<br>
   OS.EmitIntValue(TI.getIndex(), 4);<br>
   OS.AddComment("Flags");<br>
   OS.EmitIntValue(static_cast<uint16_t>(Flags), 2);<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=311957&r1=311956&r2=311957&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=311957&r1=311956&r2=311957&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h Mon Aug 28 17:06:59 2017<br>
@@ -94,6 +94,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe<br>
   struct LocalVariable {<br>
     const DILocalVariable *DIVar = nullptr;<br>
     SmallVector<LocalVarDefRange, 1> DefRanges;<br>
+    bool Deref = false;<br>
   };<br>
<br>
   struct InlineSite {<br>
@@ -147,6 +148,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe<br>
<br>
   codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP);<br>
<br>
+  void calculateRanges(LocalVariable &Var,<br>
+                       const DbgValueHistoryMap::InstrRanges &Ranges);<br>
+<br>
   static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children,<br>
                                         const FunctionInfo &FI,<br>
                                         const InlineSite &Site);<br>
@@ -259,6 +263,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe<br>
   codeview::TypeIndex getTypeIndex(DITypeRef TypeRef,<br>
                                    DITypeRef ClassTyRef = DITypeRef());<br>
<br>
+  codeview::TypeIndex getTypeIndexForReferenceTo(DITypeRef TypeRef);<br>
+<br>
   codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP,<br>
                                             const DICompositeType *Class);<br>
<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp?rev=311957&r1=311956&r2=311957&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp?rev=311957&r1=311956&r2=311957&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp Mon Aug 28 17:06:59 2017<br>
@@ -23,6 +23,57 @@<br>
<br>
 using namespace llvm;<br>
<br>
+bool DbgVariableLocation::extractFromMachineInstruction(<br>
+    DbgVariableLocation &Location, const MachineInstr &Instruction) {<br>
+  if (!Instruction.isDebugValue())<br>
+    return false;<br>
+  if (!Instruction.getOperand(0).isReg())<br>
+    return false;<br>
+  Location.Register = Instruction.getOperand(0).getReg();<br>
+  Location.InMemory = Instruction.getOperand(1).isImm();<br>
+  Location.Deref = false;<br>
+  Location.FragmentInfo.reset();<br>
+  // We only handle expressions generated by DIExpression::appendOffset,<br>
+  // which doesn't require a full stack machine.<br>
+  int64_t Offset = 0;<br>
+  const DIExpression *DIExpr = Instruction.getDebugExpression();<br>
+  auto Op = DIExpr->expr_op_begin();<br>
+  while (Op != DIExpr->expr_op_end()) {<br>
+    switch (Op->getOp()) {<br>
+    case dwarf::DW_OP_constu: {<br>
+      int Value = Op->getArg(0);<br>
+      ++Op;<br>
+      if (Op != DIExpr->expr_op_end()) {<br>
+        switch (Op->getOp()) {<br>
+        case dwarf::DW_OP_minus:<br>
+          Offset -= Value;<br>
+          break;<br>
+        case dwarf::DW_OP_plus:<br>
+          Offset += Value;<br>
+        default:<br>
+          continue;<br>
+        }<br>
+      }<br>
+    } break;<br>
+    case dwarf::DW_OP_plus_uconst:<br>
+      Offset += Op->getArg(0);<br>
+      break;<br>
+    case dwarf::DW_OP_LLVM_fragment:<br>
+      Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)};<br>
+      break;<br>
+    case dwarf::DW_OP_deref:<br>
+      Location.Deref = true;<br>
+      break;<br>
+    default:<br>
+      return false;<br>
+    }<br>
+    ++Op;<br>
+  }<br>
+<br>
+  Location.Offset = Offset;<br>
+  return true;<br>
+}<br>
+<br>
 DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}<br>
<br>
 // Each LexicalScope has first instruction and last instruction to mark<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h?rev=311957&r1=311956&r2=311957&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h?rev=311957&r1=311956&r2=311957&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h Mon Aug 28 17:06:59 2017<br>
@@ -17,14 +17,44 @@<br>
<br>
 #include "AsmPrinterHandler.h"<br>
 #include "DbgValueHistoryCalculator.h"<br>
+#include "llvm/ADT/Optional.h"<br>
 #include "llvm/CodeGen/LexicalScopes.h"<br>
 #include "llvm/CodeGen/MachineInstr.h"<br>
+#include "llvm/IR/DebugInfoMetadata.h"<br>
<br>
 namespace llvm {<br>
<br>
 class AsmPrinter;<br>
+class MachineInstr;<br>
 class MachineModuleInfo;<br>
<br>
+/// Represents the location at which a variable is stored.<br>
+struct DbgVariableLocation {<br>
+  /// Offset relative to base register.<br>
+  int64_t Offset;<br>
+<br>
+  /// Base register.<br>
+  unsigned Register;<br>
+<br>
+  /// If false, Register is the location. If true,<br>
+  /// Register+Offset point at the location.<br>
+  unsigned InMemory : 1;<br>
+<br>
+  /// If false, the location holds the variable's value.<br>
+  /// If true, the location holds the variable's address.<br>
+  unsigned Deref : 1;<br>
+<br>
+  /// Present if the location is part of a larger variable.<br>
+  llvm::Optional<llvm::DIExpression::FragmentInfo> FragmentInfo;<br>
+<br>
+  /// Extract a VariableLocation from a MachineInstr.  The struct passed in as<br>
+  /// Location is populated.  The MachineInstr must be a debug value<br>
+  /// instruction.<br>
+  /// @return true if successful and false if not.<br>
+  static bool extractFromMachineInstruction(DbgVariableLocation &Location,<br>
+                                            const MachineInstr &Instruction);<br>
+};<br>
+<br>
 /// Base class for debug information backends. Common functionality related to<br>
 /// tracking which variables and scopes are alive at a given PC live here.<br>
 class DebugHandlerBase : public AsmPrinterHandler {<br>
<br>
Added: llvm/trunk/test/CodeGen/MIR/X86/diexpr-win32.mir<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/diexpr-win32.mir?rev=311957&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/diexpr-win32.mir?rev=311957&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/MIR/X86/diexpr-win32.mir (added)<br>
+++ llvm/trunk/test/CodeGen/MIR/X86/diexpr-win32.mir Mon Aug 28 17:06:59 2017<br>
@@ -0,0 +1,253 @@<br>
+# RUN: llc -filetype=obj -O0 %s -o - | llvm-readobj -codeview | FileCheck %s<br>
+#<br>
+# (DW_OP_plus_uconst 12)<br>
+# CHECK: LocalSym {<br>
+# CHECK-NEXT:   Kind: S_LOCAL (0x113E)<br>
+# CHECK-NEXT:   Type: string* (0x<br>
+# CHECK-NEXT:   Flags [ (0x0)<br>
+# CHECK-NEXT:   ]<br>
+# CHECK-NEXT:   VarName: Str<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: DefRangeRegisterRelSym {<br>
+# CHECK-NEXT:   Kind: S_DEFRANGE_REGISTER_REL (0x1145)<br>
+# CHECK-NEXT:   BaseRegister:<br>
+# CHECK-NEXT:   HasSpilledUDTMember: No<br>
+# CHECK-NEXT:   OffsetInParent: 0<br>
+# CHECK-NEXT:   BasePointerOffset: 12<br>
+# CHECK-NEXT:   LocalVariableAddrRange {<br>
+# CHECK-NEXT:     OffsetStart:<br>
+# CHECK-NEXT:     ISectStart:<br>
+# CHECK-NEXT:     Range:<br>
+# CHECK-NEXT:   }<br>
+# CHECK-NEXT: }<br>
+# (DW_OP_plus_uconst, 8, DW_OP_deref)<br>
+# CHECK: LocalSym {<br>
+# CHECK-NEXT:   Kind: S_LOCAL (0x113E)<br>
+# CHECK-NEXT:   Type: string& (0x<br>
+# CHECK-NEXT:   Flags [ (0x0)<br>
+# CHECK-NEXT:   ]<br>
+# CHECK-NEXT:   VarName: Result<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: DefRangeRegisterRelSym {<br>
+# CHECK-NEXT:   Kind: S_DEFRANGE_REGISTER_REL (0x1145)<br>
+# CHECK-NEXT:   BaseRegister:<br>
+# CHECK-NEXT:   HasSpilledUDTMember: No<br>
+# CHECK-NEXT:   OffsetInParent: 0<br>
+# CHECK-NEXT:   BasePointerOffset: 8<br>
+# CHECK-NEXT:   LocalVariableAddrRange {<br>
+# CHECK-NEXT:     OffsetStart:<br>
+# CHECK-NEXT:     ISectStart:<br>
+# CHECK-NEXT:     Range:<br>
+# CHECK-NEXT:   }<br>
+# CHECK-NEXT: }<br>
+# (DW_OP_constu, 4, DW_OP_minus)<br>
+# CHECK: LocalSym {<br>
+# CHECK-NEXT:   Kind: S_LOCAL (0x113E)<br>
+# CHECK-NEXT:   Type: long (0x12)<br>
+# CHECK-NEXT:   Flags [ (0x0)<br>
+# CHECK-NEXT:   ]<br>
+# CHECK-NEXT:   VarName: Bytes<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: DefRangeRegisterRelSym {<br>
+# CHECK-NEXT:   Kind: S_DEFRANGE_REGISTER_REL (0x1145)<br>
+# CHECK-NEXT:   BaseRegister:<br>
+# CHECK-NEXT:   HasSpilledUDTMember: No<br>
+# CHECK-NEXT:   OffsetInParent: 0<br>
+# CHECK-NEXT:   BasePointerOffset: -4<br>
+# CHECK-NEXT:   LocalVariableAddrRange {<br>
+# CHECK-NEXT:     OffsetStart:<br>
+# CHECK-NEXT:     ISectStart:<br>
+# CHECK-NEXT:     Range:<br>
+# CHECK-NEXT:   }<br>
+# CHECK-NEXT: }<br>
+--- |<br>
+  ; ModuleID = '<stdin>'<br>
+  source_filename = "<stdin>"<br>
+  target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"<br>
+  target triple = "i386-pc-windows-msvc19.0.24215"<br>
+<br>
+  %struct.string = type { i32, i32, i8* }<br>
+<br>
+  define void @fun(%struct.string* noalias sret %agg.result, %struct.string* noalias %str) !dbg !12 {<br>
+  entry:<br>
+    call void @llvm.dbg.value(metadata %struct.string* %agg.result, metadata !23, metadata !24), !dbg !25<br>
+    call void @llvm.dbg.value(metadata %struct.string* %str, metadata !26, metadata !28), !dbg !25<br>
+    %call = call dereferenceable(12) %struct.string* @getString(), !dbg !29<br>
+    %0 = bitcast %struct.string* %agg.result to i8*, !dbg !29<br>
+    %1 = bitcast %struct.string* %call to i8*, !dbg !29<br>
+    call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 12, i32 4, i1 false), !dbg !29<br>
+    ret void, !dbg !30<br>
+  }<br>
+<br>
+  define i32 @len(%struct.string* %s, i32 %acc) !dbg !31 {<br>
+  entry:<br>
+    %0 = bitcast %struct.string* %s to i32*<br>
+    %bytes = load i32, i32* %0, !dbg !34<br>
+    call void @llvm.dbg.declare(metadata i32 %bytes, metadata !35, metadata !28), !dbg !34<br>
+    %1 = add i32 %bytes, %acc, !dbg !36<br>
+    ret i32 %1, !dbg !36<br>
+  }<br>
+<br>
+  ; Function Attrs: nounwind readnone speculatable<br>
+  declare void @llvm.dbg.declare(metadata, metadata, metadata) #0<br>
+<br>
+  ; Function Attrs: nounwind readnone speculatable<br>
+  declare void @llvm.dbg.value(metadata, metadata, metadata) #0<br>
+<br>
+  declare dereferenceable(12) %struct.string* @getString()<br>
+<br>
+  ; Function Attrs: argmemonly nounwind<br>
+  declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i1) #1<br>
+<br>
+  ; Function Attrs: nounwind<br>
+  declare void @llvm.stackprotector(i8*, i8**) #2<br>
+<br>
+  attributes #0 = { nounwind readnone speculatable }<br>
+  attributes #1 = { argmemonly nounwind }<br>
+  attributes #2 = { nounwind }<br>
+<br>
+  !<a href="http://llvm.dbg.cu" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
+  !llvm.linker.options = !{!3, !4}<br>
+  !llvm.module.flags = !{!5, !6, !7, !8}<br>
+  !llvm.ident = !{!9}<br>
+<br>
+  !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)<br>
+  !1 = !DIFile(filename: "diexpr.ll", directory: "C:\5Csrc", checksumkind: CSK_MD5, checksum: "c547c362c610fa79e7abaddc76e1efe7")<br>
+  !2 = !{}<br>
+  !3 = !{!"/DEFAULTLIB:libcmt.lib"}<br>
+  !4 = !{!"/DEFAULTLIB:oldnames.lib"}<br>
+  !5 = !{i32 1, !"NumRegisterParameters", i32 0}<br>
+  !6 = !{i32 2, !"CodeView", i32 1}<br>
+  !7 = !{i32 2, !"Debug Info Version", i32 3}<br>
+  !8 = !{i32 1, !"wchar_size", i32 2}<br>
+  !9 = !{!"clang version 6.0.0 "}<br>
+  !10 = !DIExpression(DW_OP_plus_uconst, 12)<br>
+  !11 = !DIExpression(DW_OP_plus_uconst, 8, DW_OP_deref)<br>
+  !12 = distinct !DISubprogram(name: "fun", linkageName: "fun", scope: !1, file: !1, line: 9, type: !13, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)<br>
+  !13 = !DISubroutineType(types: !14)<br>
+  !14 = !{!15}<br>
+  !15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "string", file: !1, line: 1, size: 96, elements: !16, identifier: ".?AUstring@@")<br>
+  !16 = !{!17, !19, !20}<br>
+  !17 = !DIDerivedType(tag: DW_TAG_member, name: "length", scope: !15, file: !1, line: 2, baseType: !18, size: 32)<br>
+  !18 = !DIBasicType(name: "long int", size: 32, encoding: DW_ATE_signed)<br>
+  !19 = !DIDerivedType(tag: DW_TAG_member, name: "size", scope: !15, file: !1, line: 3, baseType: !18, size: 32, offset: 32)<br>
+  !20 = !DIDerivedType(tag: DW_TAG_member, name: "data", scope: !15, file: !1, line: 4, baseType: !21, size: 32, offset: 64)<br>
+  !21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 32)<br>
+  !22 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)<br>
+  !23 = !DILocalVariable(name: "Result", scope: !12, file: !1, line: 10, type: !15)<br>
+  !24 = !DIExpression(DW_OP_deref)<br>
+  !25 = !DILocation(line: 10, scope: !12)<br>
+  !26 = !DILocalVariable(name: "Str", scope: !12, file: !1, line: 10, type: !27)<br>
+  !27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !15, size: 32)<br>
+  !28 = !DIExpression(DW_OP_constu, 4, DW_OP_minus)<br>
+  !29 = !DILocation(line: 11, scope: !12)<br>
+  !30 = !DILocation(line: 12, scope: !12)<br>
+  !31 = distinct !DISubprogram(name: "len", linkageName: "len", scope: !1, file: !1, line: 14, type: !32, isLocal: false, isDefinition: true, scopeLine: 14, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)<br>
+  !32 = !DISubroutineType(types: !33)<br>
+  !33 = !{!18}<br>
+  !34 = !DILocation(line: 15, scope: !31)<br>
+  !35 = !DILocalVariable(name: "Bytes", scope: !31, file: !1, line: 15, type: !18)<br>
+  !36 = !DILocation(line: 16, scope: !31)<br>
+<br>
+...<br>
+---<br>
+name:            fun<br>
+alignment:       4<br>
+exposesReturnsTwice: false<br>
+legalized:       false<br>
+regBankSelected: false<br>
+selected:        false<br>
+tracksRegLiveness: true<br>
+registers:<br>
+liveins:<br>
+frameInfo:<br>
+  isFrameAddressTaken: false<br>
+  isReturnAddressTaken: false<br>
+  hasStackMap:     false<br>
+  hasPatchPoint:   false<br>
+  stackSize:       4<br>
+  offsetAdjustment: 0<br>
+  maxAlignment:    4<br>
+  adjustsStack:    true<br>
+  hasCalls:        true<br>
+  stackProtector:  ''<br>
+  maxCallFrameSize: 0<br>
+  hasOpaqueSPAdjustment: false<br>
+  hasVAStart:      false<br>
+  hasMustTailInVarArgFunc: false<br>
+  savePoint:       ''<br>
+  restorePoint:    ''<br>
+fixedStack:<br>
+  - { id: 0, type: spill-slot, offset: -8, size: 4, alignment: 4, stack-id: 0,<br>
+      callee-saved-register: '%esi' }<br>
+  - { id: 1, type: default, offset: 4, size: 4, alignment: 4, stack-id: 0,<br>
+      isImmutable: true, isAliased: false, callee-saved-register: '' }<br>
+  - { id: 2, type: default, offset: 0, size: 4, alignment: 4, stack-id: 0,<br>
+      isImmutable: true, isAliased: false, callee-saved-register: '' }<br>
+stack:<br>
+constants:<br>
+body:             |<br>
+  bb.0.entry:<br>
+    liveins: %esi<br>
+<br>
+    frame-setup PUSH32r killed %esi, implicit-def %esp, implicit %esp<br>
+    CFI_INSTRUCTION def_cfa_offset 8<br>
+    CFI_INSTRUCTION offset %esi, -8<br>
+    %esi = MOV32rm %esp, 1, _, 8, _ :: (load 4 from %fixed-stack.2)<br>
+    DBG_VALUE %esp, 0, !26, !10, debug-location !25<br>
+    DBG_VALUE %esp, 0, !23, !11, debug-location !25<br>
+    CALLpcrel32 @getString, csr_32, implicit %esp, implicit-def %esp, implicit-def %eax, debug-location !29<br>
+    %ecx = MOV32rm %eax, 1, _, 0, _, debug-location !29 :: (dereferenceable load 4 from %ir.1)<br>
+    %edx = MOV32rm %eax, 1, _, 4, _, debug-location !29 :: (dereferenceable load 4 from %ir.1 + 4)<br>
+    MOV32mr %esi, 1, _, 0, _, killed %ecx, debug-location !29 :: (store 4 into %ir.0)<br>
+    MOV32mr %esi, 1, _, 4, _, killed %edx, debug-location !29 :: (store 4 into %ir.0 + 4)<br>
+    %eax = MOV32rm killed %eax, 1, _, 8, _, debug-location !29 :: (dereferenceable load 4 from %ir.1 + 8)<br>
+    MOV32mr %esi, 1, _, 8, _, killed %eax, debug-location !29 :: (store 4 into %ir.0 + 8)<br>
+    %eax = COPY killed %esi, debug-location !30<br>
+    %esi = POP32r implicit-def %esp, implicit %esp, debug-location !30<br>
+    RET 0, %eax, debug-location !30<br>
+<br>
+...<br>
+---<br>
+name:            len<br>
+alignment:       4<br>
+exposesReturnsTwice: false<br>
+legalized:       false<br>
+regBankSelected: false<br>
+selected:        false<br>
+tracksRegLiveness: true<br>
+registers:<br>
+liveins:<br>
+frameInfo:<br>
+  isFrameAddressTaken: false<br>
+  isReturnAddressTaken: false<br>
+  hasStackMap:     false<br>
+  hasPatchPoint:   false<br>
+  stackSize:       0<br>
+  offsetAdjustment: 0<br>
+  maxAlignment:    4<br>
+  adjustsStack:    false<br>
+  hasCalls:        false<br>
+  stackProtector:  ''<br>
+  maxCallFrameSize: 0<br>
+  hasOpaqueSPAdjustment: false<br>
+  hasVAStart:      false<br>
+  hasMustTailInVarArgFunc: false<br>
+  savePoint:       ''<br>
+  restorePoint:    ''<br>
+fixedStack:<br>
+  - { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: 0,<br>
+      isImmutable: true, isAliased: false, callee-saved-register: '' }<br>
+  - { id: 1, type: default, offset: 0, size: 4, alignment: 4, stack-id: 0,<br>
+      isImmutable: true, isAliased: false, callee-saved-register: '' }<br>
+stack:<br>
+constants:<br>
+body:             |<br>
+  bb.0.entry:<br>
+    %eax = MOV32rm %esp, 1, _, 4, _ :: (load 4 from %fixed-stack.1)<br>
+    %eax = MOV32rm killed %eax, 1, _, 0, _, debug-location !34 :: (load 4 from %ir.0)<br>
+    DBG_VALUE debug-use %eax, 0, !35, !28, debug-location !34<br>
+    %eax = ADD32rm killed %eax, %esp, 1, _, 8, _, implicit-def dead %eflags, debug-location !36 :: (load 4 from %fixed-stack.0)<br>
+    RET 0, %eax, debug-location !36<br>
+<br>
+...<br>
<br>
Modified: llvm/trunk/test/DebugInfo/COFF/pieces.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/pieces.ll?rev=311957&r1=311956&r2=311957&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/pieces.ll?rev=311957&r1=311956&r2=311957&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/DebugInfo/COFF/pieces.ll (original)<br>
+++ llvm/trunk/test/DebugInfo/COFF/pieces.ll Mon Aug 28 17:06:59 2017<br>
@@ -179,8 +179,7 @@<br>
 ; ASM:        .asciz  "nested"                # Function name<br>
 ; ASM:        .short  4414                    # Record kind: S_LOCAL<br>
 ; ASM:        .asciz  "o"<br>
-; FIXME: We should have a .cv_def_range for 'o', but we don't yet.<br>
-; ASM-NOT:    .cv_def_range<br>
+; ASM:        .cv_def_range    .Lfunc_begin3 .Lfunc_end3, "E\021J\001\000\000\000\000\000\000"<br>
 ; ASM:        .short  4414                    # Record kind: S_LOCAL<br>
 ; ASM:        .asciz  "p"<br>
 ; ASM:        .cv_def_range    [[p_start]] .Lfunc_end3, "C\021\021\000\000\000\004\000\000\000"<br>
@@ -190,8 +189,17 @@<br>
 ; OBJ:         DisplayName: nested<br>
 ; OBJ:       }<br>
 ; OBJ:       LocalSym {<br>
+; OBJ:         Type: Nested&<br>
 ; OBJ:         VarName: o<br>
 ; OBJ:       }<br>
+; OBJ:       DefRangeRegisterRelSym {<br>
+; OBJ:         BaseRegister: 330<br>
+; OBJ:         HasSpilledUDTMember: No<br>
+; OBJ:         OffsetInParent: 0<br>
+; OBJ:         BasePointerOffset: 0<br>
+; OBJ:         LocalVariableAddrRange {<br>
+; OBJ:         }<br>
+; OBJ:       }<br>
 ; OBJ:       LocalSym {<br>
 ; OBJ:         VarName: p<br>
 ; OBJ:       }<br>
<br>
Modified: llvm/trunk/test/DebugInfo/COFF/types-array-advanced.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/types-array-advanced.ll?rev=311957&r1=311956&r2=311957&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/types-array-advanced.ll?rev=311957&r1=311956&r2=311957&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/DebugInfo/COFF/types-array-advanced.ll (original)<br>
+++ llvm/trunk/test/DebugInfo/COFF/types-array-advanced.ll Mon Aug 28 17:06:59 2017<br>
@@ -50,28 +50,40 @@<br>
 ; CHECK:     SizeOf: 4<br>
 ; CHECK:     Name:<br>
 ; CHECK:   }<br>
-; CHECK:   Array (0x1004) {<br>
+; CHECK:   Pointer (0x1004) {<br>
+; CHECK:     TypeLeafKind: LF_POINTER (0x1002)<br>
+; CHECK:     PointeeType: 0x1003<br>
+; CHECK:     PointerAttributes: 0x2A<br>
+; CHECK:     PtrType: Near32 (0xA)<br>
+; CHECK:     PtrMode: LValueReference (0x1)<br>
+; CHECK:     IsFlat: 0<br>
+; CHECK:     IsConst: 0<br>
+; CHECK:     IsVolatile: 0<br>
+; CHECK:     IsUnaligned: 0<br>
+; CHECK:     SizeOf: 0<br>
+; CHECK:   }<br>
+; CHECK:   Array (0x1005) {<br>
 ; CHECK:     TypeLeafKind: LF_ARRAY (0x1503)<br>
 ; CHECK:     ElementType: char (0x70)<br>
 ; CHECK:     IndexType: unsigned long (0x22)<br>
 ; CHECK:     SizeOf: 7<br>
 ; CHECK:     Name:<br>
 ; CHECK:   }<br>
-; CHECK:   Array (0x1005) {<br>
+; CHECK:   Array (0x1006) {<br>
 ; CHECK:     TypeLeafKind: LF_ARRAY (0x1503)<br>
-; CHECK:     ElementType: 0x1004<br>
+; CHECK:     ElementType: 0x1005<br>
 ; CHECK:     IndexType: unsigned long (0x22)<br>
 ; CHECK:     SizeOf: 35<br>
 ; CHECK:     Name:<br>
 ; CHECK:   }<br>
-; CHECK:   Array (0x1006) {<br>
+; CHECK:   Array (0x1007) {<br>
 ; CHECK:     TypeLeafKind: LF_ARRAY (0x1503)<br>
-; CHECK:     ElementType: 0x1005<br>
+; CHECK:     ElementType: 0x1006<br>
 ; CHECK:     IndexType: unsigned long (0x22)<br>
 ; CHECK:     SizeOf: 70<br>
 ; CHECK:     Name:<br>
 ; CHECK:   }<br>
-; CHECK:   Struct (0x1007) {<br>
+; CHECK:   Struct (0x1008) {<br>
 ; CHECK:     TypeLeafKind: LF_STRUCTURE (0x1505)<br>
 ; CHECK:     MemberCount: 0<br>
 ; CHECK:     Properties [ (0x280)<br>
@@ -85,16 +97,16 @@<br>
 ; CHECK:     Name: incomplete_struct<br>
 ; CHECK:     LinkageName: .?AUincomplete_struct@@<br>
 ; CHECK:   }<br>
-; CHECK:   Array (0x1008) {<br>
+; CHECK:   Array (0x1009) {<br>
 ; CHECK:     TypeLeafKind: LF_ARRAY (0x1503)<br>
-; CHECK:     ElementType: incomplete_struct (0x1007)<br>
+; CHECK:     ElementType: incomplete_struct (0x1008)<br>
 ; CHECK:     IndexType: unsigned long (0x22)<br>
 ; CHECK:     SizeOf: 12<br>
 ; CHECK:     Name:<br>
 ; CHECK:   }<br>
-; CHECK:   Pointer (0x1009) {<br>
+; CHECK:   Pointer (0x100A) {<br>
 ; CHECK:     TypeLeafKind: LF_POINTER (0x1002)<br>
-; CHECK:     PointeeType: 0x1008<br>
+; CHECK:     PointeeType: 0x1009<br>
 ; CHECK:     PointerAttributes: 0x800A<br>
 ; CHECK:     PtrType: Near32 (0xA)<br>
 ; CHECK:     PtrMode: Pointer (0x0)<br>
@@ -104,8 +116,41 @@<br>
 ; CHECK:     IsUnaligned: 0<br>
 ; CHECK:     SizeOf: 4<br>
 ; CHECK:   }<br>
-;<br>
-; CHECK:   Modifier (0x100E) {<br>
+; CHECK:   FieldList (0x100B) {<br>
+; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)<br>
+; CHECK:     DataMember {<br>
+; CHECK:       TypeLeafKind: LF_MEMBER (0x150D)<br>
+; CHECK:       AccessSpecifier: Public (0x3)<br>
+; CHECK:       Type: int (0x74)<br>
+; CHECK:       FieldOffset: 0x0<br>
+; CHECK:       Name: s1<br>
+; CHECK:     }<br>
+; CHECK:   }<br>
+; CHECK:   Struct (0x100C) {<br>
+; CHECK:     TypeLeafKind: LF_STRUCTURE (0x1505)<br>
+; CHECK:     MemberCount: 1<br>
+; CHECK:     Properties [ (0x200)<br>
+; CHECK:       HasUniqueName (0x200)<br>
+; CHECK:     ]<br>
+; CHECK:     FieldList: <field list> (0x100B)<br>
+; CHECK:     DerivedFrom: 0x0<br>
+; CHECK:     VShape: 0x0<br>
+; CHECK:     SizeOf: 4<br>
+; CHECK:     Name: incomplete_struct<br>
+; CHECK:     LinkageName: .?AUincomplete_struct@@<br>
+; CHECK:   }<br>
+; CHECK:   StringId (0x100D) {<br>
+; CHECK:     TypeLeafKind: LF_STRING_ID (0x1605)<br>
+; CHECK:     Id: 0x0<br>
+; CHECK:     StringData: \t.cpp<br>
+; CHECK:   }<br>
+; CHECK:   UdtSourceLine (0x100E) {<br>
+; CHECK:     TypeLeafKind: LF_UDT_SRC_LINE (0x1606)<br>
+; CHECK:     UDT: incomplete_struct (0x100C)<br>
+; CHECK:     SourceFile: \t.cpp (0x100D)<br>
+; CHECK:     LineNumber: 4<br>
+; CHECK:   }<br>
+; CHECK:   Modifier (0x100F) {<br>
 ; CHECK:     TypeLeafKind: LF_MODIFIER (0x1001)<br>
 ; CHECK:     ModifiedType: int (0x74)<br>
 ; CHECK:     Modifiers [ (0x3)<br>
@@ -113,12 +158,12 @@<br>
 ; CHECK:       Volatile (0x2)<br>
 ; CHECK:     ]<br>
 ; CHECK:   }<br>
-; CHECK:   Array (0x100F) {<br>
+; CHECK:   Array (0x1010) {<br>
 ; CHECK:     TypeLeafKind: LF_ARRAY (0x1503)<br>
-; CHECK:     ElementType: const volatile int (0x100E)<br>
+; CHECK:     ElementType: const volatile int (0x100F)<br>
 ; CHECK:     IndexType: unsigned long (0x22)<br>
 ; CHECK:     SizeOf: 16<br>
-; CHECK:     Name:<br>
+; CHECK:     Name:<br>
 ; CHECK:   }<br>
 ; CHECK: ]<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>