[PATCH] D20183: Enhance CodeView record deserialization with some template metaprogramming

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Wed May 11 15:13:12 PDT 2016


zturner created this revision.
zturner added reviewers: rnk, amccarth.
zturner added a subscriber: llvm-commits.

The general idea is to introduce a variadic template function which can deserialize arbitrary sequences of items from a byte stream.  For example, if you write:

```
const Layout *L;
StringRef S;
uint64_t N;
consume(Data, L, S, N);
```

it will deserialize each of these in sequence, returning an error at any point if there is a problem.

There are a few cases where things get more complicated.

1. Sometimes fields might only be present if a particular condition is true.  For example, if a function is an introducing pure virtual function, then a VFTableOffset will be present, otherwise it won't.  To handle this we introduce the notion of conditional fields, specified with the `CONDITIONAL_FIELD` macro.
2. There might be a field which represents a number N of elements, and then an N element array might follow.  To handle this we introduce the `ARRAY_FIELD_N` macro.
3. There are occasions where what follows is an array whose length is not encoded, but which runs until the end of the buffer.  To handle this we introduce the `ARRAY_FIELD_TAIL` macro.

These macros work by constructing a lambda function with the given conditional, so that it is evaluated lazily, meaning that if you write

```
const uint64_t Count;
ArrayRef<uint32_t> Items;
consume(Data, Count, ARRAY_FIELD_N(Items, Count));
```

it will work, because `Count` in the macro is not evaluated until it processes that item, at which point it has already been deserialized.

There are 2 remaining instances where I was not able to come up with a good solution that allows us to use this variadic template.  One involves a nested "sub field" which must be deserialized, and another involves a complex nibble decoding algorithm.

In any case, this should handle 90% of cases, and greatly reduces the amount of boilerplate needed to deserialize records.

http://reviews.llvm.org/D20183

Files:
  include/llvm/DebugInfo/CodeView/RecordSerialization.h
  include/llvm/DebugInfo/CodeView/TypeRecord.h
  lib/DebugInfo/CodeView/CMakeLists.txt
  lib/DebugInfo/CodeView/RecordSerialization.cpp
  lib/DebugInfo/CodeView/TypeStream.cpp
  tools/llvm-readobj/COFFDumper.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20183.56969.patch
Type: text/x-patch
Size: 38554 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160511/3fba944a/attachment-0001.bin>


More information about the llvm-commits mailing list