[cfe-dev] Basic source-to-source transformation with Clang

Satya Prakash Prasad satyaprakash.prasad at gmail.com
Mon Jul 9 04:52:40 PDT 2012


I got one way to do that, not sure if correct:

                        Stmt *i =  cast<Stmt>(*I);
                        SourceManager &SourceMgr =
TheCompInst.getSourceManager();
                        SourceLocation ST = i->getSourceRange().getBegin();
                        SourceLocation ED = i->getLocEnd().getLocWithOffset(4);
                        const char * scode = SourceMgr.getCharacterData(ST);
                        const char * ecode = SourceMgr.getCharacterData(ED);
                        char *code = (char *)calloc(ecode - scode + 1,
sizeof(char));
                        strncpy(code, scode, ecode - scode);
                        std::cout << "STMT :" << code << "\n";

But I found that if, for or while etc which can have sub blocks the
inside a main compound block - how do I traverse through them. The
following code does not works:

 if (isa<ForStmt>(i)) {
                for (CompoundStmt::body_iterator  x = i->body_begin(),
y = i->body_end(); x != y; ++x)
                {

                }
   }
Compilation Error:

rewritersample.cpp:59: error: 'class clang::Stmt' has no member named
'body_begin'
rewritersample.cpp:59: error: 'class clang::Stmt' has no member named 'body_end'

Please help and thanks in advance.

Regards,
Prakash

On Mon, Jul 9, 2012 at 1:05 PM, Manuel Klimek <klimek at google.com> wrote:
> On Mon, Jul 9, 2012 at 9:32 AM, Satya Prakash Prasad
> <satyaprakash.prasad at gmail.com> wrote:
>>
>> Thanks once again. I am really thankful to Manuel and others in group
>> who gave me more insight and confidence to work with CLANG.
>>
>> However please note that when I used the below code to print the C++
>> code (input as an input param : rewritecode test.cpp):
>>
>>                         Stmt *i =  cast<Stmt>(*I);
>>                         SourceManager &SourceMgr =
>> TheCompInst.getSourceManager();
>>                         SourceLocation ST =
>> i->getSourceRange().getBegin();
>>                         const char * code =
>> SourceMgr.getCharacterData(ST);
>>                         std::cout << "STMT  : " << code << "\n";
>
>
> Do the same for getEnd(), then you have a char * for the end, and you can
> print to that character...
>
> Cheers,
> /Manuel
>
>>
>>
>> Ii prints additional line than what I want each time. Example if my
>> test.cpp file is like below:
>>
>> int inc(int &p)
>> {
>>         p++;
>>         printf("%s %d",__FILE__,__LINE__);
>>         printf("In inc [%d]\n", p);
>>         return p;
>> }
>>
>>
>> I get output like:
>>
>> STMT : p++;
>>         printf("In inc [%d]\n", p);
>>         return p;
>> }
>> ......................................................
>>
>> How can I print only a single line of code at a time and not its
>> consecutive one. I cannot tokenize it with '\n' as there are can
>> multiple lines for a single statement. I would also really appreciate
>> if I can get some reference of good books either offline / online to
>> refer for beginners level.
>>
>> Thanks in advance.
>>
>> Regards,
>> Prakash
>>
>> On Fri, Jul 6, 2012 at 7:30 PM, Manuel Klimek <klimek at google.com> wrote:
>> > On Fri, Jul 6, 2012 at 2:33 PM, Satya Prakash Prasad
>> > <satyaprakash.prasad at gmail.com> wrote:
>> >>
>> >> Thanks for the information as provided, but I get output like below:
>> >>
>> >> (CallExpr 0x1a85c480 'int'
>> >>   (ImplicitCastExpr 0x1a85c468 'int (*)(const char *restrict, ...)'
>> >> <FunctionToPointerDecay>
>> >>     (DeclRefExpr 0x1a85c3e8 'int (const char *restrict, ...)' lvalue
>> >> Function 0x1a84e8e0 'printf' 'int (const char *restrict, ...)'))
>> >>   (ImplicitCastExpr 0x1a85c4b8 'const char *' <ArrayToPointerDecay>
>> >>     (StringLiteral 0x1a85c388 'const char [13]' lvalue "In inc
>> >> [%d]\n"))
>> >>   (ImplicitCastExpr 0x1a85c4d0 'int' <LValueToRValue>
>> >>     (DeclRefExpr 0x1a85c3c0 'int' lvalue ParmVar 0x1a85c100 'p' 'int
>> >> &')))
>> >>
>> >> Kindly note that my requirement is to print the C++ code itself like
>> >> dumpAll() method generated for above for below C++ code:
>> >
>> >
>> > If you want to print the C++ code that produce the AST, you'll want to
>> > get
>> > the SourceRange, and use SourceManager's getCharacterData() method to
>> > get
>> > the underlying data - that will get you the C++ code as it was written
>> > by
>> > the user.
>> >
>> > Cheers,
>> > /Manuel
>> >>
>> >>
>> >> p++;
>> >>
>> >> Similarly for other like:
>> >>
>> >> dumpAll()
>> >>
>> >> (CallExpr 0x1a85dec8 'int'
>> >>   (ImplicitCastExpr 0x1a85deb0 'int (*)(const char *restrict, ...)'
>> >> <FunctionToPointerDecay>
>> >>     (DeclRefExpr 0x1a85de88 'int (const char *restrict, ...)' lvalue
>> >> Function 0x1a84e8e0 'printf' 'int (const char *restrict, ...)'))
>> >>   (ImplicitCastExpr 0x1a85df08 'const char *' <ArrayToPointerDecay>
>> >>     (StringLiteral 0x1a85cdd8 'const char [19]' lvalue "y = [%d] z =
>> >> [%d]\n"))
>> >>   (ImplicitCastExpr 0x1a85df20 'int' <LValueToRValue>
>> >>     (DeclRefExpr 0x1a85ce18 'int' lvalue Var 0x1a85c6f0 'y' 'int'))
>> >>   (ImplicitCastExpr 0x1a85df38 'int' <LValueToRValue>
>> >>     (DeclRefExpr 0x1a85de60 'int' lvalue Var 0x1a85c760 'z' 'int')))
>> >>
>> >> While C++ Code:
>> >>
>> >> printf("y = [%d] z = [%d]\n", y , z);
>> >>
>> >> Thanks in advance.
>> >>
>> >> Regards,
>> >> Prakash
>> >>
>> >>
>> >> On Fri, Jul 6, 2012 at 4:22 PM, Manuel Klimek <klimek at google.com>
>> >> wrote:
>> >> > On Fri, Jul 6, 2012 at 12:25 PM, Satya Prakash Prasad
>> >> > <satyaprakash.prasad at gmail.com> wrote:
>> >> >>
>> >> >> I made some progress with whatever support I received from this
>> >> >> discussion forum. Thanks to all who responded to my request. My
>> >> >> requirement now is to find a way I can print CLANG AST code to C++ /
>> >> >> C
>> >> >> human readable statements:
>> >> >>
>> >> >>     bool VisitStmt(Stmt *s) {
>> >> >>         if (isa<CompoundStmt>(s)) {
>> >> >>                 CompoundStmt *S = cast<CompoundStmt>(s);
>> >> >>                 for (CompoundStmt::body_iterator  I =
>> >> >> S->body_begin(),
>> >> >> E = S->body_end(); I != E; ++I)
>> >> >>                 {
>> >> >>                         Stmt *i =  cast<Stmt>(*I);
>> >> >>                         //How can I print the C++ / C statement
>> >> >> which
>> >> >> CLANG is processing
>> >> >
>> >> >
>> >> > You can use i->dumpAll() if you want to see what's going on.
>> >> >
>> >> > Cheers,
>> >> > /Manuel
>> >> >
>> >> >>
>> >> >>                 }
>> >> >>         }
>> >> >>
>> >> >>         return true;
>> >> >>     }
>> >> >>
>> >> >> Regards,
>> >> >> Prakash
>> >> >>
>> >> >> _______________________________________________
>> >> >> cfe-dev mailing list
>> >> >> cfe-dev at cs.uiuc.edu
>> >> >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>> >> >
>> >> >
>> >
>> >
>
>



More information about the cfe-dev mailing list