Make CodeView record serialization more generic.

This introduces a variadic template and some helper macros to
safely and correctly deserialize many types of common record
fields while maintaining error checking.

Differential Revision: http://reviews.llvm.org/D20183
Reviewed By: rnk, amccarth

llvm-svn: 269315
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index ebb52aa..6cb543b 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -24,6 +24,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeDumper.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
@@ -770,8 +771,8 @@
     // The section consists of a number of subsection in the following format:
     // |SubSectionType|SubSectionSize|Contents...|
     uint32_t SubType, SubSectionSize;
-    error(consumeUInt32(Data, SubType));
-    error(consumeUInt32(Data, SubSectionSize));
+    error(consume(Data, SubType));
+    error(consume(Data, SubSectionSize));
     if (SubSectionSize > Data.size())
       return error(object_error::parse_failed);
     switch (ModuleSubstreamKind(SubType)) {
@@ -802,7 +803,7 @@
   W.printNumber("Section", SectionName, Obj->getSectionID(Section));
 
   uint32_t Magic;
-  error(consumeUInt32(Data, Magic));
+  error(consume(Data, Magic));
   W.printHex("Magic", Magic);
   if (Magic != COFF::DEBUG_SECTION_MAGIC)
     return error(object_error::parse_failed);
@@ -813,8 +814,8 @@
     // The section consists of a number of subsection in the following format:
     // |SubSectionType|SubSectionSize|Contents...|
     uint32_t SubType, SubSectionSize;
-    error(consumeUInt32(Data, SubType));
-    error(consumeUInt32(Data, SubSectionSize));
+    error(consume(Data, SubType));
+    error(consume(Data, SubSectionSize));
 
     ListScope S(W, "Subsection");
     W.printEnum("SubSectionType", SubType, makeArrayRef(SubSectionTypes));
@@ -1211,7 +1212,7 @@
     case S_CALLEES: {
       ListScope S(W, Kind == S_CALLEES ? "Callees" : "Callers");
       uint32_t Count;
-      error(consumeUInt32(SymData, Count));
+      error(consume(SymData, Count));
       for (uint32_t I = 0; I < Count; ++I) {
         const TypeIndex *FuncID;
         error(consumeObject(SymData, FuncID));
@@ -1500,7 +1501,7 @@
       error(consumeObject(SymData, Constant));
       printTypeIndex("Type", Constant->Type);
       APSInt Value;
-      if (!decodeNumericLeaf(SymData, Value))
+      if (consume(SymData, Value))
         error(object_error::parse_failed);
       W.printNumber("Value", Value);
       StringRef Name = SymData.split('\0').first;
@@ -1551,7 +1552,7 @@
 void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) {
   StringRef Data = Subsection;
   uint32_t Signature;
-  error(consumeUInt32(Data, Signature));
+  error(consume(Data, Signature));
   bool HasExtraFiles = Signature == unsigned(InlineeLinesSignature::ExtraFiles);
 
   while (!Data.empty()) {
@@ -1564,12 +1565,12 @@
 
     if (HasExtraFiles) {
       uint32_t ExtraFileCount;
-      error(consumeUInt32(Data, ExtraFileCount));
+      error(consume(Data, ExtraFileCount));
       W.printNumber("ExtraFileCount", ExtraFileCount);
       ListScope ExtraFiles(W, "ExtraFiles");
       for (unsigned I = 0; I < ExtraFileCount; ++I) {
         uint32_t FileID;
-        error(consumeUInt32(Data, FileID));
+        error(consume(Data, FileID));
         printFileNameForOffset("FileID", FileID);
       }
     }
@@ -1606,7 +1607,7 @@
   // The string table offset comes first before the file checksum.
   StringRef Data = CVFileChecksumTable.drop_front(FileOffset);
   uint32_t StringOffset;
-  error(consumeUInt32(Data, StringOffset));
+  error(consume(Data, StringOffset));
 
   // Check if the string table offset is valid.
   if (StringOffset >= CVStringTable.size())
@@ -1631,7 +1632,7 @@
     W.printBinaryBlock("Data", Data);
 
   uint32_t Magic;
-  error(consumeUInt32(Data, Magic));
+  error(consume(Data, Magic));
   W.printHex("Magic", Magic);
   if (Magic != COFF::DEBUG_SECTION_MAGIC)
     return error(object_error::parse_failed);