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