On Wed, 28 Apr 2021 at 13:53, Taylor, Max via cfe-users < cfe-users@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@lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users >
_______________________________________________ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users