[cfe-dev] Preprocessor/Parser interaction

Sean Silva silvas at purdue.edu
Wed Feb 22 07:54:49 PST 2012

There's a huge amount of boilerplate needed to do what you want, and it
will still be missing things like #include paths which will render your
program unusable for real code.

The dependency graph of objects that need to be created in order to get a
Preprocessor is gigantic. I manually tracked it here as I was exploring the
APIs myself: http://web.ics.purdue.edu/~silvas/deps.svg . CompilerInstance
reduces the amount of boilerplate needed, but there are still crucial
things missing for it to be "useful" (see:
https://github.com/loarabia/Clang-tutorial/blob/master/CItutorial3.cpp and
try including stdio.h in test.c).

A couple weeks ago I went down this path that you are trying to go down,
and I can tell you that you are not going to achieve what you want by doing
it like this (e.g., as a standalone program using the Clang libs). There
are just too many little things that need to be configured in specific ways
for the compiler to work "as usual, except also run my
(PPCallbacks|ASTConsumer|...)". My recommendation is to write a Clang
plugin, so that you can forget about all those things. There is an example
plugin called PrintFunctionNames in examples/PrintFunctionNames that you
can look at (although TBH I found it extremely unhelpful for some reason).
If you want, I can post on github a minimal "hello world" example for how
to run a PPCallbacks.

--Sean Silva

On Tue, Feb 21, 2012 at 5:35 PM, Aditya Kumar <hiraditya at msn.com> wrote:

>  I want to use a PPCallback function (MacroExpands) to track all the
> locations where
> a macro has been invoked in the program.
> In the main function, there are a few things that I want to implement,
> details are
> given as comment inside the main function.
> Till now what I have done is the following:
> namespace clang {
> class MyASTAction : public FrontendAction
> {
>   public:
>     ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
>                   llvm::StringRef InFile)
>     {    return 0;   }
>     void ExecuteAction() { }
>     bool usesPreprocessorOnly() const
>     { return false; }
> };
> class TrackMacro : public PPCallbacks
> {
>   public:
>   void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
>                     SourceRange Range)
>   {
>     std::cout<<"Macro expands to"<<MacroNameTok.getRawIdentifierData();
>   }
>   ~TrackMacro(){}
> };
> }
> using namespace clang;
> int main(int argc, const char** argv)
> {
>   MyASTAction action;
>   CompilerInstance Clang;
> /*****************************************
> How to create an instance of the preprocessor class, it seems like
> it takes too many(9) arguments which I was not able to figure out.
> Or is there a way to just create a default preprocessor and add my
> own call back function to it. And then pass the preprocessor object
> to the Parser and invoke the parser just by supplying a filename.
> *****************************************/
>   TrackMacro track_macro;
>   PP.addPPCallbacks(&track_macro);
>   Clang.setPreprocessor(PP);
>    MyASTAction* Act = new MyASTAction();
>    Clang.ExecuteAction(*Act);
> return 0;
> }
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120222/c3379930/attachment.html>

More information about the cfe-dev mailing list