Fixes github issues #59178, #58464 and #62799.
The problem was that the LevelIndentTracker remembered
the indentation level of previous deeper levels when
leaving a scope. Afterwards, when it entered again a
deeper level, it blindly reused the previous
indentation level. In case the --lines option was used
such that the previous deeper level was not formatted,
that previous level was whatever happened to be there
in the source code. The formatter simply believed it.
This is fixed by letting the LevelIndentTracker forget
the previous deeper levels when stepping out of them
(=> the added resize() in LevelIndentTracker::nextLine()).
Note that this resize() existed in the past until LLVM
14.0.6, but was changed in https://reviews.llvm.org/D129064
(#56352, rev. 14c30c7) to fix a crash. Our commit here
essentially reverts that crash fix. The crash no longer
occurs, most likely because of the changes made in
https://reviews.llvm.org/D144296 (#60843).
However, just reverting 14c30c7 is not enough, since
then the LevelIndentTracker would forget the current
indent if it happens to encounter a preprocessor
directive on a lower level. Hence, the resize()
in nextLine() may not be executed when handling
a preprocessor directive.
The new test in
FormatTestSelective.ReformatRegionAdjustsIndent check
what originally triggered this patch.
The new tests in
FormatMacroRegardlessOfPreviousIndent check the
formatting of a preprocessor #define. They ensure
that the content of LevelIndentTracker::IndentForLevel
does not affect PP directives.
The new test FormatTestSelective.DontAssert checks
a case where a previous iteration of the present
patch triggered an assert().
See
https://github.com/llvm/llvm-project/issues/59178#issuecomment-1542637781
and https://reviews.llvm.org/D151047
for some more details.
Do we need this check? I assume resize has a check if it has to grow or shrink, so we would check twice when the size is to be changed and once if not.