summaryrefslogtreecommitdiffstats
path: root/unittests/Format/FormatTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Format/FormatTest.cpp')
-rw-r--r--unittests/Format/FormatTest.cpp1706
1 files changed, 1646 insertions, 60 deletions
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index bcbdbbf3e5..82530c0376 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -30,24 +30,25 @@ FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); }
class FormatTest : public ::testing::Test {
protected:
- enum IncompleteCheck {
- IC_ExpectComplete,
- IC_ExpectIncomplete,
- IC_DoNotCheck
+ enum StatusCheck {
+ SC_ExpectComplete,
+ SC_ExpectIncomplete,
+ SC_DoNotCheck
};
std::string format(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle(),
- IncompleteCheck CheckIncomplete = IC_ExpectComplete) {
+ StatusCheck CheckComplete = SC_ExpectComplete) {
DEBUG(llvm::errs() << "---\n");
DEBUG(llvm::errs() << Code << "\n\n");
std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
- bool IncompleteFormat = false;
+ FormattingAttemptStatus Status;
tooling::Replacements Replaces =
- reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
- if (CheckIncomplete != IC_DoNotCheck) {
- bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete;
- EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n";
+ reformat(Style, Code, Ranges, "<stdin>", &Status);
+ if (CheckComplete != SC_DoNotCheck) {
+ bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete;
+ EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete)
+ << Code << "\n\n";
}
ReplacementCount = Replaces.size();
auto Result = applyAllReplacements(Code, Replaces);
@@ -56,16 +57,17 @@ protected:
return *Result;
}
- FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) {
- FormatStyle Style = getLLVMStyle();
+ FormatStyle getStyleWithColumns(FormatStyle Style, unsigned ColumnLimit) {
Style.ColumnLimit = ColumnLimit;
return Style;
}
+ FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) {
+ return getStyleWithColumns(getLLVMStyle(), ColumnLimit);
+ }
+
FormatStyle getGoogleStyleWithColumns(unsigned ColumnLimit) {
- FormatStyle Style = getGoogleStyle();
- Style.ColumnLimit = ColumnLimit;
- return Style;
+ return getStyleWithColumns(getGoogleStyle(), ColumnLimit);
}
void verifyFormat(llvm::StringRef Code,
@@ -83,7 +85,7 @@ protected:
void verifyIncompleteFormat(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle()) {
EXPECT_EQ(Code.str(),
- format(test::messUp(Code), Style, IC_ExpectIncomplete));
+ format(test::messUp(Code), Style, SC_ExpectIncomplete));
}
void verifyGoogleFormat(llvm::StringRef Code) {
@@ -98,7 +100,7 @@ protected:
/// \brief Verify that clang-format does not crash on the given input.
void verifyNoCrash(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle()) {
- format(Code, Style, IC_DoNotCheck);
+ format(Code, Style, SC_DoNotCheck);
}
int ReplacementCount;
@@ -331,6 +333,16 @@ TEST_F(FormatTest, RecognizesBinaryOperatorKeywords) {
verifyFormat("x = (a) xor (b);");
}
+TEST_F(FormatTest, RecognizesUnaryOperatorKeywords) {
+ verifyFormat("x = compl(a);");
+ verifyFormat("x = not(a);");
+ verifyFormat("x = bitand(a);");
+ // Unary operator must not be merged with the next identifier
+ verifyFormat("x = compl a;");
+ verifyFormat("x = not a;");
+ verifyFormat("x = bitand a;");
+}
+
//===----------------------------------------------------------------------===//
// Tests for control statements.
//===----------------------------------------------------------------------===//
@@ -339,9 +351,21 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
verifyFormat("if (true)\n f();\ng();");
verifyFormat("if (a)\n if (b)\n if (c)\n g();\nh();");
verifyFormat("if (a)\n if (b) {\n f();\n }\ng();");
+ verifyFormat("if constexpr (true)\n"
+ " f();\ng();");
+ verifyFormat("if constexpr (a)\n"
+ " if constexpr (b)\n"
+ " if constexpr (c)\n"
+ " g();\n"
+ "h();");
+ verifyFormat("if constexpr (a)\n"
+ " if constexpr (b) {\n"
+ " f();\n"
+ " }\n"
+ "g();");
FormatStyle AllowsMergedIf = getLLVMStyle();
- AllowsMergedIf.AlignEscapedNewlinesLeft = true;
+ AllowsMergedIf.AlignEscapedNewlines = FormatStyle::ENAS_Left;
AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true;
verifyFormat("if (a)\n"
" // comment\n"
@@ -415,17 +439,28 @@ TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) {
TEST_F(FormatTest, FormatShortBracedStatements) {
FormatStyle AllowSimpleBracedStatements = getLLVMStyle();
+ AllowSimpleBracedStatements.ColumnLimit = 40;
AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = true;
AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true;
AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true;
+ AllowSimpleBracedStatements.BreakBeforeBraces = FormatStyle::BS_Custom;
+ AllowSimpleBracedStatements.BraceWrapping.AfterFunction = true;
+ AllowSimpleBracedStatements.BraceWrapping.SplitEmptyRecord = false;
+
verifyFormat("if (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements);
verifyFormat("while (true) {}", AllowSimpleBracedStatements);
verifyFormat("for (;;) {}", AllowSimpleBracedStatements);
verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("if constexpr (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("if (true) {\n"
+ " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n"
+ "}",
+ AllowSimpleBracedStatements);
verifyFormat("if (true) { //\n"
" f();\n"
"}",
@@ -442,12 +477,21 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
"}",
AllowSimpleBracedStatements);
+ verifyFormat("struct A2 {\n"
+ " int X;\n"
+ "};",
+ AllowSimpleBracedStatements);
+ verifyFormat("typedef struct A2 {\n"
+ " int X;\n"
+ "} A2_t;",
+ AllowSimpleBracedStatements);
verifyFormat("template <int> struct A2 {\n"
" struct B {};\n"
"};",
AllowSimpleBracedStatements);
AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false;
+ verifyFormat("if (true) {}", AllowSimpleBracedStatements);
verifyFormat("if (true) {\n"
" f();\n"
"}",
@@ -460,14 +504,83 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
AllowSimpleBracedStatements);
AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false;
+ verifyFormat("while (true) {}", AllowSimpleBracedStatements);
verifyFormat("while (true) {\n"
" f();\n"
"}",
AllowSimpleBracedStatements);
+ verifyFormat("for (;;) {}", AllowSimpleBracedStatements);
verifyFormat("for (;;) {\n"
" f();\n"
"}",
AllowSimpleBracedStatements);
+
+ AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true;
+ AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true;
+ AllowSimpleBracedStatements.BraceWrapping.AfterControlStatement = true;
+
+ verifyFormat("if (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("while (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("for (;;) {}", AllowSimpleBracedStatements);
+ verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("if constexpr (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("if (true)\n"
+ "{\n"
+ " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("if (true)\n"
+ "{ //\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("if (true)\n"
+ "{\n"
+ " f();\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("if (true)\n"
+ "{\n"
+ " f();\n"
+ "} else\n"
+ "{\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+
+ AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false;
+ verifyFormat("if (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("if (true)\n"
+ "{\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("if (true)\n"
+ "{\n"
+ " f();\n"
+ "} else\n"
+ "{\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+
+ AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false;
+ verifyFormat("while (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("while (true)\n"
+ "{\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("for (;;) {}", AllowSimpleBracedStatements);
+ verifyFormat("for (;;)\n"
+ "{\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
}
TEST_F(FormatTest, ParseIfElse) {
@@ -494,6 +607,19 @@ TEST_F(FormatTest, ParseIfElse) {
"else {\n"
" i();\n"
"}");
+ verifyFormat("if (true)\n"
+ " if constexpr (true)\n"
+ " if (true) {\n"
+ " if constexpr (true)\n"
+ " f();\n"
+ " } else {\n"
+ " g();\n"
+ " }\n"
+ " else\n"
+ " h();\n"
+ "else {\n"
+ " i();\n"
+ "}");
verifyFormat("void f() {\n"
" if (a) {\n"
" } else {\n"
@@ -509,6 +635,12 @@ TEST_F(FormatTest, ElseIf) {
" g();\n"
"else\n"
" h();");
+ verifyFormat("if constexpr (a)\n"
+ " f();\n"
+ "else if constexpr (b)\n"
+ " g();\n"
+ "else\n"
+ " h();");
verifyFormat("if (a) {\n"
" f();\n"
"}\n"
@@ -526,6 +658,11 @@ TEST_F(FormatTest, ElseIf) {
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n"
"}",
getLLVMStyleWithColumns(62));
+ verifyFormat("if (a) {\n"
+ "} else if constexpr (\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n"
+ "}",
+ getLLVMStyleWithColumns(62));
}
TEST_F(FormatTest, FormatsForLoop) {
@@ -599,6 +736,10 @@ TEST_F(FormatTest, FormatsForLoop) {
" I != E;\n"
" ++I) {\n}",
NoBinPacking);
+
+ FormatStyle AlignLeft = getLLVMStyle();
+ AlignLeft.PointerAlignment = FormatStyle::PAS_Left;
+ verifyFormat("for (A* a = start; a < end; ++a, ++value) {\n}", AlignLeft);
}
TEST_F(FormatTest, RangeBasedForLoops) {
@@ -777,12 +918,35 @@ TEST_F(FormatTest, FormatsSwitchStatement) {
" case A:\n"
" f();\n"
" break;\n"
- " // On B:\n"
+ " // fallthrough\n"
" case B:\n"
" g();\n"
" break;\n"
" }\n"
"});");
+ EXPECT_EQ("DEBUG({\n"
+ " switch (x) {\n"
+ " case A:\n"
+ " f();\n"
+ " break;\n"
+ " // On B:\n"
+ " case B:\n"
+ " g();\n"
+ " break;\n"
+ " }\n"
+ "});",
+ format("DEBUG({\n"
+ " switch (x) {\n"
+ " case A:\n"
+ " f();\n"
+ " break;\n"
+ " // On B:\n"
+ " case B:\n"
+ " g();\n"
+ " break;\n"
+ " }\n"
+ "});",
+ getLLVMStyle()));
verifyFormat("switch (a) {\n"
"case (b):\n"
" return;\n"
@@ -826,6 +990,77 @@ TEST_F(FormatTest, ShortCaseLabels) {
"}",
Style);
verifyFormat("switch (a) {\n"
+ "case 0: return; // comment\n"
+ "case 1: break; // comment\n"
+ "case 2: return;\n"
+ "// comment\n"
+ "case 3: return;\n"
+ "// comment 1\n"
+ "// comment 2\n"
+ "// comment 3\n"
+ "case 4: break; /* comment */\n"
+ "case 5:\n"
+ " // comment\n"
+ " break;\n"
+ "case 6: /* comment */ x = 1; break;\n"
+ "case 7: x = /* comment */ 1; break;\n"
+ "case 8:\n"
+ " x = 1; /* comment */\n"
+ " break;\n"
+ "case 9:\n"
+ " break; // comment line 1\n"
+ " // comment line 2\n"
+ "}",
+ Style);
+ EXPECT_EQ("switch (a) {\n"
+ "case 1:\n"
+ " x = 8;\n"
+ " // fall through\n"
+ "case 2: x = 8;\n"
+ "// comment\n"
+ "case 3:\n"
+ " return; /* comment line 1\n"
+ " * comment line 2 */\n"
+ "case 4: i = 8;\n"
+ "// something else\n"
+ "#if FOO\n"
+ "case 5: break;\n"
+ "#endif\n"
+ "}",
+ format("switch (a) {\n"
+ "case 1: x = 8;\n"
+ " // fall through\n"
+ "case 2:\n"
+ " x = 8;\n"
+ "// comment\n"
+ "case 3:\n"
+ " return; /* comment line 1\n"
+ " * comment line 2 */\n"
+ "case 4:\n"
+ " i = 8;\n"
+ "// something else\n"
+ "#if FOO\n"
+ "case 5: break;\n"
+ "#endif\n"
+ "}",
+ Style));
+ EXPECT_EQ("switch (a) {\n" "case 0:\n"
+ " return; // long long long long long long long long long long long long comment\n"
+ " // line\n" "}",
+ format("switch (a) {\n"
+ "case 0: return; // long long long long long long long long long long long long comment line\n"
+ "}",
+ Style));
+ EXPECT_EQ("switch (a) {\n"
+ "case 0:\n"
+ " return; /* long long long long long long long long long long long long comment\n"
+ " line */\n"
+ "}",
+ format("switch (a) {\n"
+ "case 0: return; /* long long long long long long long long long long long long comment line */\n"
+ "}",
+ Style));
+ verifyFormat("switch (a) {\n"
"#if FOO\n"
"case 0: return 0;\n"
"#endif\n"
@@ -1172,6 +1407,32 @@ TEST_F(FormatTest, FormatsEnumTypes) {
verifyFormat("enum X : std::uint32_t { A, B };");
}
+TEST_F(FormatTest, FormatsTypedefEnum) {
+ FormatStyle Style = getLLVMStyle();
+ Style.ColumnLimit = 40;
+ verifyFormat("typedef enum {} EmptyEnum;");
+ verifyFormat("typedef enum { A, B, C } ShortEnum;");
+ verifyFormat("typedef enum {\n"
+ " ZERO = 0,\n"
+ " ONE = 1,\n"
+ " TWO = 2,\n"
+ " THREE = 3\n"
+ "} LongEnum;",
+ Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterEnum = true;
+ verifyFormat("typedef enum {} EmptyEnum;");
+ verifyFormat("typedef enum { A, B, C } ShortEnum;");
+ verifyFormat("typedef enum\n"
+ "{\n"
+ " ZERO = 0,\n"
+ " ONE = 1,\n"
+ " TWO = 2,\n"
+ " THREE = 3\n"
+ "} LongEnum;",
+ Style);
+}
+
TEST_F(FormatTest, FormatsNSEnums) {
verifyGoogleFormat("typedef NS_ENUM(NSInteger, SomeName) { AAA, BBB }");
verifyGoogleFormat("typedef NS_ENUM(NSInteger, MyType) {\n"
@@ -1308,7 +1569,177 @@ TEST_F(FormatTest, FormatsNamespaces) {
Style));
}
-TEST_F(FormatTest, FormatsExternC) { verifyFormat("extern \"C\" {\nint a;"); }
+TEST_F(FormatTest, FormatsCompactNamespaces) {
+ FormatStyle Style = getLLVMStyle();
+ Style.CompactNamespaces = true;
+
+ verifyFormat("namespace A { namespace B {\n"
+ "}} // namespace A::B",
+ Style);
+
+ EXPECT_EQ("namespace out { namespace in {\n"
+ "}} // namespace out::in",
+ format("namespace out {\n"
+ "namespace in {\n"
+ "} // namespace in\n"
+ "} // namespace out",
+ Style));
+
+ // Only namespaces which have both consecutive opening and end get compacted
+ EXPECT_EQ("namespace out {\n"
+ "namespace in1 {\n"
+ "} // namespace in1\n"
+ "namespace in2 {\n"
+ "} // namespace in2\n"
+ "} // namespace out",
+ format("namespace out {\n"
+ "namespace in1 {\n"
+ "} // namespace in1\n"
+ "namespace in2 {\n"
+ "} // namespace in2\n"
+ "} // namespace out",
+ Style));
+
+ EXPECT_EQ("namespace out {\n"
+ "int i;\n"
+ "namespace in {\n"
+ "int j;\n"
+ "} // namespace in\n"
+ "int k;\n"
+ "} // namespace out",
+ format("namespace out { int i;\n"
+ "namespace in { int j; } // namespace in\n"
+ "int k; } // namespace out",
+ Style));
+
+ EXPECT_EQ("namespace A { namespace B { namespace C {\n"
+ "}}} // namespace A::B::C\n",
+ format("namespace A { namespace B {\n"
+ "namespace C {\n"
+ "}} // namespace B::C\n"
+ "} // namespace A\n",
+ Style));
+
+ Style.ColumnLimit = 40;
+ EXPECT_EQ("namespace aaaaaaaaaa {\n"
+ "namespace bbbbbbbbbb {\n"
+ "}} // namespace aaaaaaaaaa::bbbbbbbbbb",
+ format("namespace aaaaaaaaaa {\n"
+ "namespace bbbbbbbbbb {\n"
+ "} // namespace bbbbbbbbbb\n"
+ "} // namespace aaaaaaaaaa",
+ Style));
+
+ EXPECT_EQ("namespace aaaaaa { namespace bbbbbb {\n"
+ "namespace cccccc {\n"
+ "}}} // namespace aaaaaa::bbbbbb::cccccc",
+ format("namespace aaaaaa {\n"
+ "namespace bbbbbb {\n"
+ "namespace cccccc {\n"
+ "} // namespace cccccc\n"
+ "} // namespace bbbbbb\n"
+ "} // namespace aaaaaa",
+ Style));
+ Style.ColumnLimit = 80;
+
+ // Extra semicolon after 'inner' closing brace prevents merging
+ EXPECT_EQ("namespace out { namespace in {\n"
+ "}; } // namespace out::in",
+ format("namespace out {\n"
+ "namespace in {\n"
+ "}; // namespace in\n"
+ "} // namespace out",
+ Style));
+
+ // Extra semicolon after 'outer' closing brace is conserved
+ EXPECT_EQ("namespace out { namespace in {\n"
+ "}}; // namespace out::in",
+ format("namespace out {\n"
+ "namespace in {\n"
+ "} // namespace in\n"
+ "}; // namespace out",
+ Style));
+
+ Style.NamespaceIndentation = FormatStyle::NI_All;
+ EXPECT_EQ("namespace out { namespace in {\n"
+ " int i;\n"
+ "}} // namespace out::in",
+ format("namespace out {\n"
+ "namespace in {\n"
+ "int i;\n"
+ "} // namespace in\n"
+ "} // namespace out",
+ Style));
+ EXPECT_EQ("namespace out { namespace mid {\n"
+ " namespace in {\n"
+ " int j;\n"
+ " } // namespace in\n"
+ " int k;\n"
+ "}} // namespace out::mid",
+ format("namespace out { namespace mid {\n"
+ "namespace in { int j; } // namespace in\n"
+ "int k; }} // namespace out::mid",
+ Style));
+
+ Style.NamespaceIndentation = FormatStyle::NI_Inner;
+ EXPECT_EQ("namespace out { namespace in {\n"
+ " int i;\n"
+ "}} // namespace out::in",
+ format("namespace out {\n"
+ "namespace in {\n"
+ "int i;\n"
+ "} // namespace in\n"
+ "} // namespace out",
+ Style));
+ EXPECT_EQ("namespace out { namespace mid { namespace in {\n"
+ " int i;\n"
+ "}}} // namespace out::mid::in",
+ format("namespace out {\n"
+ "namespace mid {\n"
+ "namespace in {\n"
+ "int i;\n"
+ "} // namespace in\n"
+ "} // namespace mid\n"
+ "} // namespace out",
+ Style));
+}
+
+TEST_F(FormatTest, FormatsExternC) {
+ verifyFormat("extern \"C\" {\nint a;");
+ verifyFormat("extern \"C\" {}");
+ verifyFormat("extern \"C\" {\n"
+ "int foo();\n"
+ "}");
+ verifyFormat("extern \"C\" int foo() {}");
+ verifyFormat("extern \"C\" int foo();");
+ verifyFormat("extern \"C\" int foo() {\n"
+ " int i = 42;\n"
+ " return i;\n"
+ "}");
+
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterFunction = true;
+ verifyFormat("extern \"C\" int foo() {}", Style);
+ verifyFormat("extern \"C\" int foo();", Style);
+ verifyFormat("extern \"C\" int foo()\n"
+ "{\n"
+ " int i = 42;\n"
+ " return i;\n"
+ "}",
+ Style);
+
+ Style.BraceWrapping.AfterExternBlock = true;
+ Style.BraceWrapping.SplitEmptyRecord = false;
+ verifyFormat("extern \"C\"\n"
+ "{}",
+ Style);
+ verifyFormat("extern \"C\"\n"
+ "{\n"
+ " int foo();\n"
+ "}",
+ Style);
+}
TEST_F(FormatTest, FormatsInlineASM) {
verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
@@ -1521,6 +1952,19 @@ TEST_F(FormatTest, DesignatedInitializers) {
" .eeeeeeeeeeeeeeeeeeeeeeeeeee = 5};");
verifyGoogleFormat("const struct A a = {.a = 1, .b = 2};");
+
+ verifyFormat("const struct A a = {[0] = 1, [1] = 2};");
+ verifyFormat("const struct A a = {[1] = aaaaaaaaaa,\n"
+ " [2] = bbbbbbbbbb,\n"
+ " [3] = cccccccccc,\n"
+ " [4] = dddddddddd,\n"
+ " [5] = eeeeeeeeee};");
+ verifyFormat("const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = {\n"
+ " [1] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " [2] = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
+ " [3] = cccccccccccccccccccccccccccccccccccccc,\n"
+ " [4] = dddddddddddddddddddddddddddddddddddddd,\n"
+ " [5] = eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee};");
}
TEST_F(FormatTest, NestedStaticInitializers) {
@@ -1986,8 +2430,191 @@ TEST_F(FormatTest, LayoutMacroDefinitionsStatementsSpanningBlocks) {
getLLVMStyleWithColumns(11));
}
-TEST_F(FormatTest, IndentPreprocessorDirectivesAtZero) {
- EXPECT_EQ("{\n {\n#define A\n }\n}", format("{{\n#define A\n}}"));
+TEST_F(FormatTest, IndentPreprocessorDirectives) {
+ FormatStyle Style = getLLVMStyle();
+ Style.IndentPPDirectives = FormatStyle::PPDIS_None;
+ Style.ColumnLimit = 40;
+ verifyFormat("#ifdef _WIN32\n"
+ "#define A 0\n"
+ "#ifdef VAR2\n"
+ "#define B 1\n"
+ "#include <someheader.h>\n"
+ "#define MACRO \\\n"
+ " some_very_long_func_aaaaaaaaaa();\n"
+ "#endif\n"
+ "#else\n"
+ "#define A 1\n"
+ "#endif",
+ Style);
+ Style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash;
+ verifyFormat("#ifdef _WIN32\n"
+ "# define A 0\n"
+ "# ifdef VAR2\n"
+ "# define B 1\n"
+ "# include <someheader.h>\n"
+ "# define MACRO \\\n"
+ " some_very_long_func_aaaaaaaaaa();\n"
+ "# endif\n"
+ "#else\n"
+ "# define A 1\n"
+ "#endif",
+ Style);
+ verifyFormat("#if A\n"
+ "# define MACRO \\\n"
+ " void a(int x) { \\\n"
+ " b(); \\\n"
+ " c(); \\\n"
+ " d(); \\\n"
+ " e(); \\\n"
+ " f(); \\\n"
+ " }\n"
+ "#endif",
+ Style);
+ // Comments before include guard.
+ verifyFormat("// file comment\n"
+ "// file comment\n"
+ "#ifndef HEADER_H\n"
+ "#define HEADER_H\n"
+ "code();\n"
+ "#endif",
+ Style);
+ // Test with include guards.
+ // EXPECT_EQ is used because verifyFormat() calls messUp() which incorrectly
+ // merges lines.
+ verifyFormat("#ifndef HEADER_H\n"
+ "#define HEADER_H\n"
+ "code();\n"
+ "#endif",
+ Style);
+ // Include guards must have a #define with the same variable immediately
+ // after #ifndef.
+ verifyFormat("#ifndef NOT_GUARD\n"
+ "# define FOO\n"
+ "code();\n"
+ "#endif",
+ Style);
+
+ // Include guards must cover the entire file.
+ verifyFormat("code();\n"
+ "code();\n"
+ "#ifndef NOT_GUARD\n"
+ "# define NOT_GUARD\n"
+ "code();\n"
+ "#endif",
+ Style);
+ verifyFormat("#ifndef NOT_GUARD\n"
+ "# define NOT_GUARD\n"
+ "code();\n"
+ "#endif\n"
+ "code();",
+ Style);
+ // Test with trailing blank lines.
+ verifyFormat("#ifndef HEADER_H\n"
+ "#define HEADER_H\n"
+ "code();\n"
+ "#endif\n",
+ Style);
+ // Include guards don't have #else.
+ verifyFormat("#ifndef NOT_GUARD\n"
+ "# define NOT_GUARD\n"
+ "code();\n"
+ "#else\n"
+ "#endif",
+ Style);
+ verifyFormat("#ifndef NOT_GUARD\n"
+ "# define NOT_GUARD\n"
+ "code();\n"
+ "#elif FOO\n"
+ "#endif",
+ Style);
+ // FIXME: This doesn't handle the case where there's code between the
+ // #ifndef and #define but all other conditions hold. This is because when
+ // the #define line is parsed, UnwrappedLineParser::Lines doesn't hold the
+ // previous code line yet, so we can't detect it.
+ EXPECT_EQ("#ifndef NOT_GUARD\n"
+ "code();\n"
+ "#define NOT_GUARD\n"
+ "code();\n"
+ "#endif",
+ format("#ifndef NOT_GUARD\n"
+ "code();\n"
+ "# define NOT_GUARD\n"
+ "code();\n"
+ "#endif",
+ Style));
+ // FIXME: This doesn't handle cases where legitimate preprocessor lines may
+ // be outside an include guard. Examples are #pragma once and
+ // #pragma GCC diagnostic, or anything else that does not change the meaning
+ // of the file if it's included multiple times.
+ EXPECT_EQ("#ifdef WIN32\n"
+ "# pragma once\n"
+ "#endif\n"
+ "#ifndef HEADER_H\n"
+ "# define HEADER_H\n"
+ "code();\n"
+ "#endif",
+ format("#ifdef WIN32\n"
+ "# pragma once\n"
+ "#endif\n"
+ "#ifndef HEADER_H\n"
+ "#define HEADER_H\n"
+ "code();\n"
+ "#endif",
+ Style));
+ // FIXME: This does not detect when there is a single non-preprocessor line
+ // in front of an include-guard-like structure where other conditions hold
+ // because ScopedLineState hides the line.
+ EXPECT_EQ("code();\n"
+ "#ifndef HEADER_H\n"
+ "#define HEADER_H\n"
+ "code();\n"
+ "#endif",
+ format("code();\n"
+ "#ifndef HEADER_H\n"
+ "# define HEADER_H\n"
+ "code();\n"
+ "#endif",
+ Style));
+ // FIXME: The comment indent corrector in TokenAnnotator gets thrown off by
+ // preprocessor indentation.
+ EXPECT_EQ("#if 1\n"
+ " // comment\n"
+ "# define A 0\n"
+ "// comment\n"
+ "# define B 0\n"
+ "#endif",
+ format("#if 1\n"
+ "// comment\n"
+ "# define A 0\n"
+ " // comment\n"
+ "# define B 0\n"
+ "#endif",
+ Style));
+ // Test with tabs.
+ Style.UseTab = FormatStyle::UT_Always;
+ Style.IndentWidth = 8;
+ Style.TabWidth = 8;
+ verifyFormat("#ifdef _WIN32\n"
+ "#\tdefine A 0\n"
+ "#\tifdef VAR2\n"
+ "#\t\tdefine B 1\n"
+ "#\t\tinclude <someheader.h>\n"
+ "#\t\tdefine MACRO \\\n"
+ "\t\t\tsome_very_long_func_aaaaaaaaaa();\n"
+ "#\tendif\n"
+ "#else\n"
+ "#\tdefine A 1\n"
+ "#endif",
+ Style);
+
+ // Regression test: Multiline-macro inside include guards.
+ verifyFormat("#ifndef HEADER_H\n"
+ "#define HEADER_H\n"
+ "#define A() \\\n"
+ " int i; \\\n"
+ " int j;\n"
+ "#endif // HEADER_H",
+ getLLVMStyleWithColumns(20));
}
TEST_F(FormatTest, FormatHashIfNotAtStartOfLine) {
@@ -2002,13 +2629,63 @@ TEST_F(FormatTest, FormatUnbalancedStructuralElements) {
}
TEST_F(FormatTest, EscapedNewlines) {
- EXPECT_EQ(
- "#define A \\\n int i; \\\n int j;",
- format("#define A \\\nint i;\\\n int j;", getLLVMStyleWithColumns(11)));
+ FormatStyle Narrow = getLLVMStyleWithColumns(11);
+ EXPECT_EQ("#define A \\\n int i; \\\n int j;",
+ format("#define A \\\nint i;\\\n int j;", Narrow));
EXPECT_EQ("#define A\n\nint i;", format("#define A \\\n\n int i;"));
EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();"));
EXPECT_EQ("/* \\ \\ \\\n */", format("\\\n/* \\ \\ \\\n */"));
EXPECT_EQ("<a\n\\\\\n>", format("<a\n\\\\\n>"));
+
+ FormatStyle AlignLeft = getLLVMStyle();
+ AlignLeft.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+ EXPECT_EQ("#define MACRO(x) \\\n"
+ "private: \\\n"
+ " int x(int a);\n",
+ format("#define MACRO(x) \\\n"
+ "private: \\\n"
+ " int x(int a);\n",
+ AlignLeft));
+
+ // CRLF line endings
+ EXPECT_EQ("#define A \\\r\n int i; \\\r\n int j;",
+ format("#define A \\\r\nint i;\\\r\n int j;", Narrow));
+ EXPECT_EQ("#define A\r\n\r\nint i;", format("#define A \\\r\n\r\n int i;"));
+ EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();"));
+ EXPECT_EQ("/* \\ \\ \\\r\n */", format("\\\r\n/* \\ \\ \\\r\n */"));
+ EXPECT_EQ("<a\r\n\\\\\r\n>", format("<a\r\n\\\\\r\n>"));
+ EXPECT_EQ("#define MACRO(x) \\\r\n"
+ "private: \\\r\n"
+ " int x(int a);\r\n",
+ format("#define MACRO(x) \\\r\n"
+ "private: \\\r\n"
+ " int x(int a);\r\n",
+ AlignLeft));
+
+ FormatStyle DontAlign = getLLVMStyle();
+ DontAlign.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+ DontAlign.MaxEmptyLinesToKeep = 3;
+ // FIXME: can't use verifyFormat here because the newline before
+ // "public:" is not inserted the first time it's reformatted
+ EXPECT_EQ("#define A \\\n"
+ " class Foo { \\\n"
+ " void bar(); \\\n"
+ "\\\n"
+ "\\\n"
+ "\\\n"
+ " public: \\\n"
+ " void baz(); \\\n"
+ " };",
+ format("#define A \\\n"
+ " class Foo { \\\n"
+ " void bar(); \\\n"
+ "\\\n"
+ "\\\n"
+ "\\\n"
+ " public: \\\n"
+ " void baz(); \\\n"
+ " };",
+ DontAlign));
}
TEST_F(FormatTest, CalculateSpaceOnConsecutiveLinesInMacro) {
@@ -2105,7 +2782,7 @@ TEST_F(FormatTest, LayoutStatementsAroundPreprocessorDirectives) {
verifyIncompleteFormat("void f(\n"
"#if A\n"
- " );\n"
+ ");\n"
"#else\n"
"#endif");
}
@@ -2369,6 +3046,9 @@ TEST_F(FormatTest, LineBreakingInBinaryExpressions) {
verifyFormat("if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
" bbbbbbbbbbbbbbbbbb) && // aaaaaaaaaaaaaaaa\n"
" cccccc) {\n}");
+ verifyFormat("if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
+ " bbbbbbbbbbbbbbbbbb) && // aaaaaaaaaaa\n"
+ " cccccc) {\n}");
verifyFormat("b = a &&\n"
" // Comment\n"
" b.c && d;");
@@ -2590,6 +3270,60 @@ TEST_F(FormatTest, BreakingBeforeNonAssigmentOperators) {
Style);
}
+TEST_F(FormatTest, AllowBinPackingInsideArguments) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
+ Style.BinPackArguments = false;
+ Style.ColumnLimit = 40;
+ verifyFormat("void test() {\n"
+ " someFunction(\n"
+ " this + argument + is + quite\n"
+ " + long + so + it + gets + wrapped\n"
+ " + but + remains + bin - packed);\n"
+ "}",
+ Style);
+ verifyFormat("void test() {\n"
+ " someFunction(arg1,\n"
+ " this + argument + is\n"
+ " + quite + long + so\n"
+ " + it + gets + wrapped\n"
+ " + but + remains + bin\n"
+ " - packed,\n"
+ " arg3);\n"
+ "}",
+ Style);
+ verifyFormat("void test() {\n"
+ " someFunction(\n"
+ " arg1,\n"
+ " this + argument + has\n"
+ " + anotherFunc(nested,\n"
+ " calls + whose\n"
+ " + arguments\n"
+ " + are + also\n"
+ " + wrapped,\n"
+ " in + addition)\n"
+ " + to + being + bin - packed,\n"
+ " arg3);\n"
+ "}",
+ Style);
+
+ Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
+ verifyFormat("void test() {\n"
+ " someFunction(\n"
+ " arg1,\n"
+ " this + argument + has +\n"
+ " anotherFunc(nested,\n"
+ " calls + whose +\n"
+ " arguments +\n"
+ " are + also +\n"
+ " wrapped,\n"
+ " in + addition) +\n"
+ " to + being + bin - packed,\n"
+ " arg3);\n"
+ "}",
+ Style);
+}
+
TEST_F(FormatTest, ConstructorInitializers) {
verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}");
verifyFormat("Constructor() : Inttializer(FitsOnTheLine) {}",
@@ -2699,6 +3433,169 @@ TEST_F(FormatTest, ConstructorInitializers) {
" aaaa(aaaa) {}"));
}
+TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon;
+
+ verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}");
+ verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}",
+ getStyleWithColumns(Style, 45));
+ verifyFormat("Constructor() :\n"
+ " Initializer(FitsOnTheLine) {}",
+ getStyleWithColumns(Style, 44));
+ verifyFormat("Constructor() :\n"
+ " Initializer(FitsOnTheLine) {}",
+ getStyleWithColumns(Style, 43));
+
+ verifyFormat("template <typename T>\n"
+ "Constructor() : Initializer(FitsOnTheLine) {}",
+ getStyleWithColumns(Style, 50));
+
+ verifyFormat(
+ "SomeClass::Constructor() :\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}",
+ Style);
+
+ verifyFormat(
+ "SomeClass::Constructor() :\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}",
+ Style);
+ verifyFormat(
+ "SomeClass::Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n"
+ " aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}",
+ Style);
+ verifyFormat("Constructor(aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) :\n"
+ " aaaaaaaaaa(aaaaaa) {}",
+ Style);
+
+ verifyFormat("Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n"
+ " aaaaaaaaaaaaaaaaaaaaaaa() {}",
+ Style);
+
+ verifyFormat("Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}",
+ Style);
+
+ verifyFormat("Constructor(int Parameter = 0) :\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa),\n"
+ " aaaaaaaaaaaa(aaaaaaaaaaaaaaaaa) {}",
+ Style);
+ verifyFormat("Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbbbbb(b) {\n"
+ "}",
+ getStyleWithColumns(Style, 60));
+ verifyFormat("Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaa(aaaa, aaaa)) {}",
+ Style);
+
+ // Here a line could be saved by splitting the second initializer onto two
+ // lines, but that is not desirable.
+ verifyFormat("Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaa),\n"
+ " aaaaaaaaaaa(aaaaaaaaaaa),\n"
+ " aaaaaaaaaaaaaaaaaaaaat(aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}",
+ Style);
+
+ FormatStyle OnePerLine = Style;
+ OnePerLine.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
+ OnePerLine.AllowAllParametersOfDeclarationOnNextLine = false;
+ verifyFormat("SomeClass::Constructor() :\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}",
+ OnePerLine);
+ verifyFormat("SomeClass::Constructor() :\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), // Some comment\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}",
+ OnePerLine);
+ verifyFormat("MyClass::MyClass(int var) :\n"
+ " some_var_(var), // 4 space indent\n"
+ " some_other_var_(var + 1) { // lined up\n"
+ "}",
+ OnePerLine);
+ verifyFormat("Constructor() :\n"
+ " aaaaa(aaaaaa),\n"
+ " aaaaa(aaaaaa),\n"
+ " aaaaa(aaaaaa),\n"
+ " aaaaa(aaaaaa),\n"
+ " aaaaa(aaaaaa) {}",
+ OnePerLine);
+ verifyFormat("Constructor() :\n"
+ " aaaaa(aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaaaaaaaa) {}",
+ OnePerLine);
+ OnePerLine.BinPackParameters = false;
+ verifyFormat(
+ "Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaa(\n"
+ " aaaaaaaaaaa().aaa(),\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}",
+ OnePerLine);
+ OnePerLine.ColumnLimit = 60;
+ verifyFormat("Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaaaa(a),\n"
+ " bbbbbbbbbbbbbbbbbbbbbbbb(b) {}",
+ OnePerLine);
+
+ EXPECT_EQ("Constructor() :\n"
+ " // Comment forcing unwanted break.\n"
+ " aaaa(aaaa) {}",
+ format("Constructor() :\n"
+ " // Comment forcing unwanted break.\n"
+ " aaaa(aaaa) {}",
+ Style));
+
+ Style.ColumnLimit = 0;
+ verifyFormat("SomeClass::Constructor() :\n"
+ " a(a) {}",
+ Style);
+ verifyFormat("SomeClass::Constructor() noexcept :\n"
+ " a(a) {}",
+ Style);
+ verifyFormat("SomeClass::Constructor() :\n"
+ " a(a), b(b), c(c) {}",
+ Style);
+ verifyFormat("SomeClass::Constructor() :\n"
+ " a(a) {\n"
+ " foo();\n"
+ " bar();\n"
+ "}",
+ Style);
+
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ verifyFormat("SomeClass::Constructor() :\n"
+ " a(a), b(b), c(c) {\n"
+ "}",
+ Style);
+ verifyFormat("SomeClass::Constructor() :\n"
+ " a(a) {\n"
+ "}",
+ Style);
+
+ Style.ColumnLimit = 80;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.ConstructorInitializerIndentWidth = 2;
+ verifyFormat("SomeClass::Constructor() : a(a), b(b), c(c) {}",
+ Style);
+ verifyFormat("SomeClass::Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {}",
+ Style);
+}
+
+#ifndef EXPENSIVE_CHECKS
+// Expensive checks enables libstdc++ checking which includes validating the
+// state of ranges used in std::priority_queue - this blows out the
+// runtime/scalability of the function and makes this test unacceptably slow.
TEST_F(FormatTest, MemoizationTests) {
// This breaks if the memoization lookup does not take \c Indent and
// \c LastSpace into account.
@@ -2777,6 +3674,7 @@ TEST_F(FormatTest, MemoizationTests) {
input += " a) {}";
verifyFormat(input, OnePerLine);
}
+#endif
TEST_F(FormatTest, BreaksAsHighAsPossible) {
verifyFormat(
@@ -3402,6 +4300,18 @@ TEST_F(FormatTest, BreaksAfterAssignments) {
" 1;");
}
+TEST_F(FormatTest, ConfigurableBreakAssignmentPenalty) {
+ FormatStyle Style = getLLVMStyle();
+ verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
+ " bbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccccccc;",
+ Style);
+
+ Style.PenaltyBreakAssignment = 20;
+ verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbb +\n"
+ " cccccccccccccccccccccccccc;",
+ Style);
+}
+
TEST_F(FormatTest, AlignsAfterAssignments) {
verifyFormat(
"int Result = aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n"
@@ -4090,9 +5000,9 @@ TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) {
"c\";",
Break));
- // Exempt ObjC strings for now.
- EXPECT_EQ("NSString *const kString = @\"aaaa\"\n"
- " @\"bbbb\";",
+ EXPECT_EQ("NSString *const kString =\n"
+ " @\"aaaa\"\n"
+ " @\"bbbb\";",
format("NSString *const kString = @\"aaaa\"\n"
"@\"bbbb\";",
Break));
@@ -4132,6 +5042,9 @@ TEST_F(FormatTest, AlignsPipes) {
verifyFormat(
"llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+ verifyFormat(
+ "auto Diag = diag() << aaaaaaaaaaaaaaaa(aaaaaaaaaaaa, aaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaa);");
verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \"\n"
" << aaaaaaaa.aaaaaaaaaaaa(aaa)->aaaaaaaaaaaaaa();");
@@ -4417,7 +5330,7 @@ TEST_F(FormatTest, WrapsTemplateDeclarations) {
EXPECT_EQ("static_cast<A< //\n"
" B> *>(\n"
"\n"
- " );",
+ ");",
format("static_cast<A<//\n"
" B>*>(\n"
"\n"
@@ -4728,7 +5641,8 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
verifyFormat("SomeType MemberFunction(const Deleted &) && {}");
verifyFormat("SomeType MemberFunction(const Deleted &) && final {}");
verifyFormat("SomeType MemberFunction(const Deleted &) && override {}");
- verifyFormat("SomeType MemberFunction(const Deleted &) const &;");
+ verifyFormat("void Fn(T const &) const &;");
+ verifyFormat("void Fn(T const volatile &&) const volatile &&;");
verifyFormat("template <typename T>\n"
"void F(T) && = delete;",
getGoogleStyle());
@@ -4745,7 +5659,8 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
verifyFormat("auto Function(T... t) & -> void {}", AlignLeft);
verifyFormat("auto Function(T) & -> void {}", AlignLeft);
verifyFormat("auto Function(T) & -> void;", AlignLeft);
- verifyFormat("SomeType MemberFunction(const Deleted&) const &;", AlignLeft);
+ verifyFormat("void Fn(T const&) const&;", AlignLeft);
+ verifyFormat("void Fn(T const volatile&&) const volatile&&;", AlignLeft);
FormatStyle Spaces = getLLVMStyle();
Spaces.SpacesInCStyleCastParentheses = true;
@@ -4890,6 +5805,11 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("x = *a(x) = *a(y);", Left);
verifyFormat("for (;; *a = b) {\n}", Left);
verifyFormat("return *this += 1;", Left);
+ verifyFormat("throw *x;", Left);
+ verifyFormat("delete *x;", Left);
+ verifyFormat("typedef typeof(int(int, int))* MyFuncPtr;", Left);
+ verifyFormat("[](const decltype(*a)* ptr) {}", Left);
+ verifyFormat("typedef typeof /*comment*/ (int(int, int))* MyFuncPtr;", Left);
verifyIndependentOfContext("a = *(x + y);");
verifyIndependentOfContext("a = &(x + y);");
@@ -4936,9 +5856,6 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyGoogleFormat("T** t = new T*;");
verifyGoogleFormat("T** t = new T*();");
- FormatStyle PointerLeft = getLLVMStyle();
- PointerLeft.PointerAlignment = FormatStyle::PAS_Left;
- verifyFormat("delete *x;", PointerLeft);
verifyFormat("STATIC_ASSERT((a & b) == 0);");
verifyFormat("STATIC_ASSERT(0 == (a & b));");
verifyFormat("template <bool a, bool b> "
@@ -5217,6 +6134,12 @@ TEST_F(FormatTest, FormatsFunctionTypes) {
verifyFormat("void f() { function(*some_pointer_var)[0] = 10; }");
verifyFormat("int x = f(&h)();");
verifyFormat("returnsFunction(&param1, &param2)(param);");
+ verifyFormat("std::function<\n"
+ " LooooooooooongTemplatedType<\n"
+ " SomeType>*(\n"
+ " LooooooooooooooooongType type)>\n"
+ " function;",
+ getGoogleStyleWithColumns(40));
}
TEST_F(FormatTest, FormatsPointersToArrayTypes) {
@@ -5571,7 +6494,10 @@ TEST_F(FormatTest, LayoutBraceInitializersInReturnStatement) {
TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
verifyFormat("vector<int> x{1, 2, 3, 4};");
verifyFormat("vector<int> x{\n"
- " 1, 2, 3, 4,\n"
+ " 1,\n"
+ " 2,\n"
+ " 3,\n"
+ " 4,\n"
"};");
verifyFormat("vector<T> x{{}, {}, {}, {}};");
verifyFormat("f({1, 2});");
@@ -5590,6 +6516,8 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
" T member = {arg1, arg2};\n"
"};");
verifyFormat("vector<int> foo = {::SomeGlobalFunction()};");
+ verifyFormat("const struct A a = {.a = 1, .b = 2};");
+ verifyFormat("const struct A a = {[0] = 1, [1] = 2};");
verifyFormat("static_assert(std::is_integral<int>{} + 0, \"\");");
verifyFormat("int a = std::is_integral<int>{} + 0;");
@@ -5614,6 +6542,17 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
"};");
verifyFormat("#define A {a, a},");
+ // Binpacking only if there is no trailing comma
+ verifyFormat("const Aaaaaa aaaaa = {aaaaaaaaaa, bbbbbbbbbb,\n"
+ " cccccccccc, dddddddddd};",
+ getLLVMStyleWithColumns(50));
+ verifyFormat("const Aaaaaa aaaaa = {\n"
+ " aaaaaaaaaaa,\n"
+ " bbbbbbbbbbb,\n"
+ " ccccccccccc,\n"
+ " ddddddddddd,\n"
+ "};", getLLVMStyleWithColumns(50));
+
// Cases where distinguising braced lists and blocks is hard.
verifyFormat("vector<int> v{12} GUARDED_BY(mutex);");
verifyFormat("void f() {\n"
@@ -5693,10 +6632,12 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
" // Second element:\n"
" 2};",
getLLVMStyleWithColumns(30)));
- // A trailing comma should still lead to an enforced line break.
+ // A trailing comma should still lead to an enforced line break and no
+ // binpacking.
EXPECT_EQ("vector<int> SomeVector = {\n"
" // aaa\n"
- " 1, 2,\n"
+ " 1,\n"
+ " 2,\n"
"};",
format("vector<int> SomeVector = { // aaa\n"
" 1, 2, };"));
@@ -5755,6 +6696,8 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
" aaaaaaa,\n"
" a};");
verifyFormat("vector<int> foo = { ::SomeGlobalFunction() };", ExtraSpaces);
+ verifyFormat("const struct A a = { .a = 1, .b = 2 };", ExtraSpaces);
+ verifyFormat("const struct A a = { [0] = 1, [1] = 2 };", ExtraSpaces);
}
TEST_F(FormatTest, FormatsBracedListsInColumnLayout) {
@@ -5860,7 +6803,7 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) {
" aaaaaaaaaaaa, a, aaaaaaaaaa, aaaaaaaaa, aaa}};");
// No column layout should be used here.
- verifyFormat("aaaaaaaaaaaaaaa = {aaaaaaaaaaaaaaaaaaaaaaaaaaa, 0, 0,\n"
+ verifyFormat("aaaaaaaaaaaaaaa = {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0, 0,\n"
" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb};");
verifyNoCrash("a<,");
@@ -6003,6 +6946,35 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
getLLVMStyleWithColumns(23));
}
+TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) {
+ FormatStyle MergeEmptyOnly = getLLVMStyle();
+ MergeEmptyOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ MergeEmptyOnly);
+ verifyFormat("class C {\n"
+ " int f() {\n"
+ " return 42;\n"
+ " }\n"
+ "};",
+ MergeEmptyOnly);
+ verifyFormat("int f() {}", MergeEmptyOnly);
+ verifyFormat("int f() {\n"
+ " return 42;\n"
+ "}",
+ MergeEmptyOnly);
+
+ // Also verify behavior when BraceWrapping.AfterFunction = true
+ MergeEmptyOnly.BreakBeforeBraces = FormatStyle::BS_Custom;
+ MergeEmptyOnly.BraceWrapping.AfterFunction = true;
+ verifyFormat("int f() {}", MergeEmptyOnly);
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ MergeEmptyOnly);
+}
+
TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
FormatStyle MergeInlineOnly = getLLVMStyle();
MergeInlineOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
@@ -6014,6 +6986,329 @@ TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
" return 42;\n"
"}",
MergeInlineOnly);
+
+ // SFS_Inline implies SFS_Empty
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("int f() {}", MergeInlineOnly);
+
+ // Also verify behavior when BraceWrapping.AfterFunction = true
+ MergeInlineOnly.BreakBeforeBraces = FormatStyle::BS_Custom;
+ MergeInlineOnly.BraceWrapping.AfterFunction = true;
+ verifyFormat("class C {\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("int f()\n"
+ "{\n"
+ " return 42;\n"
+ "}",
+ MergeInlineOnly);
+
+ // SFS_Inline implies SFS_Empty
+ verifyFormat("int f() {}", MergeInlineOnly);
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ MergeInlineOnly);
+}
+
+TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
+ FormatStyle MergeInlineOnly = getLLVMStyle();
+ MergeInlineOnly.AllowShortFunctionsOnASingleLine =
+ FormatStyle::SFS_InlineOnly;
+ verifyFormat("class C {\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("int f() {\n"
+ " return 42;\n"
+ "}",
+ MergeInlineOnly);
+
+ // SFS_InlineOnly does not imply SFS_Empty
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("int f() {\n"
+ "}",
+ MergeInlineOnly);
+
+ // Also verify behavior when BraceWrapping.AfterFunction = true
+ MergeInlineOnly.BreakBeforeBraces = FormatStyle::BS_Custom;
+ MergeInlineOnly.BraceWrapping.AfterFunction = true;
+ verifyFormat("class C {\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("int f()\n"
+ "{\n"
+ " return 42;\n"
+ "}",
+ MergeInlineOnly);
+
+ // SFS_InlineOnly does not imply SFS_Empty
+ verifyFormat("int f()\n"
+ "{\n"
+ "}",
+ MergeInlineOnly);
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ MergeInlineOnly);
+}
+
+TEST_F(FormatTest, SplitEmptyFunction) {
+ FormatStyle Style = getLLVMStyle();
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterFunction = true;
+ Style.BraceWrapping.SplitEmptyFunction = false;
+ Style.ColumnLimit = 40;
+
+ verifyFormat("int f()\n"
+ "{}",
+ Style);
+ verifyFormat("int f()\n"
+ "{\n"
+ " return 42;\n"
+ "}",
+ Style);
+ verifyFormat("int f()\n"
+ "{\n"
+ " // some comment\n"
+ "}",
+ Style);
+
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ verifyFormat("int f() {}", Style);
+ verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
+ "{}",
+ Style);
+ verifyFormat("int f()\n"
+ "{\n"
+ " return 0;\n"
+ "}",
+ Style);
+
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ verifyFormat("class Foo {\n"
+ " int f() {}\n"
+ "};\n",
+ Style);
+ verifyFormat("class Foo {\n"
+ " int f() { return 0; }\n"
+ "};\n",
+ Style);
+ verifyFormat("class Foo {\n"
+ " int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
+ " {}\n"
+ "};\n",
+ Style);
+ verifyFormat("class Foo {\n"
+ " int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
+ " {\n"
+ " return 0;\n"
+ " }\n"
+ "};\n",
+ Style);
+
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ verifyFormat("int f() {}", Style);
+ verifyFormat("int f() { return 0; }", Style);
+ verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
+ "{}",
+ Style);
+ verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
+ "{\n"
+ " return 0;\n"
+ "}",
+ Style);
+}
+TEST_F(FormatTest, KeepShortFunctionAfterPPElse) {
+ FormatStyle Style = getLLVMStyle();
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ verifyFormat("#ifdef A\n"
+ "int f() {}\n"
+ "#else\n"
+ "int g() {}\n"
+ "#endif",
+ Style);
+}
+
+TEST_F(FormatTest, SplitEmptyClass) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterClass = true;
+ Style.BraceWrapping.SplitEmptyRecord = false;
+
+ verifyFormat("class Foo\n"
+ "{};",
+ Style);
+ verifyFormat("/* something */ class Foo\n"
+ "{};",
+ Style);
+ verifyFormat("template <typename X> class Foo\n"
+ "{};",
+ Style);
+ verifyFormat("class Foo\n"
+ "{\n"
+ " Foo();\n"
+ "};",
+ Style);
+ verifyFormat("typedef class Foo\n"
+ "{\n"
+ "} Foo_t;",
+ Style);
+}
+
+TEST_F(FormatTest, SplitEmptyStruct) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterStruct = true;
+ Style.BraceWrapping.SplitEmptyRecord = false;
+
+ verifyFormat("struct Foo\n"
+ "{};",
+ Style);
+ verifyFormat("/* something */ struct Foo\n"
+ "{};",
+ Style);
+ verifyFormat("template <typename X> struct Foo\n"
+ "{};",
+ Style);
+ verifyFormat("struct Foo\n"
+ "{\n"
+ " Foo();\n"
+ "};",
+ Style);
+ verifyFormat("typedef struct Foo\n"
+ "{\n"
+ "} Foo_t;",
+ Style);
+ //typedef struct Bar {} Bar_t;
+}
+
+TEST_F(FormatTest, SplitEmptyUnion) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterUnion = true;
+ Style.BraceWrapping.SplitEmptyRecord = false;
+
+ verifyFormat("union Foo\n"
+ "{};",
+ Style);
+ verifyFormat("/* something */ union Foo\n"
+ "{};",
+ Style);
+ verifyFormat("union Foo\n"
+ "{\n"
+ " A,\n"
+ "};",
+ Style);
+ verifyFormat("typedef union Foo\n"
+ "{\n"
+ "} Foo_t;",
+ Style);
+}
+
+TEST_F(FormatTest, SplitEmptyNamespace) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterNamespace = true;
+ Style.BraceWrapping.SplitEmptyNamespace = false;
+
+ verifyFormat("namespace Foo\n"
+ "{};",
+ Style);
+ verifyFormat("/* something */ namespace Foo\n"
+ "{};",
+ Style);
+ verifyFormat("inline namespace Foo\n"
+ "{};",
+ Style);
+ verifyFormat("namespace Foo\n"
+ "{\n"
+ "void Bar();\n"
+ "};",
+ Style);
+}
+
+TEST_F(FormatTest, NeverMergeShortRecords) {
+ FormatStyle Style = getLLVMStyle();
+
+ verifyFormat("class Foo {\n"
+ " Foo();\n"
+ "};",
+ Style);
+ verifyFormat("typedef class Foo {\n"
+ " Foo();\n"
+ "} Foo_t;",
+ Style);
+ verifyFormat("struct Foo {\n"
+ " Foo();\n"
+ "};",
+ Style);
+ verifyFormat("typedef struct Foo {\n"
+ " Foo();\n"
+ "} Foo_t;",
+ Style);
+ verifyFormat("union Foo {\n"
+ " A,\n"
+ "};",
+ Style);
+ verifyFormat("typedef union Foo {\n"
+ " A,\n"
+ "} Foo_t;",
+ Style);
+ verifyFormat("namespace Foo {\n"
+ "void Bar();\n"
+ "};",
+ Style);
+
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterClass = true;
+ Style.BraceWrapping.AfterStruct = true;
+ Style.BraceWrapping.AfterUnion = true;
+ Style.BraceWrapping.AfterNamespace = true;
+ verifyFormat("class Foo\n"
+ "{\n"
+ " Foo();\n"
+ "};",
+ Style);
+ verifyFormat("typedef class Foo\n"
+ "{\n"
+ " Foo();\n"
+ "} Foo_t;",
+ Style);
+ verifyFormat("struct Foo\n"
+ "{\n"
+ " Foo();\n"
+ "};",
+ Style);
+ verifyFormat("typedef struct Foo\n"
+ "{\n"
+ " Foo();\n"
+ "} Foo_t;",
+ Style);
+ verifyFormat("union Foo\n"
+ "{\n"
+ " A,\n"
+ "};",
+ Style);
+ verifyFormat("typedef union Foo\n"
+ "{\n"
+ " A,\n"
+ "} Foo_t;",
+ Style);
+ verifyFormat("namespace Foo\n"
+ "{\n"
+ "void Bar();\n"
+ "};",
+ Style);
}
TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) {
@@ -6132,6 +7427,10 @@ TEST_F(FormatTest, MergeHandlingInTheFaceOfPreprocessorDirectives) {
" if (true) continue;\n"
"}",
ShortMergedIf);
+ ShortMergedIf.ColumnLimit = 33;
+ verifyFormat("#define A \\\n"
+ " if constexpr (true) return 42;",
+ ShortMergedIf);
ShortMergedIf.ColumnLimit = 29;
verifyFormat("#define A \\\n"
" if (aaaaaaaaaa) return 1; \\\n"
@@ -6143,6 +7442,11 @@ TEST_F(FormatTest, MergeHandlingInTheFaceOfPreprocessorDirectives) {
" return 1; \\\n"
" return 2;",
ShortMergedIf);
+ verifyFormat("#define A \\\n"
+ " if constexpr (aaaaaaa) \\\n"
+ " return 1; \\\n"
+ " return 2;",
+ ShortMergedIf);
}
TEST_F(FormatTest, FormatStarDependingOnContext) {
@@ -6186,7 +7490,7 @@ TEST_F(FormatTest, SkipsDeeplyNestedLines) {
// Deeply nested part is untouched, rest is formatted.
EXPECT_EQ(std::string("int i;\n") + Code + "int j;\n",
format(std::string("int i;\n") + Code + "int j;\n",
- getLLVMStyle(), IC_ExpectIncomplete));
+ getLLVMStyle(), SC_ExpectIncomplete));
}
//===----------------------------------------------------------------------===//
@@ -6413,7 +7717,7 @@ TEST_F(FormatTest, BreaksStringLiterals) {
EXPECT_EQ("\"some text other\";", format("\"some text other\";", Style));
FormatStyle AlignLeft = getLLVMStyleWithColumns(12);
- AlignLeft.AlignEscapedNewlinesLeft = true;
+ AlignLeft.AlignEscapedNewlines = FormatStyle::ENAS_Left;
EXPECT_EQ("#define A \\\n"
" \"some \" \\\n"
" \"text \" \\\n"
@@ -6457,6 +7761,7 @@ TEST_F(FormatTest, BreaksWideAndNSStringLiterals) {
EXPECT_EQ("@\"NSString \"\n"
"@\"literal\";",
format("@\"NSString literal\";", getGoogleStyleWithColumns(19)));
+ verifyFormat(R"(NSString *s = @"那那那那";)", getLLVMStyleWithColumns(26));
// This input makes clang-format try to split the incomplete unicode escape
// sequence, which used to lead to a crasher.
@@ -6502,7 +7807,7 @@ TEST_F(FormatTest, BreaksStringLiteralsWithin_TMacro) {
"#if !TEST\n"
" _T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n"
"#endif\n"
- " );",
+ ");",
format("f(\n"
"#if !TEST\n"
"_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n"
@@ -6813,7 +8118,7 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
FormatStyle Tab = getLLVMStyleWithColumns(42);
Tab.IndentWidth = 8;
Tab.UseTab = FormatStyle::UT_Always;
- Tab.AlignEscapedNewlinesLeft = true;
+ Tab.AlignEscapedNewlines = FormatStyle::ENAS_Left;
EXPECT_EQ("if (aaaaaaaa && // q\n"
" bb)\t\t// w\n"
@@ -7594,14 +8899,21 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
"int oneTwoThree = 123;\n"
"int oneTwo = 12;",
Alignment));
- Alignment.AlignEscapedNewlinesLeft = true;
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+ verifyFormat("#define A \\\n"
+ " int aaaa = 12; \\\n"
+ " int b = 23; \\\n"
+ " int ccc = 234; \\\n"
+ " int dddddddddd = 2345;",
+ Alignment);
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left;
verifyFormat("#define A \\\n"
" int aaaa = 12; \\\n"
" int b = 23; \\\n"
" int ccc = 234; \\\n"
" int dddddddddd = 2345;",
Alignment);
- Alignment.AlignEscapedNewlinesLeft = false;
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right;
verifyFormat("#define A "
" \\\n"
" int aaaa = 12; "
@@ -7669,12 +8981,11 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
"};",
Alignment);
- // FIXME: Should align all three assignments
verifyFormat(
"int i = 1;\n"
"SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n"
" loooooooooooooooooooooongParameterB);\n"
- "int j = 2;",
+ "int j = 2;",
Alignment);
verifyFormat("template <typename T, typename T_0 = very_long_type_name_0,\n"
@@ -7689,6 +9000,13 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n"
"float b[1][] = {{3.f}};\n",
Alignment);
+ verifyFormat("for (int i = 0; i < 1; i++)\n"
+ " int x = 1;\n",
+ Alignment);
+ verifyFormat("for (i = 0; i < 1; i++)\n"
+ " x = 1;\n"
+ "y = 1;\n",
+ Alignment);
}
TEST_F(FormatTest, AlignConsecutiveDeclarations) {
@@ -7756,7 +9074,57 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
"unsigned oneTwoThree = 123;\n"
"int oneTwo = 12;",
Alignment));
+ // Function prototype alignment
+ verifyFormat("int a();\n"
+ "double b();",
+ Alignment);
+ verifyFormat("int a(int x);\n"
+ "double b();",
+ Alignment);
+ unsigned OldColumnLimit = Alignment.ColumnLimit;
+ // We need to set ColumnLimit to zero, in order to stress nested alignments,
+ // otherwise the function parameters will be re-flowed onto a single line.
+ Alignment.ColumnLimit = 0;
+ EXPECT_EQ("int a(int x,\n"
+ " float y);\n"
+ "double b(int x,\n"
+ " double y);",
+ format("int a(int x,\n"
+ " float y);\n"
+ "double b(int x,\n"
+ " double y);",
+ Alignment));
+ // This ensures that function parameters of function declarations are
+ // correctly indented when their owning functions are indented.
+ // The failure case here is for 'double y' to not be indented enough.
+ EXPECT_EQ("double a(int x);\n"
+ "int b(int y,\n"
+ " double z);",
+ format("double a(int x);\n"
+ "int b(int y,\n"
+ " double z);",
+ Alignment));
+ // Set ColumnLimit low so that we induce wrapping immediately after
+ // the function name and opening paren.
+ Alignment.ColumnLimit = 13;
+ verifyFormat("int function(\n"
+ " int x,\n"
+ " bool y);",
+ Alignment);
+ Alignment.ColumnLimit = OldColumnLimit;
+ // Ensure function pointers don't screw up recursive alignment
+ verifyFormat("int a(int x, void (*fp)(int y));\n"
+ "double b();",
+ Alignment);
Alignment.AlignConsecutiveAssignments = true;
+ // Ensure recursive alignment is broken by function braces, so that the
+ // "a = 1" does not align with subsequent assignments inside the function
+ // body.
+ verifyFormat("int func(int a = 1) {\n"
+ " int b = 2;\n"
+ " int cc = 3;\n"
+ "}",
+ Alignment);
verifyFormat("float something = 2000;\n"
"double another = 911;\n"
"int i = 1, j = 10;\n"
@@ -7766,6 +9134,28 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
verifyFormat("int oneTwoThree = {0}; // comment\n"
"unsigned oneTwo = 0; // comment",
Alignment);
+ // Make sure that scope is correctly tracked, in the absence of braces
+ verifyFormat("for (int i = 0; i < n; i++)\n"
+ " j = i;\n"
+ "double x = 1;\n",
+ Alignment);
+ verifyFormat("if (int i = 0)\n"
+ " j = i;\n"
+ "double x = 1;\n",
+ Alignment);
+ // Ensure operator[] and operator() are comprehended
+ verifyFormat("struct test {\n"
+ " long long int foo();\n"
+ " int operator[](int a);\n"
+ " double bar();\n"
+ "};\n",
+ Alignment);
+ verifyFormat("struct test {\n"
+ " long long int foo();\n"
+ " int operator()(int a);\n"
+ " double bar();\n"
+ "};\n",
+ Alignment);
EXPECT_EQ("void SomeFunction(int parameter = 0) {\n"
" int const i = 1;\n"
" int * j = 2;\n"
@@ -7790,14 +9180,21 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
"}",
Alignment));
Alignment.AlignConsecutiveAssignments = false;
- Alignment.AlignEscapedNewlinesLeft = true;
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+ verifyFormat("#define A \\\n"
+ " int aaaa = 12; \\\n"
+ " float b = 23; \\\n"
+ " const int ccc = 234; \\\n"
+ " unsigned dddddddddd = 2345;",
+ Alignment);
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left;
verifyFormat("#define A \\\n"
" int aaaa = 12; \\\n"
" float b = 23; \\\n"
" const int ccc = 234; \\\n"
" unsigned dddddddddd = 2345;",
Alignment);
- Alignment.AlignEscapedNewlinesLeft = false;
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right;
Alignment.ColumnLimit = 30;
verifyFormat("#define A \\\n"
" int aaaa = 12; \\\n"
@@ -7867,17 +9264,16 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
Alignment);
Alignment.AlignConsecutiveAssignments = false;
- // FIXME: Should align all three declarations
verifyFormat(
"int i = 1;\n"
"SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n"
" loooooooooooooooooooooongParameterB);\n"
- "int j = 2;",
+ "int j = 2;",
Alignment);
// Test interactions with ColumnLimit and AlignConsecutiveAssignments:
// We expect declarations and assignments to align, as long as it doesn't
- // exceed the column limit, starting a new alignemnt sequence whenever it
+ // exceed the column limit, starting a new alignment sequence whenever it
// happens.
Alignment.AlignConsecutiveAssignments = true;
Alignment.ColumnLimit = 30;
@@ -7930,6 +9326,16 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
Alignment);
Alignment.BinPackParameters = true;
Alignment.ColumnLimit = 80;
+
+ // Bug 33507
+ Alignment.PointerAlignment = FormatStyle::PAS_Middle;
+ verifyFormat(
+ "auto found = range::find_if(vsProducts, [&](auto * aProduct) {\n"
+ " static const Version verVs2017;\n"
+ " return true;\n"
+ "});\n",
+ Alignment);
+ Alignment.PointerAlignment = FormatStyle::PAS_Right;
}
TEST_F(FormatTest, LinuxBraceBreaking) {
@@ -7953,7 +9359,7 @@ TEST_F(FormatTest, LinuxBraceBreaking) {
"struct B {\n"
" int x;\n"
"};\n"
- "}\n",
+ "} // namespace a\n",
LinuxBraceStyle);
verifyFormat("enum X {\n"
" Y = 0,\n"
@@ -8083,6 +9489,19 @@ TEST_F(FormatTest, StroustrupBraceBreaking) {
TEST_F(FormatTest, AllmanBraceBreaking) {
FormatStyle AllmanBraceStyle = getLLVMStyle();
AllmanBraceStyle.BreakBeforeBraces = FormatStyle::BS_Allman;
+
+ EXPECT_EQ("namespace a\n"
+ "{\n"
+ "void f();\n"
+ "void g();\n"
+ "} // namespace a\n",
+ format("namespace a\n"
+ "{\n"
+ "void f();\n"
+ "void g();\n"
+ "}\n",
+ AllmanBraceStyle));
+
verifyFormat("namespace a\n"
"{\n"
"class A\n"
@@ -8101,7 +9520,7 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
"{\n"
" int x;\n"
"};\n"
- "}",
+ "} // namespace a",
AllmanBraceStyle);
verifyFormat("void f()\n"
@@ -8221,7 +9640,14 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
// .. or dict literals.
verifyFormat("void f()\n"
"{\n"
- " [object someMethod:@{ @\"a\" : @\"b\" }];\n"
+ " // ...\n"
+ " [object someMethod:@{@\"a\" : @\"b\"}];\n"
+ "}",
+ AllmanBraceStyle);
+ verifyFormat("void f()\n"
+ "{\n"
+ " // ...\n"
+ " [object someMethod:@{a : @\"b\"}];\n"
"}",
AllmanBraceStyle);
verifyFormat("int f()\n"
@@ -8253,11 +9679,24 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
BreakBeforeBraceShortIfs);
verifyFormat("void f(bool b)\n"
"{\n"
+ " if constexpr (b)\n"
+ " {\n"
+ " return;\n"
+ " }\n"
+ "}\n",
+ BreakBeforeBraceShortIfs);
+ verifyFormat("void f(bool b)\n"
+ "{\n"
" if (b) return;\n"
"}\n",
BreakBeforeBraceShortIfs);
verifyFormat("void f(bool b)\n"
"{\n"
+ " if constexpr (b) return;\n"
+ "}\n",
+ BreakBeforeBraceShortIfs);
+ verifyFormat("void f(bool b)\n"
+ "{\n"
" while (b)\n"
" {\n"
" return;\n"
@@ -8287,7 +9726,7 @@ TEST_F(FormatTest, GNUBraceBreaking) {
" }\n"
" void g() { return; }\n"
"}\n"
- "}",
+ "} // namespace a",
GNUBraceStyle);
verifyFormat("void f()\n"
@@ -8576,7 +10015,6 @@ TEST_F(FormatTest, GetsCorrectBasedOnStyle) {
TEST_F(FormatTest, ParsesConfigurationBools) {
FormatStyle Style = {};
Style.Language = FormatStyle::LK_Cpp;
- CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft);
CHECK_PARSE_BOOL(AlignOperands);
CHECK_PARSE_BOOL(AlignTrailingComments);
CHECK_PARSE_BOOL(AlignConsecutiveAssignments);
@@ -8591,9 +10029,9 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(BinPackParameters);
CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations);
CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
- CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma);
CHECK_PARSE_BOOL(BreakStringLiterals);
CHECK_PARSE_BOOL(BreakBeforeInheritanceComma)
+ CHECK_PARSE_BOOL(CompactNamespaces);
CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine);
CHECK_PARSE_BOOL(DerivePointerAlignment);
CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding");
@@ -8606,6 +10044,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(Cpp11BracedListStyle);
CHECK_PARSE_BOOL(ReflowComments);
CHECK_PARSE_BOOL(SortIncludes);
+ CHECK_PARSE_BOOL(SortUsingDeclarations);
CHECK_PARSE_BOOL(SpacesInParentheses);
CHECK_PARSE_BOOL(SpacesInSquareBrackets);
CHECK_PARSE_BOOL(SpacesInAngles);
@@ -8624,9 +10063,13 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterObjCDeclaration);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterStruct);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterUnion);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterExternBlock);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace);
}
#undef CHECK_PARSE_BOOL
@@ -8640,6 +10083,8 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("ObjCBlockIndentWidth: 1234", ObjCBlockIndentWidth, 1234u);
CHECK_PARSE("ColumnLimit: 1234", ColumnLimit, 1234u);
CHECK_PARSE("MaxEmptyLinesToKeep: 1234", MaxEmptyLinesToKeep, 1234u);
+ CHECK_PARSE("PenaltyBreakAssignment: 1234",
+ PenaltyBreakAssignment, 1234u);
CHECK_PARSE("PenaltyBreakBeforeFirstCallParameter: 1234",
PenaltyBreakBeforeFirstCallParameter, 1234u);
CHECK_PARSE("PenaltyExcessCharacter: 1234", PenaltyExcessCharacter, 1234u);
@@ -8686,6 +10131,17 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators,
FormatStyle::BOS_All);
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
+ CHECK_PARSE("BreakConstructorInitializers: BeforeComma",
+ BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
+ CHECK_PARSE("BreakConstructorInitializers: AfterColon",
+ BreakConstructorInitializers, FormatStyle::BCIS_AfterColon);
+ CHECK_PARSE("BreakConstructorInitializers: BeforeColon",
+ BreakConstructorInitializers, FormatStyle::BCIS_BeforeColon);
+ // For backward compatibility:
+ CHECK_PARSE("BreakConstructorInitializersBeforeComma: true",
+ BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
+
Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket,
FormatStyle::BAS_Align);
@@ -8699,6 +10155,19 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket,
FormatStyle::BAS_Align);
+ Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+ CHECK_PARSE("AlignEscapedNewlines: DontAlign", AlignEscapedNewlines,
+ FormatStyle::ENAS_DontAlign);
+ CHECK_PARSE("AlignEscapedNewlines: Left", AlignEscapedNewlines,
+ FormatStyle::ENAS_Left);
+ CHECK_PARSE("AlignEscapedNewlines: Right", AlignEscapedNewlines,
+ FormatStyle::ENAS_Right);
+ // For backward compatibility:
+ CHECK_PARSE("AlignEscapedNewlinesLeft: true", AlignEscapedNewlines,
+ FormatStyle::ENAS_Left);
+ CHECK_PARSE("AlignEscapedNewlinesLeft: false", AlignEscapedNewlines,
+ FormatStyle::ENAS_Right);
+
Style.UseTab = FormatStyle::UT_ForIndentation;
CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
@@ -8811,6 +10280,20 @@ TEST_F(FormatTest, ParsesConfiguration) {
" Priority: 1",
IncludeCategories, ExpectedCategories);
CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeIsMainRegex, "abc$");
+
+ Style.RawStringFormats.clear();
+ std::vector<FormatStyle::RawStringFormat> ExpectedRawStringFormats = {
+ {"pb", FormatStyle::LK_TextProto, "llvm"},
+ {"cpp", FormatStyle::LK_Cpp, "google"}};
+
+ CHECK_PARSE("RawStringFormats:\n"
+ " - Delimiter: 'pb'\n"
+ " Language: TextProto\n"
+ " BasedOnStyle: llvm\n"
+ " - Delimiter: 'cpp'\n"
+ " Language: Cpp\n"
+ " BasedOnStyle: google",
+ RawStringFormats, ExpectedRawStringFormats);
}
TEST_F(FormatTest, ParsesConfigurationWithLanguages) {
@@ -9105,7 +10588,7 @@ TEST_F(FormatTest, ConstructorInitializerIndentWidth) {
TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
FormatStyle Style = getLLVMStyle();
- Style.BreakConstructorInitializersBeforeComma = true;
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
Style.ConstructorInitializerIndentWidth = 4;
verifyFormat("SomeClass::Constructor()\n"
" : a(a)\n"
@@ -9350,6 +10833,8 @@ TEST_F(FormatTest, FormatsLambdas) {
verifyFormat("int c = [&a, &a, a] { [=, a, b, &c] { return b++; }(); }();\n");
verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] { return b++; }(); }}\n");
verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] {}(); }}\n");
+ verifyFormat("auto c = [a = [b = 42] {}] {};\n");
+ verifyFormat("auto c = [a = &i + 10, b = [] {}] {};\n");
verifyFormat("int x = f(*+[] {});");
verifyFormat("void f() {\n"
" other(x.begin(), x.end(), [&](int, int) { return 1; });\n"
@@ -9464,7 +10949,7 @@ TEST_F(FormatTest, FormatsLambdas) {
// Other corner cases.
verifyFormat("void f() {\n"
" bar([]() {} // Did not respect SpacesBeforeTrailingComments\n"
- " );\n"
+ " );\n"
"}");
// Lambdas created through weird macros.
@@ -9478,6 +10963,11 @@ TEST_F(FormatTest, FormatsLambdas) {
" doo_dah();\n"
" })) {\n"
"}");
+ verifyFormat("if constexpr (blah_blah(whatever, whatever, [] {\n"
+ " doo_dah();\n"
+ " doo_dah();\n"
+ " })) {\n"
+ "}");
verifyFormat("auto lambda = []() {\n"
" int a = 2\n"
"#if A\n"
@@ -9974,6 +11464,10 @@ TEST_F(FormatTest, ArrayAsTemplateType) {
format("auto a = unique_ptr < Foo < Bar>[10]> ;", Spaces));
}
+TEST_F(FormatTest, NoSpaceAfterSuper) {
+ verifyFormat("__super::FooBar();");
+}
+
TEST(FormatStyle, GetStyleOfFile) {
vfs::InMemoryFileSystem FS;
// Test 1: format file in the same directory.
@@ -10111,6 +11605,98 @@ TEST_F(ReplacementTest, SortIncludesAfterReplacement) {
EXPECT_EQ(Expected, *Result);
}
+TEST_F(FormatTest, FormatSortsUsingDeclarations) {
+ EXPECT_EQ("using std::cin;\n"
+ "using std::cout;",
+ format("using std::cout;\n"
+ "using std::cin;", getGoogleStyle()));
+}
+
+TEST_F(FormatTest, UTF8CharacterLiteralCpp03) {
+ format::FormatStyle Style = format::getLLVMStyle();
+ Style.Standard = FormatStyle::LS_Cpp03;
+ // cpp03 recognize this string as identifier u8 and literal character 'a'
+ EXPECT_EQ("auto c = u8 'a';", format("auto c = u8'a';", Style));
+}
+
+TEST_F(FormatTest, UTF8CharacterLiteralCpp11) {
+ // u8'a' is a C++17 feature, utf8 literal character, LS_Cpp11 covers
+ // all modes, including C++11, C++14 and C++17
+ EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';"));
+}
+
+TEST_F(FormatTest, DoNotFormatLikelyXml) {
+ EXPECT_EQ("<!-- ;> -->",
+ format("<!-- ;> -->", getGoogleStyle()));
+ EXPECT_EQ(" <!-- >; -->",
+ format(" <!-- >; -->", getGoogleStyle()));
+}
+
+TEST_F(FormatTest, StructuredBindings) {
+ // Structured bindings is a C++17 feature.
+ // all modes, including C++11, C++14 and C++17
+ verifyFormat("auto [a, b] = f();");
+ EXPECT_EQ("auto [a, b] = f();", format("auto[a, b] = f();"));
+ EXPECT_EQ("const auto [a, b] = f();", format("const auto[a, b] = f();"));
+ EXPECT_EQ("auto const [a, b] = f();", format("auto const[a, b] = f();"));
+ EXPECT_EQ("auto const volatile [a, b] = f();",
+ format("auto const volatile[a, b] = f();"));
+ EXPECT_EQ("auto [a, b, c] = f();", format("auto [ a , b,c ] = f();"));
+ EXPECT_EQ("auto &[a, b, c] = f();",
+ format("auto &[ a , b,c ] = f();"));
+ EXPECT_EQ("auto &&[a, b, c] = f();",
+ format("auto &&[ a , b,c ] = f();"));
+ EXPECT_EQ("auto const &[a, b] = f();", format("auto const&[a, b] = f();"));
+ EXPECT_EQ("auto const volatile &&[a, b] = f();",
+ format("auto const volatile &&[a, b] = f();"));
+ EXPECT_EQ("auto const &&[a, b] = f();", format("auto const && [a, b] = f();"));
+ EXPECT_EQ("const auto &[a, b] = f();", format("const auto & [a, b] = f();"));
+ EXPECT_EQ("const auto volatile &&[a, b] = f();",
+ format("const auto volatile &&[a, b] = f();"));
+ EXPECT_EQ("volatile const auto &&[a, b] = f();",
+ format("volatile const auto &&[a, b] = f();"));
+ EXPECT_EQ("const auto &&[a, b] = f();", format("const auto && [a, b] = f();"));
+
+ // Make sure we don't mistake structured bindings for lambdas.
+ FormatStyle PointerMiddle = getLLVMStyle();
+ PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle;
+ verifyFormat("auto [a1, b]{A * i};", getGoogleStyle());
+ verifyFormat("auto [a2, b]{A * i};", getLLVMStyle());
+ verifyFormat("auto [a3, b]{A * i};", PointerMiddle);
+ verifyFormat("auto const [a1, b]{A * i};", getGoogleStyle());
+ verifyFormat("auto const [a2, b]{A * i};", getLLVMStyle());
+ verifyFormat("auto const [a3, b]{A * i};", PointerMiddle);
+ verifyFormat("auto const& [a1, b]{A * i};", getGoogleStyle());
+ verifyFormat("auto const &[a2, b]{A * i};", getLLVMStyle());
+ verifyFormat("auto const & [a3, b]{A * i};", PointerMiddle);
+ verifyFormat("auto const&& [a1, b]{A * i};", getGoogleStyle());
+ verifyFormat("auto const &&[a2, b]{A * i};", getLLVMStyle());
+ verifyFormat("auto const && [a3, b]{A * i};", PointerMiddle);
+
+ EXPECT_EQ("for (const auto &&[a, b] : some_range) {\n}",
+ format("for (const auto && [a, b] : some_range) {\n}"));
+ EXPECT_EQ("for (const auto &[a, b] : some_range) {\n}",
+ format("for (const auto & [a, b] : some_range) {\n}"));
+ EXPECT_EQ("for (const auto [a, b] : some_range) {\n}",
+ format("for (const auto[a, b] : some_range) {\n}"));
+ EXPECT_EQ("auto [x, y](expr);", format("auto[x,y] (expr);"));
+ EXPECT_EQ("auto &[x, y](expr);", format("auto & [x,y] (expr);"));
+ EXPECT_EQ("auto &&[x, y](expr);", format("auto && [x,y] (expr);"));
+ EXPECT_EQ("auto const &[x, y](expr);", format("auto const & [x,y] (expr);"));
+ EXPECT_EQ("auto const &&[x, y](expr);", format("auto const && [x,y] (expr);"));
+ EXPECT_EQ("auto [x, y]{expr};", format("auto[x,y] {expr};"));
+ EXPECT_EQ("auto const &[x, y]{expr};", format("auto const & [x,y] {expr};"));
+ EXPECT_EQ("auto const &&[x, y]{expr};", format("auto const && [x,y] {expr};"));
+
+ format::FormatStyle Spaces = format::getLLVMStyle();
+ Spaces.SpacesInSquareBrackets = true;
+ verifyFormat("auto [ a, b ] = f();", Spaces);
+ verifyFormat("auto &&[ a, b ] = f();", Spaces);
+ verifyFormat("auto &[ a, b ] = f();", Spaces);
+ verifyFormat("auto const &&[ a, b ] = f();", Spaces);
+ verifyFormat("auto const &[ a, b ] = f();", Spaces);
+}
+
} // end namespace
} // end namespace format
} // end namespace clang