[clang-format] Fix bug in parsing `operator<` with template
authorJino Park <pjessesco@gmail.com>
Thu, 20 Jan 2022 07:42:19 +0000 (08:42 +0100)
committerMarek Kurdej <marek.kurdej+llvm.org@gmail.com>
Thu, 20 Jan 2022 07:59:04 +0000 (08:59 +0100)
commit560eb2277bb5aea0982ce5f90321788cda3fe4b3
tree3c9f0edeb6dc0daa42a2ae5116a679700c686bff
parent8eae99dfe5411707605250d32a735d7b16453a55
[clang-format] Fix bug in parsing `operator<` with template

Fixes https://github.com/llvm/llvm-project/issues/44601.

This patch handles a bug when parsing a below example code :

```
template <class> class S;

template <class T> bool operator<(S<T> const &x, S<T> const &y) {
  return x.i < y.i;
}

template <class T> class S {
  int i = 42;
  friend bool operator< <>(S const &, S const &);
};

int main() { return S<int>{} < S<int>{}; }
```
which parse `< <>` as `<< >`, not `< <>` in terms of tokens as discussed in discord.

1. Add a condition in `tryMergeLessLess()` considering `operator` keyword and `>`
2. Force to leave a whitespace between `tok::less` and a template opener
3. Add unit test

Reviewed By: MyDeveloperDay, curdeius

Differential Revision: https://reviews.llvm.org/D117398
clang/lib/Format/FormatTokenLexer.cpp
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp