[cfe-dev] Getting the end location of a function like macro

Francesco UNINA fr.fucci.univ at gmail.com
Fri Mar 13 05:45:09 PDT 2015


Hello everyone,
I’m developing a libtooling tool and and now I need to get the end source location point of the 
a function like macro.
Consider this example:

#include <stdio.h>
#include <stdlib.h>

#define MACRO 2
#define pr_prova(fmt, ...) \
        printf(fmt, ##__VA_ARGS__)


int func(){
        return 2;
}

int main(){
        int x,y;
        x = 5;
        if ( x < 6 )
                //return MACRO;
                pr_prova("%d",func());

        return 0;
}

I need to get the SourceLocation at the end of the pr_prova line.  
The code I wrote to get this source location code is the following

SourceLocation getRightEndLocation(SourceLocation start,bool isMacroFunction,StringRef macroName){
        SourceLocation sl = rewriter->getSourceMgr().getFileLoc(start);
        int offset = Lexer::MeasureTokenLength(sl,rewriter->getSourceMgr(),rewriter->getLangOpts()) + 1;
        llvm::errs() << "offset: " << offset << '\n';

        SourceLocation left = sl.getLocWithOffset(offset);

        if(!isMacroFunction){
            llvm::errs() << "!MacroFunction" << '\n';
            return left;
        }
        left = sl.getLocWithOffset(offset-1);

        const MacroInfo* mi = pre->getMacroInfo(pre->getIdentifierInfo(macroName));
        assert(mi->isFunctionLike() && "This macro must be function like");
        //int displ = 0;
        Token t;
        llvm::errs() << "Left location: " << '\n';
        printLocation(left);
        bool ret = pre->getRawToken(left,t);
        pre->DumpToken(t);
        llvm::errs() << '\n';
        if(ret == true){
            assert(false && "Cannot get token");
        }
        int NumPar = 0;
        SourceLocation end,temp;
        temp = left;
        llvm::errs() << "ref: " << macroName << '\n';
        while(t.isNot(tok::eod)){
            llvm::errs() << “Here.." << '\n';

            assert((t.is(tok::l_paren) || t.is(tok::comma)) &&
                   "only expect argument separators here");

            //SourceLocation argStart = t.getLocation();
            while(1){
               pre->Lex(t);
               if(t.is(tok::l_paren)){
                    llvm::errs() << "L parens.." << '\n';
                    NumPar++;
              }else if(t.is(tok::r_paren)){
                  if(NumPar-- == 0){
                      end = t.getLocation();
                      llvm::errs() << “Here.." << '\n';
                      break;
                   }
                }
            }
        }
        return end;
    }

This function can get the right end location with a not function like macro but it crashes with the example that I mentioned above.
Do you know any method that I can use to get the macro end source location? 

Cheers,
Francesco





More information about the cfe-dev mailing list