This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Fixed toHalfOpenFileRange
ClosedPublic

Authored by SureYeaah on Jul 11 2019, 5:57 AM.

Details

Summary
  • Fixed toHalfOpenFileRange to work for macros as well as template

instantiations

  • Added unit tests

Breaking test case for older version of toHalfOpenFileRange:
\# define FOO(X) X++
int a = 1;
int b = FOO(a);
toHalfOpenFileRange for the sourceRange of VarDecl for b returned the
wrong Range.

Diff Detail

Repository
rL LLVM

Event Timeline

SureYeaah created this revision.Jul 11 2019, 5:57 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 11 2019, 5:57 AM
SureYeaah updated this revision to Diff 209193.Jul 11 2019, 6:08 AM

Minor fixes

Thanks for fixing this, this stuff is such a tangled web.

Logic seems great, so just style/test nits.

clang-tools-extra/clangd/SourceCode.cpp
261 ↗(On Diff #209193)

>>= too? That's legal with variable templates.

(If you're deliberately choosing different behavior that definitely deserves a comment)

303 ↗(On Diff #209193)

Explain why we're implementing this from scratch?

Maybe something like

This is similar to getFileLocation in SourceManager, which chooses getExpansionRange or getSpellingLocation (for macro arguments).
However:
 - we need full range information, which getFileLocation discards
 - (there's something else wrong with getExpansionRange, right?)
 - we want to split `>>` tokens
338 ↗(On Diff #209193)

maybe a comment "convert from closed token range to half-open range"

clang-tools-extra/clangd/SourceCode.h
69 ↗(On Diff #209193)

This isn't well-defined without more information, because a SourceRange may be token/char range etc.
(And in fact this appears to treat it as a half-open range, which isn't the most common type).

Because this is ambiguous, fairly rare, and simple, can we just inline it into the test where it's used instead?

clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
410 ↗(On Diff #209193)

this is a function on ranges, so only using decls isn't a limitation per se.

Is there a type of range you're unable to test because you can't construct it as the source range of a decl? If so, please say which. If not I think we should just drop this comment.

412 ↗(On Diff #209193)

Can you add an explanation of what's in the test?

e.g. "each marked range should be the file range of the decl with the same name"

421 ↗(On Diff #209193)

some tests where the expansion range is a macro arg? e.g.

#define ECHO(X) X
ECHO($e[[ECHO(int) ECHO(e)]])

(if I'm understanding right)

432 ↗(On Diff #209193)

I like the "factored out" test, but one trap is that if assertions fail then you can't tell which case it was.

You can use SCOPED_TRACE(Name) at the top of this block to make sure we print the range name.

kadircet added inline comments.Jul 11 2019, 7:08 AM
clang-tools-extra/clangd/SourceCode.cpp
252 ↗(On Diff #209193)

maybe move the comment to just before if(thetok.is(greatergreater)) check?

260 ↗(On Diff #209193)

re-arrange for less indentation:

if(Lexer::getRawToken(...))
  return 0;
if(TheTok.is(tok::greater...)
  return 1;
return TheTok...;
SureYeaah updated this revision to Diff 209363.Jul 11 2019, 3:56 PM
SureYeaah marked 12 inline comments as done.

Added comments and minor changes

SureYeaah added inline comments.Jul 11 2019, 4:03 PM
clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
410 ↗(On Diff #209193)

e.g. Nested template instantiation (TemplateSpecializationTypeLoc)

421 ↗(On Diff #209193)

In this case, the FileRange would be

ECHO(ECHO($e[[int) ECHO(e]]));

So the code works correctly. But it's not how we want it to behave right?

sammccall accepted this revision.Jul 12 2019, 3:10 AM
sammccall added inline comments.
clang-tools-extra/clangd/SourceCode.cpp
261 ↗(On Diff #209193)

nit: please don't just mark comments "done" if there's reason not to do them - a brief explanation in the review and/or the code is useful to keep track.

For the record, it turns out that it seems C++ doesn't actually allow >>= to be ambiguous - the user has to put a space before = if it's not a shift.

clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
410 ↗(On Diff #209193)

That's a type of decl, not a type of range.

This function inputs and outputs a range, so the type of decl used isn't relevant to its correctness.
Is there a particular type of range (e.g. certain macro expansion structure and pair of points) that you want to test but can't construct a decl to cover?

421 ↗(On Diff #209193)

That looks OK to me. It's surprising, but I think defensible.

The most likely source of complaints is I guess if we use selection tree to implement structured selection expansion. Anyway, whatever the behavior is, thanks for adding the test :-)

This revision is now accepted and ready to land.Jul 12 2019, 3:10 AM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptJul 12 2019, 4:42 AM