3

I have an existing and working source-to-source code modification tool using libtooling. Now I want to integrate this tool into clang, so users can compile the modified source code without actually saving it somewhere.

The modification part isn't problematic, Matchers + Rewriters work the same way with clang, my problem is how to tell the compiler to reparse the source code after my changes.

My progress so far:

  • I found a conversation on cve-dev, but without specific information how to do it
  • I also found clang::ASTUnit::Reparse, but I couldn't figure out how to call it. In the clang sources nothing uses it, and my every try was rewarded with crashes.
  • There was a similar question in StackOverflow, but without a good answer
  • There are some plugins tools like traces, which do the same source modification, but it just calls the compiler two times.

I'm hope that based on the first two eventually I find a working solution, but maybe someone knows the answer already, and could help me with an example, or at least more specific instructions how to implement it?

Dutow
  • 5,638
  • 1
  • 30
  • 40

1 Answers1

2

You can wrap the EmitObjAction that generates the object file by using a WrapperFrontendAction. In the wrapper action you can override the function BeginInvocation(). In this function you can create your own ASTFrontendAction that traverses the AST and performs textual changes with a Rewriter class.

When your action is finished, you can access the buffers in the Rewriter class. You can make a copy of these buffers and add them to the PreprocessorOptions with addRemappedFile(). Since the PreprocessorOptions are attached to the CompilerInstance, they are also used by the following EmitObjAction, that you wrapped.

This means that the EmitObjAction will actually read the changed source files.

You can get some inspiration from how the FixItRecompile class is used in Clang.

Ivan
  • 46
  • 4
  • Unfortunately, I can't wrap EmitObjAction with a WrapperFrontendAction without actually modifying the source of clang (FixItRecompile is hardwired into it too). Or I am missing something? – Dutow Nov 30 '15 at 12:29
  • Personally, I changed the clang source to do this, and thus I compiled a special purpose clang executable. As far as I know, if you want to use clang plugins or libtooling, you have to indeed add some code to clang that exposes the possiblity to wrap EmitObjAction. You can always try to ask at the [cfe-dev mailing list](http://lists.llvm.org/mailman/listinfo/cfe-dev) aswell. – Ivan Dec 02 '15 at 21:02
  • I came up with a similar solution (invoking the clang compiler from my clang tool). Your version is certainly easier to use, but it still requires maintenance from my part for every clang version, and the users have to download and specify a different compiler instead of just a plugin. I asked this question on the mailing list too and got similar answers there. But looks like there is no current way to do this, so I'll ask them if they would accept a patch adding this possibility to plugins. – Dutow Dec 03 '15 at 07:44