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