mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
[Format] Don't derive pointers right based on space before method ref-qualifiers
The second space in `void foo() &` is always produced by clang-format, and isn't evidence of any particular style. Before this patch, it was considered evidence of PAS_Right, because there is a space before a pointerlike ampersand. This caused the following code to have "unstable" pointer alignment: void a() &; void b() &; int *x; PAS_Left, Derive=false would produce 'int* x' with other lines unchanged. But subsequent formatting with Derive=true would produce 'int *x' again. Differential Revision: https://reviews.llvm.org/D118921
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "ContinuationIndenter.h"
|
||||
#include "DefinitionBlockSeparator.h"
|
||||
#include "FormatInternal.h"
|
||||
#include "FormatToken.h"
|
||||
#include "FormatTokenLexer.h"
|
||||
#include "NamespaceEndCommentsFixer.h"
|
||||
#include "QualifierAlignmentFixer.h"
|
||||
@@ -1940,6 +1941,14 @@ private:
|
||||
for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {
|
||||
if (!Tok->is(TT_PointerOrReference))
|
||||
continue;
|
||||
// Don't treat space in `void foo() &&` as evidence.
|
||||
if (const auto *Prev = Tok->getPreviousNonComment()) {
|
||||
if (Prev->is(tok::r_paren) && Prev->MatchingParen)
|
||||
if (const auto *Func = Prev->MatchingParen->getPreviousNonComment())
|
||||
if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,
|
||||
TT_OverloadedOperator))
|
||||
continue;
|
||||
}
|
||||
bool SpaceBefore = Tok->hasWhitespaceBefore();
|
||||
bool SpaceAfter = Tok->Next->hasWhitespaceBefore();
|
||||
if (SpaceBefore && !SpaceAfter)
|
||||
|
||||
@@ -9710,6 +9710,25 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
|
||||
AlignLeftBreakTemplate);
|
||||
|
||||
verifyFormat("void (*foopt)(int) = &func;");
|
||||
|
||||
FormatStyle DerivePointerAlignment = getLLVMStyle();
|
||||
DerivePointerAlignment.DerivePointerAlignment = true;
|
||||
// There's always a space between the function and its trailing qualifiers.
|
||||
// This isn't evidence for PAS_Right (or for PAS_Left).
|
||||
std::string Prefix = "void a() &;\n"
|
||||
"void b() &;\n";
|
||||
verifyFormat(Prefix + "int* x;", DerivePointerAlignment);
|
||||
verifyFormat(Prefix + "int *x;", DerivePointerAlignment);
|
||||
// Same if the function is an overloaded operator instead.
|
||||
Prefix = "void operator()() &;\n"
|
||||
"void operator()() &;\n";
|
||||
verifyFormat(Prefix + "int* x;", DerivePointerAlignment);
|
||||
verifyFormat(Prefix + "int *x;", DerivePointerAlignment);
|
||||
// However a space between cv-qualifiers and ref-qualifiers *is* evidence.
|
||||
Prefix = "void a() const &;\n"
|
||||
"void b() const &;\n";
|
||||
EXPECT_EQ(Prefix + "int *x;",
|
||||
format(Prefix + "int* x;", DerivePointerAlignment));
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, UnderstandsNewAndDelete) {
|
||||
|
||||
Reference in New Issue
Block a user