[cfe-commits] [PATCH] Implements support to run standalone tools

Manuel Klimek klimek at google.com
Mon Mar 26 07:39:29 PDT 2012


On Mon, Mar 26, 2012 at 4:26 PM, Douglas Gregor <dgregor at apple.com> wrote:

>
> On Mar 26, 2012, at 7:21 AM, Manuel Klimek <klimek at google.com> wrote:
>
> On Mon, Mar 26, 2012 at 3:56 PM, Douglas Gregor <dgregor at apple.com> wrote:
>
>>
>> On Mar 26, 2012, at 4:08 AM, Manuel Klimek <klimek at google.com> wrote:
>>
>> > On Wed, Mar 21, 2012 at 10:44 PM, Marshall Clow <mclow.lists at gmail.com>
>> wrote:
>> >> On Mar 21, 2012, at 8:07 AM, Manuel Klimek wrote:
>> >>> On Wed, Mar 21, 2012 at 3:09 PM, Marshall Clow <mclow.lists at gmail.com>
>> wrote:
>> >>>> On Mar 21, 2012, at 6:25 AM, Manuel Klimek wrote:
>> >> I think I understand now.  The point that I was trying to make is that
>> I think that for simple tools we (or at least I) would like to be able to
>> forego building some kind of database (JSON, Makefile, Ninja), and just
>> specify the options and source files on the command line.
>> >>
>> >> $ ./oneOffTool -I blah -Dblix=4 -I other_dir -o output_dir
>> -someCustomFlag *.cpp
>> >>
>> >> As long as we're abstracting the idea of a "compilation database", I
>> think that generating such a db from an argc/argv pair seems like a good
>> idea (and not very hard).
>> >>
>> >> Hopefully what I'm trying to convey is clearer now.
>> >
>> > Well, the interesting thing is how to design this. From a design point
>> > of view, the command line becomes very different depending on whether
>> > you basically want to "forward all args to clang in the tool" or "find
>> > the args for the specified files and run the clang tool over them".
>> > The first one inherently means I can only specify the command line for
>> > a single invocation, so it is also pretty limited. I agree it is an
>> > important use case though.
>> >
>> > A possible solution would be to allow for a command line flag that
>> > switches to use the command line arguments directly as arguments for
>> > the clang tools. My problem is that I don't really see a good way to
>> > handle that with llvm-provided command line abstractions (perhaps I'm
>> > missing something there?)
>> >
>> > What I basically want would be:
>> > <tool> -d <build directory> <file1 ... fileN>
>> > <tool> --use-args <clang command line>
>> >
>> > But I don't want to roll my own command line parsing if possible.
>>
>> I could be something as trivial as
>>
>>        <tool> <tool arguments> -- <clang command line>
>>
>> where the lack of "--" means that the tool should expect a build
>> directory in <tool arguments>. You'd need to look through argv to find the
>> "--" and split at that point, but the rest of the command-line parsing
>> would be unchanged.
>>
>
> I like the idea. I'll play around to see whether I can get the llvm
> command line parsing to behave like I want to.
> I can probably just feed the part of the command line before the "--" to
> the llvm command line parsing.
>
>
> Yeah, I think it's fine to just feed everything before "--" to the llvm
> command-line parsing.
>
> I'd probably like to write something like (leaving figuring out how to
> pack that up to make writing simple tools simpler for later):
> <define tool command lines>
> int main(...) {
>   // Make argc and argv references so we can change them? Kind of yuck,
> alternative ideas welcome.
>   llvm::OwningPtr<CompilationDatabase>
> Database(createSimpleCompilationDatabase(argc, argv));
>   <do llvm command line parsing on rest of argc, argv>
>   if (!Database) {
>     Database.reset(loadCompilationDatabase(BuildDirectory));
>   }
>   ClangTool Tool(Database.get(), Filenames);
> }
>
> where SimpleCompilationDatabase then returns the same arguments
> independent of the file name...
>
>
> Agreed.
>
>
>> >> Then again, when you say "CompilationDatabase", I think of something
>> that I can extract a set { commands, arguments, source file } tuples to be
>> executed.
>> >> Maybe that's where we are are talking past each other.
>> >
>> > When I say CompilationDatabase I think of a map<filename, { command,
>> > arguments, path}>. Does that make sense?
>>
>>
>> Makes sense to me, although of course this could end up being a multimap.
>>
>
> Which is also an interesting design question - at least for refactorings
> we'll probably want to run over all different command lines the file was
> compiled with (think: different configurations with different macros
> enabled). This would lead to a slightly different interface for
> CompilationDatabase though (returning a list of compile command lines for
> each target).
>
>
> I think it's important for us to support this case in the interface.
>

Agreed. So something like:

/// \brief Specifies the working directory and command of a compilation.
struct CompileCommand {
  /// \brief The working directory the command was executed from.
  std::string Directory;

  /// \brief The command line that was executed.
  std::vector<std::string> CommandLine;
};

class CompilationDatabase {
public:
  /// \brief Returns all compile commands in which the specified file was
compiled.
  ///
  /// This includes compile commands that span multiple source files.
  /// For example, for a compile command line
  /// $ clang++ -o test a.cc b.cc t.cc
  /// $ clang++ -o production a.cc b.cc -DPRODUCTION
  /// A compilation database representing the project would return both
command lines
  /// for a.cc and b.cc and only the first command line for t.cc.
  virtual vector<CompileCommand> getCompileCommands(StringRef FilePath) = 0;
};

Also, I'd like to pull CompilationDatabase into its own header file if that
is fine with you.

Thoughts?
/Manuel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120326/bb5a1f19/attachment.html>


More information about the cfe-commits mailing list