llvm-project/clang/lib/Format
Krasimir Georgiev ae1b7859cb [clang-format] Update noexcept reference qualifiers detection
Summary:
r373165 fixed an issue where a templated noexcept member function with a
reference qualifier would be indented more than expected:
```
// Formatting produced with LLVM style with AlwaysBreakTemplateDeclarations: Yes

// before r373165:
struct f {
  template <class T>
      void bar() && noexcept {}
};

// after:
struct f {
  template <class T>
  void bar() && noexcept {}
};

```
The way this is done is that in the AnnotatingParser in
`lib/FormatTokenAnnotator.cpp` the determination of the usage of a `&` or `&&`
(the line in determineTokenType

```
Current.Type = determineStarAmpUsage(...
```
is not performed in some cases anymore, combining with a few additional related
checks afterwards. The net effect of these checks results in the `&` or `&&`
token to start being classified as `TT_Unknown` in cases where before `r373165`
it would be classified as `TT_UnaryOperator` or `TT_PointerOrReference` by
`determineStarAmpUsage`.

This inadvertently caused 2 classes of regressions I'm aware of:

- The address-of `&` after a function assignment would be classified as
  `TT_Unknown`, causing spaces to surround it, disregarding style options:
```
// before r373165:
void (*fun_ptr)(void) = &fun;

// after:
void (*fun_ptr)(void) = & fun;
```

- In cases where there is a function declaration list -- looking macro between
  a template line and the start of the function declaration, an `&` as part of
  the return type would be classified as `TT_Unknown`, causing spaces to
  surround it:
```
// before r373165:
template <class T>
DEPRECATED("lala")
Type& foo();

// after:
template <class T>
DEPRECATED("lala")
Type & foo();
```

In these cases the problems are rooted in the skipping of the classification of
a `&` (and similarly `&&`) by determineStarAmpUsage which effects the formatting
decisions later in the pipeline.

I've looked into the goal of r373165 and noticed that replacing `noexcept` with
`const` in the given example produces no extra indentation with the old code:
```
// before r373165:
struct f {
  template <class T>
  int foo() & const {}
};

struct f {
  template <class T>
      int foo() & noexcept {}
};
```

I investigated how clang-format annotated these two examples differently to
determine the places where the processing of both diverges in the pipeline.
There were two places where the processing diverges, causing the extra indent in
the `noexcept` case:
1. The `const` is annotated as a `TT_TrailingAnnotation`, whereas `noexcept`
   is annotated as `TT_Unknown`. I've updated the `determineTokenType` function
   to account for this by adding a missing `tok:kw_noexcept` to the clause that
   marks a token as `TT_TrailingAnnotation`.
2. The `&` in the second example is wrongly identified as `TT_BinaryOperator`
   in `determineStarAmpUsage`. This is the reason for the extra indentation --
   clang-format gets confused and thinks this is an expression.
   I've updated `determineStarAmpUsage` to check for `tok:kw_noexcept`.

With these two updates in place, the additional parsing introduced by r373165
becomes unnecessary and all added tests pass (with updates, as now clang-format
respects the style configuration for spaces around the `&` in the test
examples).
I've removed these additions and added regression tests for the cases above.

Reviewers: AndWass, MyDeveloperDay

Reviewed By: MyDeveloperDay

Subscribers: cfe-commits

Tags: #clang, #clang-format

Differential Revision: https://reviews.llvm.org/D68695

llvm-svn: 374172
2019-10-09 14:46:08 +00:00
..
AffectedRangeManager.cpp Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
AffectedRangeManager.h Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
BreakableToken.cpp clang-format clang/lib/Format 2019-07-29 13:26:48 +00:00
BreakableToken.h [clang-format] Fix bug in block comment reflow that joins * and / 2019-05-03 23:15:40 +00:00
CMakeLists.txt Reland "Move #include manipulation code to new lib/Tooling/Inclusions." 2018-06-04 09:04:12 +00:00
ContinuationIndenter.cpp [clang-format] [PR43333] Fix C# breaking before function name when using Attributes 2019-10-04 07:56:49 +00:00
ContinuationIndenter.h [clang-format] Fix indent of trailing raw string param after newline 2019-04-18 17:14:05 +00:00
Encoding.h [clang-format][PR41964] Fix crash with SIGFPE when TabWidth is set to 0 and line starts with tab 2019-09-18 18:57:09 +00:00
Format.cpp [clang-format] [PR43333] Fix C# breaking before function name when using Attributes 2019-10-04 07:56:49 +00:00
FormatInternal.h Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
FormatToken.cpp Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
FormatToken.h clang-format: Support `if CONSTEXPR` if CONSTEXPR is a macro. 2019-07-27 02:41:40 +00:00
FormatTokenLexer.cpp [clang-format] [PR43338] C# clang format has space issues betweern C# only keywords 2019-10-04 08:10:22 +00:00
FormatTokenLexer.h [clang-format] [PR43338] C# clang format has space issues betweern C# only keywords 2019-10-04 08:10:22 +00:00
NamespaceEndCommentsFixer.cpp clang-format: Fix namespace end comments for namespaces with attributes and macros. 2019-07-23 17:49:45 +00:00
NamespaceEndCommentsFixer.h Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
SortJavaScriptImports.cpp Use llvm::stable_sort 2019-04-24 14:43:05 +00:00
SortJavaScriptImports.h Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
TokenAnalyzer.cpp Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
TokenAnalyzer.h [clang-format] Remove unused Environment constructor. 2019-04-18 00:36:51 +00:00
TokenAnnotator.cpp [clang-format] Update noexcept reference qualifiers detection 2019-10-09 14:46:08 +00:00
TokenAnnotator.h clang-format clang/lib/Format 2019-07-29 13:26:48 +00:00
UnwrappedLineFormatter.cpp [clang-format] Add ability to wrap braces after multi-line control statements 2019-10-03 18:42:31 +00:00
UnwrappedLineFormatter.h [clang-format] [NFC] clang-format the Format library 2019-03-01 09:09:54 +00:00
UnwrappedLineParser.cpp [clang-format] Add ability to wrap braces after multi-line control statements 2019-10-03 18:42:31 +00:00
UnwrappedLineParser.h [clang-format] Add new style option IndentGotoLabels 2019-09-12 10:07:14 +00:00
UsingDeclarationsSorter.cpp Use llvm::stable_sort 2019-04-24 14:43:05 +00:00
UsingDeclarationsSorter.h Update the file headers across all of the LLVM projects in the monorepo 2019-01-19 08:50:56 +00:00
WhitespaceManager.cpp [clang-format][PR41964] Fix crash with SIGFPE when TabWidth is set to 0 and line starts with tab 2019-09-18 18:57:09 +00:00
WhitespaceManager.h clang-format: Add new style option AlignConsecutiveMacros 2019-07-02 15:53:14 +00:00