Greetings.

I’m building a source-to-source tool with clang. What I want to do is 
instrument stores made with the binary = operator. Currently, I’m running into 
problems with rewriting expressions that contain macro invocations. I’ve done 
some digging around, and I found some info  that helped with my understanding 
(e.g. 
https://stackoverflow.com/questions/24062989/clang-fails-replacing-a-statement-if-it-contains-a-macro).
 But I’m still not sure how to solve this problem.

Concretely, suppose you have:
#define a(x) ((x) * 10 + 1)

class my_class {
    int x;

public:
    int my_function() {
        x = a(0);
        return x;
    }
};

I want to rewrite this into something like this:
#ifndef _instrument_noclash
#define _instrument_noclash(name, expr, instance_no)                            
   \
    (*({                                                                        
                                                 \
        typeof(expr) *_t_instrument_no_clash##instance_no = &(expr);        \
        _t_instrument_no_clash##instance_no;                                    
                \
        }))
#endif

#define a(x) ((x) * 10 + 1)

class my_class {
        int x;
public:
        int my_function() {
                _instrument_noclash("x",(this->x=((0) * 10 + 1)),0);
                return x;
        }
};

The problem (to me) is simple: how do I determine the physical location of the 
ending of the expression on the right hand sign of the = operator? Without this 
knowledge, I end up overwriting the end of the statement. Scanning the APIs, it 
seems like there isn’t a simple way to do this. I’ve tried several ways to get 
the ending source location:

  1.  op->getEndLoc(), where op is an instance of BinaryOperator. This doesn’t 
work, because the ending location in the AST is not the same as the physical 
end location of the expression, due to macro expansion.
  2.  sm.getSpellingLoc(op->getEndLoc()), where sm is the source manager. This 
just returns op->getEndLoc().
  3.  sm.getExpansionLoc(op->getEndLoc()). This is close, but the location 
returned is the end of the macro name, so the macro arguments are not removed.

Any suggestions (or easier way to achieve this same goal) are appreciated.

-Max
_______________________________________________
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users

Reply via email to