[llvm-commits] [PATCH] YAML I/O

Nick Kledzik kledzik at apple.com
Mon Oct 1 17:52:59 PDT 2012


On Oct 1, 2012, at 4:51 PM, Michael Spencer wrote:

> On Mon, Oct 1, 2012 at 2:11 PM, Nick Kledzik <kledzik at apple.com> wrote:
>> I now happy with how YAML I/O is working using a traits based design.   Attached is the generated documentation on how to use it and the test suite which also serves as real examples.  If this top level design looks good, I'll post the implementation for review.  Thanks.
>> -Nick
>> 
> Looks good. I have a few concerns though.
> 
> The API doesn't seem to be composable. By this I mean that everything
> has to be defined in a single translation unit. An example of where
> this comes up is reading a yaml representation of archive files. An
> archive can contain many different types of object files. We would
> need to be able to figure out which object file type is represented
> and then forward the rest of that yaml node to the proper yaml parser.
Do we need to be dynamically composable or just build time composable?
That is, is it ok to say all the types being used have to have traits
at build time, perhaps in different files.   I found that clang lets you do:

template <>
struct MappingTraits<SomeExternalType> {
	static void mapping(IO &io, SomeExternalType &value);
};

And it treats it like an extern template.  The compiler recognizes it as
a specialization, but lets the implementation be defined in another
translation unit, which is a building block of being composable.

At one point you had mentioned that the YAML spec allows for "tags",
and that we could use tags to specify when some sub-tree of a YAML
document was entering a new schema.  

For the purposes of lld, my thought was the want the different
flavors of input files to be parsed into an lld::File* objects.  So. at the top
level, the YAML is homogeneous.  But, as you parse down into each file
you may see a tag saying it is encoded as ELF sections, or native atoms,
etc.  From that you switch to using some external template to complete
the parse.  The implementation of the various templates would be in the
various format (ReaderWriter) part of lld, so it would be found at build time.



> Another use case for the above is Parser that doesn't use YAML I/O for
> everything, but wants to pass a Node* to YAML I/O for a specific case.
I have hooks in YAML I/O fir custom parsing/printing of scalars.   I suppose 
it would be possible to add hooks to start up YAML I/O in the middle of
some YAML document.  But remember, YAML I/O aims to unify reading
and writing YAML.  If you are using YAMLParser for some pieces, you still
have to handle writing out those pieces too.  It might be easier just to use
YAML I/O everywhere.


> 
> The unique types violate the non-intrusive nature of the API. I feel
> it would be better to be able to explicitly state which trait to use
> in ambiguous cases.
There was an example of this under "Order of Keys".  Since traits are keyed
off of types, you can force which trait to be used via a cast.  For example:

   io.mapRequired("flags", *(My86_64Flags*)info.flags);

Would apply the My86_64Flags trait to info.flags.



> I was thinking about using ADL instead of namespace injection for
> finding the traits, but I'll have to look more into it to figure out
> if it's the right solution here.
If there is a better solution, I'm all ears.

-Nick







More information about the llvm-commits mailing list