[CodeView] Implement .cv_inline_linetable

This support is _very_ rudimentary, just enough to get some basic data
into the CodeView debug section.

Left to do is:
- Use the combined opcodes to save space.
- Do something about code offsets.

llvm-svn: 259230
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp
index 95cf7cc..a876470 100644
--- a/llvm/lib/MC/MCCodeView.cpp
+++ b/llvm/lib/MC/MCCodeView.cpp
@@ -15,6 +15,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCObjectStreamer.h"
 #include "llvm/Support/COFF.h"
@@ -151,11 +152,11 @@
   OS.EmitCOFFSectionIndex(FuncBegin);
 
   // Actual line info.
-  ArrayRef<MCCVLineEntry> Locs = getFunctionLineEntries(FuncId);
+  std::vector<MCCVLineEntry> Locs = getFunctionLineEntries(FuncId);
   bool HaveColumns = any_of(Locs, [](const MCCVLineEntry &LineEntry) {
     return LineEntry.getColumn() != 0;
   });
-  OS.EmitIntValue(HaveColumns ? int(codeview::LineFlags::HaveColumns) : 0, 2);
+  OS.EmitIntValue(HaveColumns ? int(LineFlags::HaveColumns) : 0, 2);
   OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 4);
 
   for (auto I = Locs.begin(), E = Locs.end(); I != E;) {
@@ -180,7 +181,7 @@
       OS.emitAbsoluteSymbolDiff(J->getLabel(), FuncBegin, 4);
       unsigned LineData = J->getLine();
       if (J->isStmt())
-        LineData |= codeview::LineInfo::StatementFlag;
+        LineData |= LineInfo::StatementFlag;
       OS.EmitIntValue(LineData, 4);
     }
     if (HaveColumns) {
@@ -194,6 +195,73 @@
   OS.EmitLabel(LineEnd);
 }
 
+static bool compressAnnotation(uint32_t Data, SmallVectorImpl<char> &Buffer) {
+  if (isUInt<7>(Data)) {
+    Buffer.push_back(Data);
+    return true;
+  }
+
+  if (isUInt<14>(Data)) {
+    Buffer.push_back((Data >> 8) | 0x80);
+    Buffer.push_back(Data & 0xff);
+    return true;
+  }
+
+  if (isUInt<29>(Data)) {
+    Buffer.push_back((Data >> 24) | 0xC0);
+    Buffer.push_back((Data >> 16) & 0xff);
+    Buffer.push_back((Data >> 8) & 0xff);
+    Buffer.push_back(Data & 0xff);
+    return true;
+  }
+
+  return false;
+}
+
+static uint32_t encodeSignedNumber(uint32_t Data) {
+  if (Data >> 31)
+    return ((-Data) << 1) | 1;
+  return Data << 1;
+}
+
+void CodeViewContext::emitInlineLineTableForFunction(
+    MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId,
+    unsigned SourceLineNum, ArrayRef<unsigned> SecondaryFunctionIds) {
+  std::vector<MCCVLineEntry> Locs = getFunctionLineEntries(PrimaryFunctionId);
+  std::vector<std::pair<BinaryAnnotationsOpCode, uint32_t>> Annotations;
+
+  const MCCVLineEntry *LastLoc = nullptr;
+  unsigned LastFileId = SourceFileId;
+  unsigned LastLineNum = SourceLineNum;
+
+  for (const MCCVLineEntry &Loc : Locs) {
+    if (!LastLoc) {
+      // TODO ChangeCodeOffset
+      // TODO ChangeCodeLength
+    }
+
+    if (Loc.getFileNum() != LastFileId)
+      Annotations.push_back({ChangeFile, Loc.getFileNum()});
+
+    if (Loc.getLine() != LastLineNum)
+      Annotations.push_back(
+          {ChangeLineOffset, encodeSignedNumber(Loc.getLine() - LastLineNum)});
+
+    LastLoc = &Loc;
+    LastFileId = Loc.getFileNum();
+    LastLineNum = Loc.getLine();
+  }
+
+  SmallString<32> Buffer;
+  for (auto Annotation : Annotations) {
+    BinaryAnnotationsOpCode Opcode = Annotation.first;
+    uint32_t Operand = Annotation.second;
+    compressAnnotation(Opcode, Buffer);
+    compressAnnotation(Operand, Buffer);
+  }
+  OS.EmitBytes(Buffer);
+}
+
 //
 // This is called when an instruction is assembled into the specified section
 // and if there is information from the last .cv_loc directive that has yet to have