This is an archive of the discontinued LLVM Phabricator instance.

[CodeView] Decouple the type record deserialization from the visitor.
ClosedPublic

Authored by zturner on Aug 4 2016, 1:22 PM.

Details

Summary

Until now, our use case for the visitor has been to take a stream of bytes representing a type stream, deserialize the records in sequence, and do something with them, where "something" is determined by how the user implements a particular set of callbacks on an abstract class.

For actually writing PDBs, however, we want to do the reverse. We have some kind of description of the list of records in their in-memory format, and we want to process each one. Perhaps by serializing them to a byte stream, or perhaps by converting them from one description format (Yaml) to another (in-memory representation).

This was difficult in the current model because deserialization and invoking the callbacks were tightly coupled.

With this patch we change this so that TypeDeserializer is itself an implementation of the particular set of callbacks. This decouples deserialization from the iteration over a list of records and invocation of the callbacks. TypeDeserializer is initialized with another implementation of the callback interface, so that upon deserialization it can pass the deserialized record through to the next set of callbacks. In a sense this is like an implementation of the Decorator design pattern, where the Deserializer is a decorator.

This will be useful for writing Pdbs from yaml, where we have a description of the type records in Yaml format. In this case, the visitor implementation would have each visitation callback method implemented in such a way as to extract the proper set of fields from the Yaml, and it could maintain state that builds up a list of these records. Finally at the end we can pass this information through to another set of callbacks which serializes them into a byte stream.

Diff Detail

Repository
rL LLVM

Event Timeline

zturner updated this revision to Diff 66849.Aug 4 2016, 1:22 PM
zturner retitled this revision from to [CodeView] Decouple the type record deserialization from the visitor..
zturner updated this object.
zturner added reviewers: rnk, amccarth, ruiu.
zturner added a subscriber: llvm-commits.
majnemer added inline comments.
include/llvm/DebugInfo/CodeView/TypeDeserializer.h
89 ↗(On Diff #66849)

Is it possible for OldData.size() to be less than Data.size()? Should we assert or return an error? Or is this literally not possible?

tools/llvm-readobj/llvm-readobj.cpp
282–285 ↗(On Diff #66849)

Why make this change?

tools/llvm-readobj/llvm-readobj.h
26 ↗(On Diff #66849)

This looks like a redeclaration.

ruiu accepted this revision.Aug 4 2016, 2:48 PM
ruiu edited edge metadata.

LGTM

tools/llvm-readobj/llvm-readobj.cpp
282 ↗(On Diff #66849)

ec -> EC

tools/llvm-readobj/llvm-readobj.h
26 ↗(On Diff #66849)

EC

This revision is now accepted and ready to land.Aug 4 2016, 2:48 PM
zturner added inline comments.Aug 4 2016, 2:52 PM
include/llvm/DebugInfo/CodeView/TypeDeserializer.h
89 ↗(On Diff #66849)

I don't think this is possible. deserializeRecord is expected to set Data on output to the set of data that is leftover after consuming one record. We can assert.

tools/llvm-readobj/llvm-readobj.cpp
282–285 ↗(On Diff #66849)

Was an accident as a result of merging two patches where the order of the overloads was different.

zturner updated this revision to Diff 66861.Aug 4 2016, 2:55 PM
zturner edited edge metadata.
amccarth added inline comments.Aug 4 2016, 3:02 PM
include/llvm/DebugInfo/CodeView/RecordSerialization.h
147 ↗(On Diff #66849)

Method name seems weird given the struct name.

150 ↗(On Diff #66849)

As long as you're improving the message, how about adding the missing hyphen? "Null-terminated string..."

161 ↗(On Diff #66849)

Another hyphen needed: "Null-terminated string has no null terminator!"

include/llvm/DebugInfo/CodeView/TypeRecord.h
117 ↗(On Diff #66849)

For many of these, there is only one Kind that should be passed in. I'm concerned that by adding a new constructor, we make it possible to create a nonsense record with the wrong Kind. Perhaps an assertion would be appropriate in these cases.

I'm OK if you don't think this is worth it. Some of the record types do depend on a passed in Kind, and there's no check there, so this isn't an entirely new problem.

tools/llvm-readobj/llvm-readobj.h
26 ↗(On Diff #66849)

This seems to duplicate the prototype two lines down, except for the case of the parameter name.

rnk accepted this revision.Aug 5 2016, 8:30 AM
rnk edited edge metadata.

lgtm Thanks for straightening this out, we were conflating deserialization and dispatching type record actions in the visitor.

This revision was automatically updated to reflect the committed changes.