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

Manuel Klimek klimek at google.com
Mon Jul 9 04:56:24 PDT 2012


On Mon, Jul 9, 2012 at 1:52 PM, Satya Prakash Prasad <
satyaprakash.prasad at gmail.com> wrote:

> 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)) {
>

You'll want
if (ForStmt *S = dyn_cast<ForStmt>(i)) {
... use S ...
}


>                 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
> >> >> >
> >> >> >
> >> >
> >> >
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120709/915164a4/attachment.html>


More information about the cfe-dev mailing list