[PATCH] Fix makeFileCharRange for macro arguments in the presence of nested macro calls.
Argyrios Kyrtzidis
akyrtzi at gmail.com
Thu May 16 14:41:32 PDT 2013
Hi Manuel,
I committed r182055 with a modified version of your patch. It also fixes a couple of cases that were not handled correctly:
-if the range overlapped the arguments of 2 function macros it would give a valid range instead of giving up, e.g:
#define M(x) x
M(c M(i)) M(M(i) c)
a range of the two 'i''s would give this range
M(c M(i)) M(M(i) c)
^----------^
which is not good.
-It would give up if the range resided in one macro argument but did not have expansions in both ends, e.g:
#define M(x) x
M(M(i) c c)
it would give up if you asked for the range of ['i', 'c'], instead of returning this
M(M(i) c c)
^----^
More commenting below..
On May 8, 2013, at 8:19 AM, Manuel Klimek <klimek at google.com> wrote:
> Hi doug.gregor,
>
> Added tests that show the problems:
> 1. isAt(Start|End)OfMacroExpansion did not work correctly for nested macro
> calls; consider
> #define M(x) x
> #define N(x) x
> N(f(M(i)))
> Here getSourceText would return "M(f(M(i)))" for the token location of 'i',
> as makeFileCharRange would consider 'i' to be at the start of the macro.
> The problem is that getDecomposedLoc in this case returns the offset from
> the inner call to 'M', and I have not found a way to get the offset from
> 'N' easily, as this information seems to be incrementally overwritten during
> preprocessing.
> The solution is to instead take the location before / after the examined
> location and check whether its expansion location is the same as the
> expansion location of the examined location. If this is the case, the
> location before / after is not the first / last token of the macro expansion.
>
> 2. makeFileCharRange only considered the outermost layer of macro expansion,
> thus not returning the widest possible range if the outermost expansion
> was not fully describing the range.
> After fixing (1), this would lead to getSourceText returning an empty
> string instead of "M(i)".
>
> Note that I'm still not sure I'm entirely happy with this implementation.
> So far I have not found a good way to figure out whether the location
> is good to call getLocWithOffset(-1) or getLocWithOffset(tokLen + 1) on.
> Especially for the latter, the check for SM.isLocalSourceLocation(...) seems
> to work, but doesn't seem like the right solution. Any hints for a better
> solution would be highly welcome.
I think you were on the right track but we can use the previous/next FileID to check instead using locations like that.
And since this is very dependent in internal mechanisms of the SourceManager I abstracted such logic in a couple of helper functions in SourceManager.
If there are more cases that we don't handle correctly, let me know.
-Argyrios
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130516/de82bf87/attachment.html>
More information about the cfe-commits
mailing list