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(R"(ID3({, ID(a *b), 51 ; 52 }); 53 )", 54 Style); 55 56 verifyFormat("ID(CALL(CALL(return a * b;)));", Style); 57 58 verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n" 59 " MySomewhatLongFunction(SomethingElse()));\n", 60 Style); 61 verifyFormat("ASSIGN_OR_RETURN(MySomewhatLongType *variable,\n" 62 " MySomewhatLongFunction(SomethingElse()), " 63 "ReturnMe());\n", 64 Style); 65 66 verifyFormat(R"( 67 #define MACRO(a, b) ID(a + b) 68 )", 69 Style); 70 EXPECT_EQ(R"( 71 int a; 72 int b; 73 int c; 74 int d; 75 int e; 76 int f; 77 ID( 78 namespace foo { 79 int a; 80 } 81 ) // namespace k 82 )", 83 format(R"( 84 int a; 85 int b; 86 int c; 87 int d; 88 int e; 89 int f; 90 ID(namespace foo { int a; }) // namespace k 91 )", 92 Style)); 93 verifyFormat(R"(ID( 94 // 95 ({ ; })) 96 )", 97 Style); 98 99 Style.ColumnLimit = 35; 100 // FIXME: Arbitrary formatting of macros where the end of the logical 101 // line is in the middle of a macro call are not working yet. 102 verifyFormat(R"(ID( 103 void f(); 104 void) 105 ID(g) ID(()) ID( 106 ; 107 void g();) 108 )", 109 Style); 110 111 Style.ColumnLimit = 10; 112 verifyFormat("STMT\n" 113 "STMT\n" 114 "STMT", 115 Style); 116 117 EXPECT_EQ(R"( 118 ID(CALL(CALL( 119 a *b))); 120 )", 121 format(R"( 122 ID(CALL(CALL(a * b))); 123 )", 124 Style)); 125 126 // FIXME: If we want to support unbalanced braces or parens from macro 127 // expansions we need to re-think how we propagate errors in 128 // TokenAnnotator::parseLine; for investigation, switching the inner loop of 129 // TokenAnnotator::parseLine to return LT_Other instead of LT_Invalid in case 130 // of !consumeToken() changes the formatting of the test below and makes it 131 // believe it has a fully correct formatting. 132 EXPECT_EQ(R"( 133 ID3( 134 { 135 CLASS 136 a *b; 137 }; 138 }, 139 ID(x *y); 140 , 141 STMT 142 STMT 143 STMT) 144 void f(); 145 )", 146 format(R"( 147 ID3({CLASS a*b; };}, ID(x*y);, STMT STMT STMT) 148 void f(); 149 )", 150 Style)); 151 152 verifyFormat("ID(a(\n" 153 "#ifdef A\n" 154 " b, c\n" 155 "#else\n" 156 " d(e)\n" 157 "#endif\n" 158 " ))", 159 Style); 160 Style.ColumnLimit = 80; 161 verifyFormat(R"(ASSIGN_OR_RETURN( 162 // Comment 163 a b, c); 164 )", 165 Style); 166 Style.ColumnLimit = 30; 167 verifyFormat(R"(ASSIGN_OR_RETURN( 168 // Comment 169 // 170 a b, 171 xxxxxxxxxxxx( 172 yyyyyyyyyyyyyyyyy, 173 zzzzzzzzzzzzzzzzzz), 174 f([]() { 175 a(); 176 b(); 177 })); 178 )", 179 Style); 180 verifyFormat(R"(int a = []() { 181 ID( 182 x; 183 y; 184 z;) 185 ; 186 }(); 187 )", 188 Style); 189 EXPECT_EQ( 190 R"(ASSIGN_OR_RETURN(( 191 ==== 192 #)) 193 })", 194 format(R"(ASSIGN_OR_RETURN(( 195 ==== 196 #)) 197 })", 198 Style, SC_ExpectIncomplete)); 199 EXPECT_EQ(R"(ASSIGN_OR_RETURN( 200 } 201 ( 202 ==== 203 #), 204 a))", 205 format(R"(ASSIGN_OR_RETURN( 206 } 207 ( 208 ==== 209 #), 210 a))", 211 Style, SC_ExpectIncomplete)); 212 EXPECT_EQ(R"(ASSIGN_OR_RETURN(a 213 // 214 ==== 215 # 216 <))", 217 format(R"(ASSIGN_OR_RETURN(a 218 // 219 ==== 220 # 221 <))", 222 Style)); 223 verifyFormat("class C {\n" 224 " MOCK_METHOD(R, f,\n" 225 " (a *b, c *d),\n" 226 " (override));\n" 227 "};", 228 Style); 229 } 230 231 TEST_F(FormatTestMacroExpansion, KeepParensWhenExpandingObjectLikeMacros) { 232 FormatStyle Style = getLLVMStyle(); 233 Style.Macros.push_back("FN=class C { int f"); 234 verifyFormat("void f() {\n" 235 " FN(a *b);\n" 236 " };\n" 237 "}", 238 Style); 239 } 240 241 TEST_F(FormatTestMacroExpansion, DoesNotExpandFunctionLikeMacrosWithoutParens) { 242 FormatStyle Style = getLLVMStyle(); 243 Style.Macros.push_back("CLASS()=class C {"); 244 verifyFormat("CLASS void f();\n" 245 "}\n" 246 ";", 247 Style); 248 } 249 250 TEST_F(FormatTestMacroExpansion, 251 ContinueFormattingAfterUnclosedParensAfterObjectLikeMacro) { 252 FormatStyle Style = getLLVMStyle(); 253 Style.Macros.push_back("O=class {"); 254 verifyIncompleteFormat("O(auto x = [](){\n" 255 " f();}", 256 Style); 257 } 258 259 } // namespace 260 } // namespace test 261 } // namespace format 262 } // namespace clang 263