Creating single AST for multiple files

Hello,

I am new to Clang and so I am having some problem figuring out how to create AST for a program with multiple files .

What I am trying to do:

  • In an application containing multiple .cpp/.c and .h files, parse through all the files and identify all instances of a particular function
    -Move the function definition to a new file with a changed name(changed function name)
    -Find all instances where the particular function is called and change the function name to the new name

(I am ignoring the other dependencies like nested functions/headers etc so that I can focus on my actual question. So assume this works:))

I have been reading up on Clang/libtooling inorder to figure out a way to do the same. From what I understand, the steps to do this would be

  • Compile and create ASTs for the entire source code(assuming it includes multiple .cpp and .h files)
    -Somehow traverse these ASTs(RecursiveASTVisitor) to figure out where all this the particular function I am interested in exists(ASTMatchers??)
    -First write the function definition to a new file
    -Now use the rewriter to write the original file without the function definition and replace all the places where a call to this function exists with its new name
    (I have tried to simplify the problem statement so that I can pinpoint my issue better. I’ll ofcourse have to manipulate the ASTs and the source code more to get a working program )

First of all, I need to have ASTs of all TUs and not just one AST. Is there any way in libtooling to obtain a single AST for multiple TUs? If not is there any standard practice for the same incase anyone has faced the same problem?

The one related post I could find in the mailingList is http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-August/023865.html. But That was 2 years ago and the answer at that time was that if I am using LibTooling, it’ll get me disfferent ASTs. Has any been any changes recently to support creating a single AST?

Also will it be better to look at clang tools rather than libTooling for this?

Regards,
Deepak

I'm not sure that I understand. Standard practice is to process one AST
per TU. I've not found it to be a problem, but maybe it is for you for
some reason -- in which case it might help to say what that reason is.
There may well be solutions.

-- James

James,

Thank you for answering my query.

I might have misunderstood the issues. We have been using ‘Rose’, which is another source to source compiler. Rose generates a single AST. I expected something similar which is why I was looking for a way to generate a single AST. But having gone through some some documentation, it seems like it is indeed possible to implement this using multiple ASTs. But my problem is I will need to revisit each AST multiple times and make incremental changes on source files. Is ‘clang-apply-replacements’ a solution to this?

I am also confused as to if I should be using LibClang or LibTooling keeping in mind I’ll need to make significant changes to my source code. Is there any functionality constraint on LibClang/LibTooling which I can use to make up my mind??

Regards,
Deepak

James,

Thank you for answering my query.

I might have misunderstood the issues. We have been using ‘Rose’, which is another source to source compiler. Rose generates a single AST. I expected something similar which is why I was looking for a way to generate a single AST. But having gone through some some documentation, it seems like it is indeed possible to implement this using multiple ASTs. But my problem is I will need to revisit each AST multiple times and make incremental changes on source files. Is ‘clang-apply-replacements’ a solution to this?

Yes. Generally, you’ll want to run over all TUs, and create replacements, and then apply them in one step in the end.

I am also confused as to if I should be using LibClang or LibTooling keeping in mind I’ll need to make significant changes to my source code. Is there any functionality constraint on LibClang/LibTooling which I can use to make up my mind??

libclang currently doesn’t have refactoring support, so if you want to rewrite code, you’ll want to use libtooling…