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