<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jun 18, 2013, at 1:30 AM, Stephan Bergmann <<a href="mailto:sbergman@redhat.com">sbergman@redhat.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">On 06/11/2013 11:21 PM, Stephan Bergmann wrote:<br><blockquote type="cite">On 06/11/2013 11:13 PM, Argyrios Kyrtzidis wrote:<br><blockquote type="cite">On Jun 11, 2013, at 1:34 PM, Stephan Bergmann <<a href="mailto:sbergman@redhat.com">sbergman@redhat.com</a>><br>wrote:<br><blockquote type="cite">On 06/07/2013 08:19 PM, Argyrios Kyrtzidis wrote:<br><blockquote type="cite">On Jun 7, 2013, at 5:31 AM, Stephan Bergmann <<a href="mailto:sbergman@redhat.com">sbergman@redhat.com</a><br><<a href="mailto:sbergman@redhat.com">mailto:sbergman@redhat.com</a>>> wrote:<br><blockquote type="cite">Anyway, what I want to do is a rewriting Clang plugin that removes one<br>argument from specific function calls. But where I'm lost is how to<br>determine the SourceLocation of the comma preceding the given<br>argument, to do something like<br></blockquote><br>You could remove this range:<br><br>[loc-for-end-of-token of end location of preceding argument, end<br>location of removed argument]<br></blockquote><br>Yeah, but how do I get that loc-for-end-of-token?<br></blockquote><br>See Lexer::getLocForEndOfToken() or<br>Preprocessor::getLocForEndOfToken() (the latter delegates to the former).<br></blockquote><br>Ah, that was the missing link.<br></blockquote><br>...but that is still not working when macros are involved (getLocForEndOfToken(l) returns an invalid loc if l points into a macro expansion). What I want to do is remove the second (zero-valued) argument from all calls to f in<br><br> #define FOO "foo"<br> #define ZERO 0<br> f("foo", 0);<br> f(FOO, ZERO);<br> assert(f("foo", 0));<br> assert(f(FOO, ZERO));<br><br>(where "assert" is the std macro), i.e., end up with<br><br> #define FOO "foo"<br> #define ZERO 0<br> f("foo");<br> f(FOO);<br> assert(f("foo"));<br> assert(f(FOO));<br><br>But in the cases where the first argument uses the macro FOO,<br><br> getLocForEndOfToken(e->getArg(0)->getLocEnd())<br><br>would return an invalid loc, and<br><br> getLocForEndOfToken(SM.getSpellingLoc(e->getArg(0)->getLocEnd()))<br><br>would return the end of the<br><br> #define FOO "foo"<br><br>line. (And determining the end of the range to be removed, e->getArg(1)->getLocEnd(), has a similar problem if the second argument uses the macro ZERO.)<br></blockquote><div><br></div><div>Try this helper function that deals with macros, and make sure you are using trunk clang:</div><div><br></div><div><div><font face="Monaco">static CharSourceRange makeFileRangeBetweenArgs(SourceLocation EndArg0,<br> SourceLocation EndArg1,<br> const SourceManager &SM,<br> const LangOptions &LangOpts) {<br> if (EndArg0.isInvalid() || EndArg1.isInvalid())<br> return CharSourceRange();<br><br> // if the two locations came from the same macro argument, move up to macro argument spelling locations.<br> if (EndArg0.isMacroID() && EndArg1.isMacroID() &&<br> SM.isMacroArgExpansion(EndArg0) && SM.isMacroArgExpansion(EndArg1) &&<br> SM.getImmediateExpansionRange(EndArg0).first == SM.getImmediateExpansionRange(EndArg1).first) {<br> EndArg0 = SM.getImmediateMacroCallerLoc(EndArg0);<br> EndArg1 = SM.getImmediateMacroCallerLoc(EndArg1);<br> return makeFileRangeBetweenArgs(EndArg0, EndArg1, SM, LangOpts);<br> }<br><br> EndArg0 = Lexer::getLocForEndOfToken(EndArg0, 0, SM, LangOpts);<br> EndArg1 = Lexer::getLocForEndOfToken(EndArg1, 0, SM, LangOpts);<br><br> if (EndArg0.isFileID() && EndArg1.isFileID())<br> return CharSourceRange::getCharRange(EndArg0, EndArg1);<br><br> return CharSourceRange();<br>}<br></font><br></div></div><br><blockquote type="cite"><br>What I think I need is the location l1 of the punctuation ("," in this caes) preceeding the second argument and the location l2 of the punctuation (")" in this case) following it. Then, for each of the two lN, if spellN = SM.getSpellingLoc(lN) is contained in SM.getExpansionRange(lN), I (hope) it would be sound to drop the range from spell1 to before spell2. (This would miss cases like<br><br> #define COMMA ,<br> #define RPAREN )<br> f("foo" COMMA 0 RPAREN<br><br>but that's more acceptable for my use case than missing any of the cases given previously.) At least, that's my understanding so far (which might well be completely off track, though).<br><br>Input appreciated,<br>Stephan<br>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev<br></blockquote></div><br></body></html>