xref: /llvm-project/clang/unittests/Format/FormatTestMacroExpansion.cpp (revision 51f1681424f1a8ccf1e3432d71c341e799597171)
1f8d10d5aSManuel Klimek //===- unittest/Format/FormatMacroExpansion.cpp - Formatting unit tests ---===//
2f8d10d5aSManuel Klimek //
3f8d10d5aSManuel Klimek // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f8d10d5aSManuel Klimek // See https://llvm.org/LICENSE.txt for license information.
5f8d10d5aSManuel Klimek // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f8d10d5aSManuel Klimek //
7f8d10d5aSManuel Klimek //===----------------------------------------------------------------------===//
8f8d10d5aSManuel Klimek 
9f8d10d5aSManuel Klimek #include "FormatTestBase.h"
10f8d10d5aSManuel Klimek 
11f8d10d5aSManuel Klimek #define DEBUG_TYPE "format-test-macro-expansion"
12f8d10d5aSManuel Klimek 
13f8d10d5aSManuel Klimek namespace clang {
14f8d10d5aSManuel Klimek namespace format {
15f8d10d5aSManuel Klimek namespace test {
16f8d10d5aSManuel Klimek namespace {
17f8d10d5aSManuel Klimek 
18f8d10d5aSManuel Klimek class FormatTestMacroExpansion : public FormatTestBase {};
19f8d10d5aSManuel Klimek 
TEST_F(FormatTestMacroExpansion,UnexpandConfiguredMacros)20f8d10d5aSManuel Klimek TEST_F(FormatTestMacroExpansion, UnexpandConfiguredMacros) {
21f8d10d5aSManuel Klimek   FormatStyle Style = getLLVMStyle();
22f8d10d5aSManuel Klimek   Style.Macros.push_back("CLASS=class C {");
23f8d10d5aSManuel Klimek   Style.Macros.push_back("SEMI=;");
24f8d10d5aSManuel Klimek   Style.Macros.push_back("STMT=f();");
25f8d10d5aSManuel Klimek   Style.Macros.push_back("ID(x)=x");
26f8d10d5aSManuel Klimek   Style.Macros.push_back("ID3(x, y, z)=x y z");
27f8d10d5aSManuel Klimek   Style.Macros.push_back("CALL(x)=f([] { x })");
28f8d10d5aSManuel Klimek   Style.Macros.push_back("ASSIGN_OR_RETURN(a, b)=a = (b)");
29f8d10d5aSManuel Klimek   Style.Macros.push_back("ASSIGN_OR_RETURN(a, b, c)=a = (b); if (x) return c");
30f8d10d5aSManuel Klimek   Style.Macros.push_back("MOCK_METHOD(r, n, a, s)=r n a s");
31f8d10d5aSManuel Klimek 
32f8d10d5aSManuel Klimek   verifyFormat("ID(nested(a(b, c), d))", Style);
33f8d10d5aSManuel Klimek   verifyFormat("CLASS\n"
34f8d10d5aSManuel Klimek                "  a *b;\n"
35f8d10d5aSManuel Klimek                "};",
36f8d10d5aSManuel Klimek                Style);
37f8d10d5aSManuel Klimek   verifyFormat("SEMI\n"
38f8d10d5aSManuel Klimek                "SEMI\n"
39f8d10d5aSManuel Klimek                "SEMI",
40f8d10d5aSManuel Klimek                Style);
41f8d10d5aSManuel Klimek   verifyFormat("STMT\n"
42f8d10d5aSManuel Klimek                "STMT\n"
43f8d10d5aSManuel Klimek                "STMT",
44f8d10d5aSManuel Klimek                Style);
45f8d10d5aSManuel Klimek   verifyFormat("void f() { ID(a *b); }", Style);
46*51f16814SOwen Pan   verifyFormat("ID(\n"
47*51f16814SOwen Pan                "    {\n"
48*51f16814SOwen Pan                "      ID(a *b);\n"
49*51f16814SOwen Pan                "    });",
50f8d10d5aSManuel Klimek                Style);
517e856d18SOwen Pan   verifyIncompleteFormat("ID3({, ID(a *b),\n"
527e856d18SOwen Pan                          "    ;\n"
537e856d18SOwen Pan                          "  });",
54d08fcc81SOwen Pan                          Style);
55f8d10d5aSManuel Klimek 
56f8d10d5aSManuel Klimek   verifyFormat("ID(CALL(CALL(return a * b;)));", Style);
57f8d10d5aSManuel Klimek 
58f8d10d5aSManuel Klimek   verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n"
5988934a82SOwen Pan                "                 MySomewhatLongFunction(SomethingElse()));",
60f8d10d5aSManuel Klimek                Style);
61f8d10d5aSManuel Klimek   verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n"
62f8d10d5aSManuel Klimek                "                 MySomewhatLongFunction(SomethingElse()), "
6388934a82SOwen Pan                "ReturnMe());",
64f8d10d5aSManuel Klimek                Style);
65f8d10d5aSManuel Klimek 
66f8d10d5aSManuel Klimek   verifyFormat(R"(
67f8d10d5aSManuel Klimek #define MACRO(a, b) ID(a + b)
68f8d10d5aSManuel Klimek )",
69f8d10d5aSManuel Klimek                Style);
70f8d10d5aSManuel Klimek   EXPECT_EQ(R"(
71f8d10d5aSManuel Klimek int a;
72f8d10d5aSManuel Klimek int b;
73f8d10d5aSManuel Klimek int c;
74f8d10d5aSManuel Klimek int d;
75f8d10d5aSManuel Klimek int e;
76f8d10d5aSManuel Klimek int f;
77f8d10d5aSManuel Klimek ID(
78f8d10d5aSManuel Klimek     namespace foo {
79f8d10d5aSManuel Klimek     int a;
80f8d10d5aSManuel Klimek     }
81f8d10d5aSManuel Klimek ) // namespace k
82f8d10d5aSManuel Klimek )",
83f8d10d5aSManuel Klimek             format(R"(
84f8d10d5aSManuel Klimek int a;
85f8d10d5aSManuel Klimek int b;
86f8d10d5aSManuel Klimek int c;
87f8d10d5aSManuel Klimek int d;
88f8d10d5aSManuel Klimek int e;
89f8d10d5aSManuel Klimek int f;
90f8d10d5aSManuel Klimek ID(namespace foo { int a; })  // namespace k
91f8d10d5aSManuel Klimek )",
92f8d10d5aSManuel Klimek                    Style));
93f8d10d5aSManuel Klimek   verifyFormat(R"(ID(
94f8d10d5aSManuel Klimek     //
95f8d10d5aSManuel Klimek     ({ ; }))
96f8d10d5aSManuel Klimek )",
97f8d10d5aSManuel Klimek                Style);
98f8d10d5aSManuel Klimek 
99f8d10d5aSManuel Klimek   Style.ColumnLimit = 35;
100f8d10d5aSManuel Klimek   // FIXME: Arbitrary formatting of macros where the end of the logical
101f8d10d5aSManuel Klimek   // line is in the middle of a macro call are not working yet.
102f8d10d5aSManuel Klimek   verifyFormat(R"(ID(
103f8d10d5aSManuel Klimek     void f();
104f8d10d5aSManuel Klimek     void)
105f8d10d5aSManuel Klimek ID(g) ID(()) ID(
106f8d10d5aSManuel Klimek     ;
107f8d10d5aSManuel Klimek     void g();)
108f8d10d5aSManuel Klimek )",
109f8d10d5aSManuel Klimek                Style);
110f8d10d5aSManuel Klimek 
111f8d10d5aSManuel Klimek   Style.ColumnLimit = 10;
112f8d10d5aSManuel Klimek   verifyFormat("STMT\n"
113f8d10d5aSManuel Klimek                "STMT\n"
114f8d10d5aSManuel Klimek                "STMT",
115f8d10d5aSManuel Klimek                Style);
116f8d10d5aSManuel Klimek 
117f8d10d5aSManuel Klimek   EXPECT_EQ(R"(
118f8d10d5aSManuel Klimek ID(CALL(CALL(
119f8d10d5aSManuel Klimek     a *b)));
120f8d10d5aSManuel Klimek )",
121f8d10d5aSManuel Klimek             format(R"(
122f8d10d5aSManuel Klimek ID(CALL(CALL(a * b)));
123f8d10d5aSManuel Klimek )",
124f8d10d5aSManuel Klimek                    Style));
125f8d10d5aSManuel Klimek 
126f8d10d5aSManuel Klimek   // FIXME: If we want to support unbalanced braces or parens from macro
127f8d10d5aSManuel Klimek   // expansions we need to re-think how we propagate errors in
128f8d10d5aSManuel Klimek   // TokenAnnotator::parseLine; for investigation, switching the inner loop of
129f8d10d5aSManuel Klimek   // TokenAnnotator::parseLine to return LT_Other instead of LT_Invalid in case
130f8d10d5aSManuel Klimek   // of !consumeToken() changes the formatting of the test below and makes it
131f8d10d5aSManuel Klimek   // believe it has a fully correct formatting.
132f8d10d5aSManuel Klimek   EXPECT_EQ(R"(
133f8d10d5aSManuel Klimek ID3(
134f8d10d5aSManuel Klimek     {
135f8d10d5aSManuel Klimek       CLASS
136f8d10d5aSManuel Klimek         a *b;
137f8d10d5aSManuel Klimek       };
138f8d10d5aSManuel Klimek     },
139f8d10d5aSManuel Klimek     ID(x *y);
140f8d10d5aSManuel Klimek     ,
141f8d10d5aSManuel Klimek     STMT
142f8d10d5aSManuel Klimek     STMT
143f8d10d5aSManuel Klimek     STMT)
144f8d10d5aSManuel Klimek void f();
145f8d10d5aSManuel Klimek )",
146f8d10d5aSManuel Klimek             format(R"(
147f8d10d5aSManuel Klimek ID3({CLASS a*b; };}, ID(x*y);, STMT STMT STMT)
148f8d10d5aSManuel Klimek void f();
149f8d10d5aSManuel Klimek )",
150f8d10d5aSManuel Klimek                    Style));
151f8d10d5aSManuel Klimek 
152f8d10d5aSManuel Klimek   verifyFormat("ID(a(\n"
153f8d10d5aSManuel Klimek                "#ifdef A\n"
154f8d10d5aSManuel Klimek                "    b, c\n"
155f8d10d5aSManuel Klimek                "#else\n"
156f8d10d5aSManuel Klimek                "    d(e)\n"
157f8d10d5aSManuel Klimek                "#endif\n"
158f8d10d5aSManuel Klimek                "    ))",
159f8d10d5aSManuel Klimek                Style);
160f8d10d5aSManuel Klimek   Style.ColumnLimit = 80;
161f8d10d5aSManuel Klimek   verifyFormat(R"(ASSIGN_OR_RETURN(
162f8d10d5aSManuel Klimek     // Comment
163f8d10d5aSManuel Klimek     a b, c);
164f8d10d5aSManuel Klimek )",
165f8d10d5aSManuel Klimek                Style);
166f8d10d5aSManuel Klimek   Style.ColumnLimit = 30;
167f8d10d5aSManuel Klimek   verifyFormat(R"(ASSIGN_OR_RETURN(
168f8d10d5aSManuel Klimek     // Comment
169f8d10d5aSManuel Klimek     //
170f8d10d5aSManuel Klimek     a b,
171f8d10d5aSManuel Klimek     xxxxxxxxxxxx(
172f8d10d5aSManuel Klimek         yyyyyyyyyyyyyyyyy,
173f8d10d5aSManuel Klimek         zzzzzzzzzzzzzzzzzz),
174f8d10d5aSManuel Klimek     f([]() {
175f8d10d5aSManuel Klimek       a();
176f8d10d5aSManuel Klimek       b();
177f8d10d5aSManuel Klimek     }));
178f8d10d5aSManuel Klimek )",
179f8d10d5aSManuel Klimek                Style);
180f8d10d5aSManuel Klimek   verifyFormat(R"(int a = []() {
181f8d10d5aSManuel Klimek   ID(
182f8d10d5aSManuel Klimek       x;
183f8d10d5aSManuel Klimek       y;
184f8d10d5aSManuel Klimek       z;)
185f8d10d5aSManuel Klimek   ;
186f8d10d5aSManuel Klimek }();
187f8d10d5aSManuel Klimek )",
188f8d10d5aSManuel Klimek                Style);
189f8d10d5aSManuel Klimek   EXPECT_EQ(
190f8d10d5aSManuel Klimek       R"(ASSIGN_OR_RETURN((
191f8d10d5aSManuel Klimek ====
192f8d10d5aSManuel Klimek #))
193f8d10d5aSManuel Klimek })",
194f8d10d5aSManuel Klimek       format(R"(ASSIGN_OR_RETURN((
195f8d10d5aSManuel Klimek ====
196f8d10d5aSManuel Klimek #))
197f8d10d5aSManuel Klimek })",
198f8d10d5aSManuel Klimek              Style, SC_ExpectIncomplete));
199f8d10d5aSManuel Klimek   EXPECT_EQ(R"(ASSIGN_OR_RETURN(
200f8d10d5aSManuel Klimek }
201f8d10d5aSManuel Klimek (
202f8d10d5aSManuel Klimek ====
203f8d10d5aSManuel Klimek #),
204f8d10d5aSManuel Klimek     a))",
205f8d10d5aSManuel Klimek             format(R"(ASSIGN_OR_RETURN(
206f8d10d5aSManuel Klimek }
207f8d10d5aSManuel Klimek (
208f8d10d5aSManuel Klimek ====
209f8d10d5aSManuel Klimek #),
210f8d10d5aSManuel Klimek a))",
211f8d10d5aSManuel Klimek                    Style, SC_ExpectIncomplete));
212f8d10d5aSManuel Klimek   EXPECT_EQ(R"(ASSIGN_OR_RETURN(a
213f8d10d5aSManuel Klimek //
214f8d10d5aSManuel Klimek ====
215f8d10d5aSManuel Klimek #
216f8d10d5aSManuel Klimek                  <))",
217f8d10d5aSManuel Klimek             format(R"(ASSIGN_OR_RETURN(a
218f8d10d5aSManuel Klimek //
219f8d10d5aSManuel Klimek ====
220f8d10d5aSManuel Klimek #
221f8d10d5aSManuel Klimek                  <))",
222f8d10d5aSManuel Klimek                    Style));
223f8d10d5aSManuel Klimek   verifyFormat("class C {\n"
224f8d10d5aSManuel Klimek                "  MOCK_METHOD(R, f,\n"
225f8d10d5aSManuel Klimek                "              (a *b, c *d),\n"
226f8d10d5aSManuel Klimek                "              (override));\n"
227f8d10d5aSManuel Klimek                "};",
228f8d10d5aSManuel Klimek                Style);
229f8d10d5aSManuel Klimek }
230f8d10d5aSManuel Klimek 
TEST_F(FormatTestMacroExpansion,KeepParensWhenExpandingObjectLikeMacros)231f8d10d5aSManuel Klimek TEST_F(FormatTestMacroExpansion, KeepParensWhenExpandingObjectLikeMacros) {
232f8d10d5aSManuel Klimek   FormatStyle Style = getLLVMStyle();
233f8d10d5aSManuel Klimek   Style.Macros.push_back("FN=class C { int f");
234f8d10d5aSManuel Klimek   verifyFormat("void f() {\n"
235f8d10d5aSManuel Klimek                "  FN(a *b);\n"
236f8d10d5aSManuel Klimek                "  };\n"
237f8d10d5aSManuel Klimek                "}",
238f8d10d5aSManuel Klimek                Style);
239f8d10d5aSManuel Klimek }
240f8d10d5aSManuel Klimek 
TEST_F(FormatTestMacroExpansion,DoesNotExpandFunctionLikeMacrosWithoutParens)241f8d10d5aSManuel Klimek TEST_F(FormatTestMacroExpansion, DoesNotExpandFunctionLikeMacrosWithoutParens) {
242f8d10d5aSManuel Klimek   FormatStyle Style = getLLVMStyle();
243f8d10d5aSManuel Klimek   Style.Macros.push_back("CLASS()=class C {");
244f8d10d5aSManuel Klimek   verifyFormat("CLASS void f();\n"
245f8d10d5aSManuel Klimek                "}\n"
246f8d10d5aSManuel Klimek                ";",
247f8d10d5aSManuel Klimek                Style);
248f8d10d5aSManuel Klimek }
249f8d10d5aSManuel Klimek 
TEST_F(FormatTestMacroExpansion,ContinueFormattingAfterUnclosedParensAfterObjectLikeMacro)250f8d10d5aSManuel Klimek TEST_F(FormatTestMacroExpansion,
251f8d10d5aSManuel Klimek        ContinueFormattingAfterUnclosedParensAfterObjectLikeMacro) {
252f8d10d5aSManuel Klimek   FormatStyle Style = getLLVMStyle();
253f8d10d5aSManuel Klimek   Style.Macros.push_back("O=class {");
254d08fcc81SOwen Pan   verifyIncompleteFormat("O(auto x = [](){\n"
255d08fcc81SOwen Pan                          "    f();}",
256d08fcc81SOwen Pan                          Style);
257f8d10d5aSManuel Klimek }
258f8d10d5aSManuel Klimek 
TEST_F(FormatTestMacroExpansion,CommaAsOperator)259b7770befSr4nt TEST_F(FormatTestMacroExpansion, CommaAsOperator) {
260b7770befSr4nt   FormatStyle Style = getGoogleStyleWithColumns(42);
261b7770befSr4nt   Style.Macros.push_back("MACRO(a, b, c)=a=(b); if(x) c");
262b7770befSr4nt   verifyFormat("MACRO(auto a,\n"
263b7770befSr4nt                "      looooongfunction(first, second,\n"
264b7770befSr4nt                "                       third),\n"
265b7770befSr4nt                "      fourth);",
266b7770befSr4nt                Style);
267b7770befSr4nt }
268b7770befSr4nt 
TEST_F(FormatTestMacroExpansion,ForcedBreakDiffers)269b7770befSr4nt TEST_F(FormatTestMacroExpansion, ForcedBreakDiffers) {
270b7770befSr4nt   FormatStyle Style = getGoogleStyleWithColumns(40);
271b7770befSr4nt   Style.Macros.push_back("MACRO(a, b)=a=(b)");
272b7770befSr4nt   verifyFormat("//\n"
273b7770befSr4nt                "MACRO(const type variable,\n"
274b7770befSr4nt                "      functtioncall(\n"
275b7770befSr4nt                "          first, longsecondarg, third));",
276b7770befSr4nt                Style);
277b7770befSr4nt }
278b7770befSr4nt 
TEST_F(FormatTestMacroExpansion,PreferNotBreakingBetweenReturnTypeAndFunction)279b7770befSr4nt TEST_F(FormatTestMacroExpansion,
280b7770befSr4nt        PreferNotBreakingBetweenReturnTypeAndFunction) {
281b7770befSr4nt   FormatStyle Style = getGoogleStyleWithColumns(22);
282b7770befSr4nt   Style.Macros.push_back("MOCK_METHOD(r, n, a)=r n a");
283b7770befSr4nt   // In the expanded code, we parse a full function signature, and afterwards
284b7770befSr4nt   // know that we prefer not to break before the function name.
285b7770befSr4nt   verifyFormat("MOCK_METHOD(\n"
286b7770befSr4nt                "    type, variable,\n"
287b7770befSr4nt                "    (type));",
288ddb4450aSr4nt                Style);
289ddb4450aSr4nt }
290ddb4450aSr4nt 
TEST_F(FormatTestMacroExpansion,IndentChildrenWithinMacroCall)291ddb4450aSr4nt TEST_F(FormatTestMacroExpansion, IndentChildrenWithinMacroCall) {
292ddb4450aSr4nt   FormatStyle Style = getGoogleStyleWithColumns(22);
293ddb4450aSr4nt   Style.Macros.push_back("MACRO(a, b)=a=(b)");
294ddb4450aSr4nt   verifyFormat("void f() {\n"
295ddb4450aSr4nt                "  MACRO(a b, call([] {\n"
296ddb4450aSr4nt                "          if (expr) {\n"
297ddb4450aSr4nt                "            indent();\n"
298ddb4450aSr4nt                "          }\n"
299ddb4450aSr4nt                "        }));\n"
300ddb4450aSr4nt                "}",
301b7770befSr4nt                Style);
302b7770befSr4nt }
303b7770befSr4nt 
304f8d10d5aSManuel Klimek } // namespace
305f8d10d5aSManuel Klimek } // namespace test
306f8d10d5aSManuel Klimek } // namespace format
307f8d10d5aSManuel Klimek } // namespace clang
308