[LLVMdev] object construction patterns and unique_ptr

Chris Lattner clattner at apple.com
Tue Jun 19 10:31:36 PDT 2012


On Jun 18, 2012, at 1:22 PM, Nick Kledzik wrote:
>>> But this interface has become awkward to use. There are two "return" values.  This method is a unique_ptr "source" but the use of a by-refernce parameter means you have to start with an uninitialized unique_ptr and the readFile() has to std::move() into it.   unique_ptr is much nicer to use as a return value.
>> 
>> Not a c++'11 expert here, but does a returning an std::tuple work?
> I talked to Howard about that.  It does work, but it is cumbersome.  Either:
> 
> std::tuple<std::unique_ptr<lld::File>, error_code>  result = reader.readFile(path);
> 
> Or you use std::tie() but then you still have to declare the two local variables and tie them together.  You could define a wrapper class for the tuple, but then you realize it would be simpler to push the error_code into the File and get rid of the wrapper class.

Ok, yeah, that is annoying.

>>> An other issue is that since llvm::error_code was designed to return a fixed set of strings, there is no way to return a dynamic error message (e.g. "relocation 27 is invalid"). 
>> 
>> I'm pretty sure that the linker can specify a custom error_category with whatever information you want, and then return an error_code put with that.  Michael would know for sure, but it is definitely in the design of error_code for it to be extensible.
> 
> From what I can tell error_code is about wrapping out OS specific "int" error codes, and how to map those to static strings.  I suppose you could abuse it by having a error_category which has a static vector or recently dynamically generated strings and the int "error code" is an index into that vector.  

I'm pretty sure that error_code is designed to be "simple for errno's" but "general to other errors".  Michael?

> Clang has this great Diagnostics infrastructure for showing where the error occurred in the source file.  Does developing something like that make sense for object files whose source is not human readable?

I don't think this makes sense for the linker.  The key aspect of Clang's diagnostics (and llvm::SourceMgr, which is similar but simpler) is that it points back into source code.  This is the source of most of the complexity of its diagnostics stuff, and doesn't make a lot of sense for the linker.

That said, one crazy hack that I've been wanting to do for some time in clang would apply equally well to the linker: all the command line options could be plopped into a text buffer, and diagnostics related to command line options could refer to *that* location.  Imagine getting an error like this from the linker:

zsh> ld foo.o bar.o baz.a -o a.out
command-line:1:3: error: foo.o is not a valid object file
ld foo.o bar.o baz.a -o a.out
   ^~~~~

zsh> ld foo.o bar.o baz.a -o a.out
command-line:1:32: error: xyz.o member of baz.a is not a valid object file
ld foo.o bar.o baz.a -o a.out
               ^~~~~

zsh> ld foo.o bar.o baz.a -o a.out
command-line:1:46: error: can not open output file a.out: permission error
ld foo.o bar.o baz.a -o a.out
                        ^~~~~
or whatever.

>From an API level, this would mean that the object file parsing logic would pass back up an error_code, and then the higher level driver logic would combine the string together with the location of the command line option for printing through llvm::SourceMgr.

> One other thought that leans me towards integrating the error code/msg into the File object is that it works cleaner when you start adding multithreading to the linker.  When you have multiple threads going, each reading an object file and one of them returns an error, you need to cleaning shut down the other threads, and return the error.  With the error status integrated into the File object, all you do is have each thread append it resulting File object onto a list, then after all threads are joined, run through the list once to see if any say they encountered an error.  If the error_code is returned separately from the File, you have to create some data structure to bind together the error_code with which file path could not be parsed.

As with the other guys, I'd really prefer to avoid merging the error status *into* the file.  In principle, it is the "open file" operation that can fail, not the file itself.

-Chris




More information about the llvm-dev mailing list