[cfe-users] How to find the physical end of an expression?
Richard Smith via cfe-users
cfe-users at lists.llvm.org
Wed May 5 11:52:45 PDT 2021
On Wed, 28 Apr 2021 at 13:53, Taylor, Max via cfe-users <
cfe-users at lists.llvm.org> wrote:
> 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.
>
> sm.getExpansionRange(op->getEndLoc()).getEnd() should work in this case.
In general what you're trying to do is not possible, because the assignment
expression might end in the middle of the macro expansion, though;
depending on exactly what your goal is, it might be easiest to first
preprocess the source file and then run your transform.
> Any suggestions (or easier way to achieve this same goal) are appreciated.
>
>
>
> -Max
> _______________________________________________
> cfe-users mailing list
> cfe-users at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-users/attachments/20210505/3105914e/attachment.html>
More information about the cfe-users
mailing list