clang: lib/Format/Format.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

25#include "llvm/ADT/Sequence.h"

26

27#define DEBUG_TYPE "format-formatter"

28

30

31LLVM_YAML_IS_SEQUENCE_VECTOR(FormatStyle::RawStringFormat)

32

33namespace llvm {

34namespace yaml {

35template <>

36struct ScalarEnumerationTraits<FormatStyle::BreakBeforeNoexceptSpecifierStyle> {

37 static void

38 enumeration(IO &IO, FormatStyle::BreakBeforeNoexceptSpecifierStyle &Value) {

39 IO.enumCase(Value, "Never", FormatStyle::BBNSS_Never);

40 IO.enumCase(Value, "OnlyWithParen", FormatStyle::BBNSS_OnlyWithParen);

41 IO.enumCase(Value, "Always", FormatStyle::BBNSS_Always);

42 }

43};

44

45template <> struct MappingTraits<FormatStyle::AlignConsecutiveStyle> {

46 static void enumInput(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {

47 IO.enumCase(Value, "None", FormatStyle::AlignConsecutiveStyle({}));

48 IO.enumCase(Value, "Consecutive",

49 FormatStyle::AlignConsecutiveStyle(

50 {true, false,

51 false, false,

52 true,

53 false, true}));

54 IO.enumCase(Value, "AcrossEmptyLines",

55 FormatStyle::AlignConsecutiveStyle(

56 {true, true,

57 false, false,

58 true,

59 false, true}));

60 IO.enumCase(Value, "AcrossComments",

61 FormatStyle::AlignConsecutiveStyle(

62 {true, false,

63 true, false,

64 true,

65 false, true}));

66 IO.enumCase(Value, "AcrossEmptyLinesAndComments",

67 FormatStyle::AlignConsecutiveStyle(

68 {true, true,

69 true, false,

70 true,

71 false, true}));

72

73

74 IO.enumCase(Value, "true",

75 FormatStyle::AlignConsecutiveStyle(

76 {true, false,

77 false, false,

78 true,

79 false, true}));

80 IO.enumCase(Value, "false", FormatStyle::AlignConsecutiveStyle({}));

81 }

82

83 static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) {

84 IO.mapOptional("Enabled", Value.Enabled);

85 IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);

86 IO.mapOptional("AcrossComments", Value.AcrossComments);

87 IO.mapOptional("AlignCompound", Value.AlignCompound);

88 IO.mapOptional("AlignFunctionDeclarations",

89 Value.AlignFunctionDeclarations);

90 IO.mapOptional("AlignFunctionPointers", Value.AlignFunctionPointers);

91 IO.mapOptional("PadOperators", Value.PadOperators);

92 }

93};

94

95template <>

96struct MappingTraits<FormatStyle::ShortCaseStatementsAlignmentStyle> {

98 FormatStyle::ShortCaseStatementsAlignmentStyle &Value) {

99 IO.mapOptional("Enabled", Value.Enabled);

100 IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines);

101 IO.mapOptional("AcrossComments", Value.AcrossComments);

102 IO.mapOptional("AlignCaseArrows", Value.AlignCaseArrows);

103 IO.mapOptional("AlignCaseColons", Value.AlignCaseColons);

104 }

105};

106

107template <>

108struct ScalarEnumerationTraits<FormatStyle::AttributeBreakingStyle> {

109 static void enumeration(IO &IO, FormatStyle::AttributeBreakingStyle &Value) {

110 IO.enumCase(Value, "Always", FormatStyle::ABS_Always);

111 IO.enumCase(Value, "Leave", FormatStyle::ABS_Leave);

112 IO.enumCase(Value, "Never", FormatStyle::ABS_Never);

113 }

114};

115

116template <>

117struct ScalarEnumerationTraits<FormatStyle::ArrayInitializerAlignmentStyle> {

119 FormatStyle::ArrayInitializerAlignmentStyle &Value) {

120 IO.enumCase(Value, "None", FormatStyle::AIAS_None);

121 IO.enumCase(Value, "Left", FormatStyle::AIAS_Left);

122 IO.enumCase(Value, "Right", FormatStyle::AIAS_Right);

123 }

124};

125

126template <> struct ScalarEnumerationTraits<FormatStyle::BinaryOperatorStyle> {

127 static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) {

128 IO.enumCase(Value, "All", FormatStyle::BOS_All);

129 IO.enumCase(Value, "true", FormatStyle::BOS_All);

130 IO.enumCase(Value, "None", FormatStyle::BOS_None);

131 IO.enumCase(Value, "false", FormatStyle::BOS_None);

132 IO.enumCase(Value, "NonAssignment", FormatStyle::BOS_NonAssignment);

133 }

134};

135

136template <>

137struct ScalarEnumerationTraits<FormatStyle::BinPackParametersStyle> {

138 static void enumeration(IO &IO, FormatStyle::BinPackParametersStyle &Value) {

139 IO.enumCase(Value, "BinPack", FormatStyle::BPPS_BinPack);

140 IO.enumCase(Value, "OnePerLine", FormatStyle::BPPS_OnePerLine);

141 IO.enumCase(Value, "AlwaysOnePerLine", FormatStyle::BPPS_AlwaysOnePerLine);

142

143

144 IO.enumCase(Value, "true", FormatStyle::BPPS_BinPack);

145 IO.enumCase(Value, "false", FormatStyle::BPPS_OnePerLine);

146 }

147};

148

149template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> {

151 IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto);

152 IO.enumCase(Value, "Always", FormatStyle::BPS_Always);

153 IO.enumCase(Value, "Never", FormatStyle::BPS_Never);

154 }

155};

156

157template <>

158struct ScalarEnumerationTraits<FormatStyle::BitFieldColonSpacingStyle> {

160 FormatStyle::BitFieldColonSpacingStyle &Value) {

161 IO.enumCase(Value, "Both", FormatStyle::BFCS_Both);

162 IO.enumCase(Value, "None", FormatStyle::BFCS_None);

163 IO.enumCase(Value, "Before", FormatStyle::BFCS_Before);

164 IO.enumCase(Value, "After", FormatStyle::BFCS_After);

165 }

166};

167

168template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {

169 static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) {

170 IO.enumCase(Value, "Attach", FormatStyle::BS_Attach);

171 IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);

172 IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla);

173 IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);

174 IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);

175 IO.enumCase(Value, "Whitesmiths", FormatStyle::BS_Whitesmiths);

176 IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);

177 IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit);

178 IO.enumCase(Value, "Custom", FormatStyle::BS_Custom);

179 }

180};

181

182template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {

183 static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {

184 IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel);

185 IO.mapOptional("AfterClass", Wrapping.AfterClass);

186 IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);

187 IO.mapOptional("AfterEnum", Wrapping.AfterEnum);

188 IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock);

189 IO.mapOptional("AfterFunction", Wrapping.AfterFunction);

190 IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace);

191 IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);

192 IO.mapOptional("AfterStruct", Wrapping.AfterStruct);

193 IO.mapOptional("AfterUnion", Wrapping.AfterUnion);

194 IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch);

195 IO.mapOptional("BeforeElse", Wrapping.BeforeElse);

196 IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody);

197 IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile);

198 IO.mapOptional("IndentBraces", Wrapping.IndentBraces);

199 IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction);

200 IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord);

201 IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);

202 }

203};

204

205template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> {

206 static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) {

207 IO.enumCase(Value, "Align", FormatStyle::BAS_Align);

208 IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign);

209 IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak);

210 IO.enumCase(Value, "BlockIndent", FormatStyle::BAS_BlockIndent);

211

212

213 IO.enumCase(Value, "true", FormatStyle::BAS_Align);

214 IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign);

215 }

216};

217

218template <>

219struct ScalarEnumerationTraits<

220 FormatStyle::BraceWrappingAfterControlStatementStyle> {

221 static void

223 FormatStyle::BraceWrappingAfterControlStatementStyle &Value) {

224 IO.enumCase(Value, "Never", FormatStyle::BWACS_Never);

225 IO.enumCase(Value, "MultiLine", FormatStyle::BWACS_MultiLine);

226 IO.enumCase(Value, "Always", FormatStyle::BWACS_Always);

227

228

229 IO.enumCase(Value, "false", FormatStyle::BWACS_Never);

230 IO.enumCase(Value, "true", FormatStyle::BWACS_Always);

231 }

232};

233

234template <>

235struct ScalarEnumerationTraits<

236 FormatStyle::BreakBeforeConceptDeclarationsStyle> {

237 static void

238 enumeration(IO &IO, FormatStyle::BreakBeforeConceptDeclarationsStyle &Value) {

239 IO.enumCase(Value, "Never", FormatStyle::BBCDS_Never);

240 IO.enumCase(Value, "Allowed", FormatStyle::BBCDS_Allowed);

241 IO.enumCase(Value, "Always", FormatStyle::BBCDS_Always);

242

243

244 IO.enumCase(Value, "true", FormatStyle::BBCDS_Always);

245 IO.enumCase(Value, "false", FormatStyle::BBCDS_Allowed);

246 }

247};

248

249template <>

250struct ScalarEnumerationTraits<FormatStyle::BreakBeforeInlineASMColonStyle> {

252 FormatStyle::BreakBeforeInlineASMColonStyle &Value) {

253 IO.enumCase(Value, "Never", FormatStyle::BBIAS_Never);

254 IO.enumCase(Value, "OnlyMultiline", FormatStyle::BBIAS_OnlyMultiline);

255 IO.enumCase(Value, "Always", FormatStyle::BBIAS_Always);

256 }

257};

258

259template <>

260struct ScalarEnumerationTraits<FormatStyle::BreakBinaryOperationsStyle> {

262 FormatStyle::BreakBinaryOperationsStyle &Value) {

263 IO.enumCase(Value, "Never", FormatStyle::BBO_Never);

264 IO.enumCase(Value, "OnePerLine", FormatStyle::BBO_OnePerLine);

265 IO.enumCase(Value, "RespectPrecedence", FormatStyle::BBO_RespectPrecedence);

266 }

267};

268

269template <>

270struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {

271 static void

272 enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value) {

273 IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon);

274 IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma);

275 IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon);

276 }

277};

278

279template <>

280struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> {

282 FormatStyle::BreakInheritanceListStyle &Value) {

283 IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon);

284 IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma);

285 IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon);

286 IO.enumCase(Value, "AfterComma", FormatStyle::BILS_AfterComma);

287 }

288};

289

290template <>

291struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {

293 FormatStyle::BreakTemplateDeclarationsStyle &Value) {

294 IO.enumCase(Value, "Leave", FormatStyle::BTDS_Leave);

295 IO.enumCase(Value, "No", FormatStyle::BTDS_No);

296 IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);

297 IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);

298

299

300 IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine);

301 IO.enumCase(Value, "true", FormatStyle::BTDS_Yes);

302 }

303};

304

305template <> struct ScalarEnumerationTraits<FormatStyle::DAGArgStyle> {

307 IO.enumCase(Value, "DontBreak", FormatStyle::DAS_DontBreak);

308 IO.enumCase(Value, "BreakElements", FormatStyle::DAS_BreakElements);

309 IO.enumCase(Value, "BreakAll", FormatStyle::DAS_BreakAll);

310 }

311};

312

313template <>

314struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {

315 static void

316 enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) {

317 IO.enumCase(Value, "None", FormatStyle::DRTBS_None);

318 IO.enumCase(Value, "All", FormatStyle::DRTBS_All);

319 IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel);

320

321

322 IO.enumCase(Value, "false", FormatStyle::DRTBS_None);

323 IO.enumCase(Value, "true", FormatStyle::DRTBS_All);

324 }

325};

326

327template <>

328struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> {

330 FormatStyle::EscapedNewlineAlignmentStyle &Value) {

331 IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign);

332 IO.enumCase(Value, "Left", FormatStyle::ENAS_Left);

333 IO.enumCase(Value, "LeftWithLastLine", FormatStyle::ENAS_LeftWithLastLine);

334 IO.enumCase(Value, "Right", FormatStyle::ENAS_Right);

335

336

337 IO.enumCase(Value, "true", FormatStyle::ENAS_Left);

338 IO.enumCase(Value, "false", FormatStyle::ENAS_Right);

339 }

340};

341

342template <>

343struct ScalarEnumerationTraits<FormatStyle::EmptyLineAfterAccessModifierStyle> {

344 static void

345 enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value) {

346 IO.enumCase(Value, "Never", FormatStyle::ELAAMS_Never);

347 IO.enumCase(Value, "Leave", FormatStyle::ELAAMS_Leave);

348 IO.enumCase(Value, "Always", FormatStyle::ELAAMS_Always);

349 }

350};

351

352template <>

353struct ScalarEnumerationTraits<

354 FormatStyle::EmptyLineBeforeAccessModifierStyle> {

355 static void

356 enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value) {

357 IO.enumCase(Value, "Never", FormatStyle::ELBAMS_Never);

358 IO.enumCase(Value, "Leave", FormatStyle::ELBAMS_Leave);

359 IO.enumCase(Value, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock);

360 IO.enumCase(Value, "Always", FormatStyle::ELBAMS_Always);

361 }

362};

363

364template <>

365struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> {

366 static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) {

367 IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock);

368 IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent);

369 IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent);

370 IO.enumCase(Value, "true", FormatStyle::IEBS_Indent);

371 IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent);

372 }

373};

374

375template <> struct MappingTraits<FormatStyle::IntegerLiteralSeparatorStyle> {

376 static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &Base) {

377 IO.mapOptional("Binary", Base.Binary);

378 IO.mapOptional("BinaryMinDigits", Base.BinaryMinDigits);

379 IO.mapOptional("Decimal", Base.Decimal);

380 IO.mapOptional("DecimalMinDigits", Base.DecimalMinDigits);

381 IO.mapOptional("Hex", Base.Hex);

382 IO.mapOptional("HexMinDigits", Base.HexMinDigits);

383 }

384};

385

386template <> struct ScalarEnumerationTraits<FormatStyle::JavaScriptQuoteStyle> {

387 static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value) {

388 IO.enumCase(Value, "Leave", FormatStyle::JSQS_Leave);

389 IO.enumCase(Value, "Single", FormatStyle::JSQS_Single);

390 IO.enumCase(Value, "Double", FormatStyle::JSQS_Double);

391 }

392};

393

394template <> struct MappingTraits<FormatStyle::KeepEmptyLinesStyle> {

395 static void mapping(IO &IO, FormatStyle::KeepEmptyLinesStyle &Value) {

396 IO.mapOptional("AtEndOfFile", Value.AtEndOfFile);

397 IO.mapOptional("AtStartOfBlock", Value.AtStartOfBlock);

398 IO.mapOptional("AtStartOfFile", Value.AtStartOfFile);

399 }

400};

401

402template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {

404 IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);

405 IO.enumCase(Value, "Java", FormatStyle::LK_Java);

406 IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);

407 IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);

408 IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);

409 IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);

410 IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);

411 IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);

412 IO.enumCase(Value, "Json", FormatStyle::LK_Json);

413 IO.enumCase(Value, "Verilog", FormatStyle::LK_Verilog);

414 }

415};

416

417template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {

419 IO.enumCase(Value, "c++03", FormatStyle::LS_Cpp03);

420 IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03);

421 IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03);

422

423 IO.enumCase(Value, "c++11", FormatStyle::LS_Cpp11);

424 IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11);

425

426 IO.enumCase(Value, "c++14", FormatStyle::LS_Cpp14);

427 IO.enumCase(Value, "c++17", FormatStyle::LS_Cpp17);

428 IO.enumCase(Value, "c++20", FormatStyle::LS_Cpp20);

429

430 IO.enumCase(Value, "Latest", FormatStyle::LS_Latest);

431 IO.enumCase(Value, "Cpp11", FormatStyle::LS_Latest);

432 IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);

433 }

434};

435

436template <>

437struct ScalarEnumerationTraits<FormatStyle::LambdaBodyIndentationKind> {

439 FormatStyle::LambdaBodyIndentationKind &Value) {

440 IO.enumCase(Value, "Signature", FormatStyle::LBI_Signature);

441 IO.enumCase(Value, "OuterScope", FormatStyle::LBI_OuterScope);

442 }

443};

444

445template <> struct ScalarEnumerationTraits<FormatStyle::LineEndingStyle> {

447 IO.enumCase(Value, "LF", FormatStyle::LE_LF);

448 IO.enumCase(Value, "CRLF", FormatStyle::LE_CRLF);

449 IO.enumCase(Value, "DeriveLF", FormatStyle::LE_DeriveLF);

450 IO.enumCase(Value, "DeriveCRLF", FormatStyle::LE_DeriveCRLF);

451 }

452};

453

454template <>

455struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {

457 FormatStyle::NamespaceIndentationKind &Value) {

458 IO.enumCase(Value, "None", FormatStyle::NI_None);

459 IO.enumCase(Value, "Inner", FormatStyle::NI_Inner);

460 IO.enumCase(Value, "All", FormatStyle::NI_All);

461 }

462};

463

464template <> struct ScalarEnumerationTraits<FormatStyle::OperandAlignmentStyle> {

465 static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value) {

466 IO.enumCase(Value, "DontAlign", FormatStyle::OAS_DontAlign);

467 IO.enumCase(Value, "Align", FormatStyle::OAS_Align);

468 IO.enumCase(Value, "AlignAfterOperator",

469 FormatStyle::OAS_AlignAfterOperator);

470

471

472 IO.enumCase(Value, "true", FormatStyle::OAS_Align);

473 IO.enumCase(Value, "false", FormatStyle::OAS_DontAlign);

474 }

475};

476

477template <>

478struct ScalarEnumerationTraits<FormatStyle::PackConstructorInitializersStyle> {

479 static void

480 enumeration(IO &IO, FormatStyle::PackConstructorInitializersStyle &Value) {

481 IO.enumCase(Value, "Never", FormatStyle::PCIS_Never);

482 IO.enumCase(Value, "BinPack", FormatStyle::PCIS_BinPack);

483 IO.enumCase(Value, "CurrentLine", FormatStyle::PCIS_CurrentLine);

484 IO.enumCase(Value, "NextLine", FormatStyle::PCIS_NextLine);

485 IO.enumCase(Value, "NextLineOnly", FormatStyle::PCIS_NextLineOnly);

486 }

487};

488

489template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {

490 static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {

491 IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);

492 IO.enumCase(Value, "Left", FormatStyle::PAS_Left);

493 IO.enumCase(Value, "Right", FormatStyle::PAS_Right);

494

495

496 IO.enumCase(Value, "true", FormatStyle::PAS_Left);

497 IO.enumCase(Value, "false", FormatStyle::PAS_Right);

498 }

499};

500

501template <>

502struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {

503 static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {

504 IO.enumCase(Value, "None", FormatStyle::PPDIS_None);

505 IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash);

506 IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash);

507 }

508};

509

510template <>

511struct ScalarEnumerationTraits<FormatStyle::QualifierAlignmentStyle> {

512 static void enumeration(IO &IO, FormatStyle::QualifierAlignmentStyle &Value) {

513 IO.enumCase(Value, "Leave", FormatStyle::QAS_Leave);

514 IO.enumCase(Value, "Left", FormatStyle::QAS_Left);

515 IO.enumCase(Value, "Right", FormatStyle::QAS_Right);

516 IO.enumCase(Value, "Custom", FormatStyle::QAS_Custom);

517 }

518};

519

520template <> struct MappingTraits<FormatStyle::RawStringFormat> {

521 static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {

522 IO.mapOptional("Language", Format.Language);

523 IO.mapOptional("Delimiters", Format.Delimiters);

524 IO.mapOptional("EnclosingFunctions", Format.EnclosingFunctions);

525 IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter);

526 IO.mapOptional("BasedOnStyle", Format.BasedOnStyle);

527 }

528};

529

530template <> struct ScalarEnumerationTraits<FormatStyle::ReflowCommentsStyle> {

531 static void enumeration(IO &IO, FormatStyle::ReflowCommentsStyle &Value) {

532 IO.enumCase(Value, "Never", FormatStyle::RCS_Never);

533 IO.enumCase(Value, "IndentOnly", FormatStyle::RCS_IndentOnly);

534 IO.enumCase(Value, "Always", FormatStyle::RCS_Always);

535

536 IO.enumCase(Value, "false", FormatStyle::RCS_Never);

537 IO.enumCase(Value, "true", FormatStyle::RCS_Always);

538 }

539};

540

541template <>

542struct ScalarEnumerationTraits<FormatStyle::ReferenceAlignmentStyle> {

543 static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value) {

544 IO.enumCase(Value, "Pointer", FormatStyle::RAS_Pointer);

545 IO.enumCase(Value, "Middle", FormatStyle::RAS_Middle);

546 IO.enumCase(Value, "Left", FormatStyle::RAS_Left);

547 IO.enumCase(Value, "Right", FormatStyle::RAS_Right);

548 }

549};

550

551template <>

552struct ScalarEnumerationTraits<FormatStyle::RemoveParenthesesStyle> {

553 static void enumeration(IO &IO, FormatStyle::RemoveParenthesesStyle &Value) {

554 IO.enumCase(Value, "Leave", FormatStyle::RPS_Leave);

555 IO.enumCase(Value, "MultipleParentheses",

556 FormatStyle::RPS_MultipleParentheses);

557 IO.enumCase(Value, "ReturnStatement", FormatStyle::RPS_ReturnStatement);

558 }

559};

560

561template <>

562struct ScalarEnumerationTraits<FormatStyle::RequiresClausePositionStyle> {

564 FormatStyle::RequiresClausePositionStyle &Value) {

565 IO.enumCase(Value, "OwnLine", FormatStyle::RCPS_OwnLine);

566 IO.enumCase(Value, "OwnLineWithBrace", FormatStyle::RCPS_OwnLineWithBrace);

567 IO.enumCase(Value, "WithPreceding", FormatStyle::RCPS_WithPreceding);

568 IO.enumCase(Value, "WithFollowing", FormatStyle::RCPS_WithFollowing);

569 IO.enumCase(Value, "SingleLine", FormatStyle::RCPS_SingleLine);

570 }

571};

572

573template <>

574struct ScalarEnumerationTraits<FormatStyle::RequiresExpressionIndentationKind> {

575 static void

576 enumeration(IO &IO, FormatStyle::RequiresExpressionIndentationKind &Value) {

577 IO.enumCase(Value, "Keyword", FormatStyle::REI_Keyword);

578 IO.enumCase(Value, "OuterScope", FormatStyle::REI_OuterScope);

579 }

580};

581

582template <>

583struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {

584 static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {

585 IO.enumCase(Value, "None", FormatStyle::RTBS_None);

586 IO.enumCase(Value, "Automatic", FormatStyle::RTBS_Automatic);

587 IO.enumCase(Value, "ExceptShortType", FormatStyle::RTBS_ExceptShortType);

588 IO.enumCase(Value, "All", FormatStyle::RTBS_All);

589 IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel);

590 IO.enumCase(Value, "TopLevelDefinitions",

591 FormatStyle::RTBS_TopLevelDefinitions);

592 IO.enumCase(Value, "AllDefinitions", FormatStyle::RTBS_AllDefinitions);

593 }

594};

595

596template <>

597struct ScalarEnumerationTraits<FormatStyle::SeparateDefinitionStyle> {

598 static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value) {

599 IO.enumCase(Value, "Leave", FormatStyle::SDS_Leave);

600 IO.enumCase(Value, "Always", FormatStyle::SDS_Always);

601 IO.enumCase(Value, "Never", FormatStyle::SDS_Never);

602 }

603};

604

605template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {

607 IO.enumCase(Value, "Never", FormatStyle::SBS_Never);

608 IO.enumCase(Value, "false", FormatStyle::SBS_Never);

609 IO.enumCase(Value, "Always", FormatStyle::SBS_Always);

610 IO.enumCase(Value, "true", FormatStyle::SBS_Always);

611 IO.enumCase(Value, "Empty", FormatStyle::SBS_Empty);

612 }

613};

614

615template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {

616 static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {

617 IO.enumCase(Value, "None", FormatStyle::SFS_None);

618 IO.enumCase(Value, "false", FormatStyle::SFS_None);

619 IO.enumCase(Value, "All", FormatStyle::SFS_All);

620 IO.enumCase(Value, "true", FormatStyle::SFS_All);

621 IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);

622 IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);

623 IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);

624 }

625};

626

627template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {

629 IO.enumCase(Value, "Never", FormatStyle::SIS_Never);

630 IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse);

631 IO.enumCase(Value, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf);

632 IO.enumCase(Value, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse);

633

634

635 IO.enumCase(Value, "Always", FormatStyle::SIS_OnlyFirstIf);

636 IO.enumCase(Value, "false", FormatStyle::SIS_Never);

637 IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse);

638 }

639};

640

641template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> {

643 IO.enumCase(Value, "None", FormatStyle::SLS_None);

644 IO.enumCase(Value, "false", FormatStyle::SLS_None);

645 IO.enumCase(Value, "Empty", FormatStyle::SLS_Empty);

646 IO.enumCase(Value, "Inline", FormatStyle::SLS_Inline);

647 IO.enumCase(Value, "All", FormatStyle::SLS_All);

648 IO.enumCase(Value, "true", FormatStyle::SLS_All);

649 }

650};

651

652template <> struct ScalarEnumerationTraits<FormatStyle::SortIncludesOptions> {

653 static void enumeration(IO &IO, FormatStyle::SortIncludesOptions &Value) {

654 IO.enumCase(Value, "Never", FormatStyle::SI_Never);

655 IO.enumCase(Value, "CaseInsensitive", FormatStyle::SI_CaseInsensitive);

656 IO.enumCase(Value, "CaseSensitive", FormatStyle::SI_CaseSensitive);

657

658

659 IO.enumCase(Value, "false", FormatStyle::SI_Never);

660 IO.enumCase(Value, "true", FormatStyle::SI_CaseSensitive);

661 }

662};

663

664template <>

665struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> {

667 FormatStyle::SortJavaStaticImportOptions &Value) {

668 IO.enumCase(Value, "Before", FormatStyle::SJSIO_Before);

669 IO.enumCase(Value, "After", FormatStyle::SJSIO_After);

670 }

671};

672

673template <>

674struct ScalarEnumerationTraits<FormatStyle::SortUsingDeclarationsOptions> {

676 FormatStyle::SortUsingDeclarationsOptions &Value) {

677 IO.enumCase(Value, "Never", FormatStyle::SUD_Never);

678 IO.enumCase(Value, "Lexicographic", FormatStyle::SUD_Lexicographic);

679 IO.enumCase(Value, "LexicographicNumeric",

680 FormatStyle::SUD_LexicographicNumeric);

681

682

683 IO.enumCase(Value, "false", FormatStyle::SUD_Never);

684 IO.enumCase(Value, "true", FormatStyle::SUD_LexicographicNumeric);

685 }

686};

687

688template <>

689struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> {

690 static void

691 enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value) {

692 IO.enumCase(Value, "Default", FormatStyle::SAPQ_Default);

693 IO.enumCase(Value, "Before", FormatStyle::SAPQ_Before);

694 IO.enumCase(Value, "After", FormatStyle::SAPQ_After);

695 IO.enumCase(Value, "Both", FormatStyle::SAPQ_Both);

696 }

697};

698

699template <> struct MappingTraits<FormatStyle::SpaceBeforeParensCustom> {

700 static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing) {

701 IO.mapOptional("AfterControlStatements", Spacing.AfterControlStatements);

702 IO.mapOptional("AfterForeachMacros", Spacing.AfterForeachMacros);

703 IO.mapOptional("AfterFunctionDefinitionName",

704 Spacing.AfterFunctionDefinitionName);

705 IO.mapOptional("AfterFunctionDeclarationName",

706 Spacing.AfterFunctionDeclarationName);

707 IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros);

708 IO.mapOptional("AfterOverloadedOperator", Spacing.AfterOverloadedOperator);

709 IO.mapOptional("AfterPlacementOperator", Spacing.AfterPlacementOperator);

710 IO.mapOptional("AfterRequiresInClause", Spacing.AfterRequiresInClause);

711 IO.mapOptional("AfterRequiresInExpression",

712 Spacing.AfterRequiresInExpression);

713 IO.mapOptional("BeforeNonEmptyParentheses",

714 Spacing.BeforeNonEmptyParentheses);

715 }

716};

717

718template <>

719struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensStyle> {

720 static void enumeration(IO &IO, FormatStyle::SpaceBeforeParensStyle &Value) {

721 IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);

722 IO.enumCase(Value, "ControlStatements",

723 FormatStyle::SBPO_ControlStatements);

724 IO.enumCase(Value, "ControlStatementsExceptControlMacros",

725 FormatStyle::SBPO_ControlStatementsExceptControlMacros);

726 IO.enumCase(Value, "NonEmptyParentheses",

727 FormatStyle::SBPO_NonEmptyParentheses);

728 IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);

729 IO.enumCase(Value, "Custom", FormatStyle::SBPO_Custom);

730

731

732 IO.enumCase(Value, "false", FormatStyle::SBPO_Never);

733 IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);

734 IO.enumCase(Value, "ControlStatementsExceptForEachMacros",

735 FormatStyle::SBPO_ControlStatementsExceptControlMacros);

736 }

737};

738

739template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInAnglesStyle> {

740 static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value) {

741 IO.enumCase(Value, "Never", FormatStyle::SIAS_Never);

742 IO.enumCase(Value, "Always", FormatStyle::SIAS_Always);

743 IO.enumCase(Value, "Leave", FormatStyle::SIAS_Leave);

744

745

746 IO.enumCase(Value, "false", FormatStyle::SIAS_Never);

747 IO.enumCase(Value, "true", FormatStyle::SIAS_Always);

748 }

749};

750

751template <> struct MappingTraits<FormatStyle::SpacesInLineComment> {

752 static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) {

753

754 int signedMaximum = static_cast<int>(Space.Maximum);

755 IO.mapOptional("Minimum", Space.Minimum);

756 IO.mapOptional("Maximum", signedMaximum);

757 Space.Maximum = static_cast<unsigned>(signedMaximum);

758

759 if (Space.Maximum != -1u)

760 Space.Minimum = std::min(Space.Minimum, Space.Maximum);

761 }

762};

763

764template <> struct MappingTraits<FormatStyle::SpacesInParensCustom> {

765 static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces) {

766 IO.mapOptional("ExceptDoubleParentheses", Spaces.ExceptDoubleParentheses);

767 IO.mapOptional("InCStyleCasts", Spaces.InCStyleCasts);

768 IO.mapOptional("InConditionalStatements", Spaces.InConditionalStatements);

769 IO.mapOptional("InEmptyParentheses", Spaces.InEmptyParentheses);

770 IO.mapOptional("Other", Spaces.Other);

771 }

772};

773

774template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInParensStyle> {

775 static void enumeration(IO &IO, FormatStyle::SpacesInParensStyle &Value) {

776 IO.enumCase(Value, "Never", FormatStyle::SIPO_Never);

777 IO.enumCase(Value, "Custom", FormatStyle::SIPO_Custom);

778 }

779};

780

781template <> struct ScalarEnumerationTraits<FormatStyle::TrailingCommaStyle> {

782 static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value) {

783 IO.enumCase(Value, "None", FormatStyle::TCS_None);

784 IO.enumCase(Value, "Wrapped", FormatStyle::TCS_Wrapped);

785 }

786};

787

788template <>

789struct ScalarEnumerationTraits<FormatStyle::TrailingCommentsAlignmentKinds> {

791 FormatStyle::TrailingCommentsAlignmentKinds &Value) {

792 IO.enumCase(Value, "Leave", FormatStyle::TCAS_Leave);

793 IO.enumCase(Value, "Always", FormatStyle::TCAS_Always);

794 IO.enumCase(Value, "Never", FormatStyle::TCAS_Never);

795 }

796};

797

798template <> struct MappingTraits<FormatStyle::TrailingCommentsAlignmentStyle> {

800 FormatStyle::TrailingCommentsAlignmentStyle &Value) {

801 IO.enumCase(Value, "Leave",

802 FormatStyle::TrailingCommentsAlignmentStyle(

803 {FormatStyle::TCAS_Leave, 0}));

804

805 IO.enumCase(Value, "Always",

806 FormatStyle::TrailingCommentsAlignmentStyle(

807 {FormatStyle::TCAS_Always, 0}));

808

809 IO.enumCase(Value, "Never",

810 FormatStyle::TrailingCommentsAlignmentStyle(

811 {FormatStyle::TCAS_Never, 0}));

812

813

814 IO.enumCase(Value, "true",

815 FormatStyle::TrailingCommentsAlignmentStyle(

816 {FormatStyle::TCAS_Always, 0}));

817 IO.enumCase(Value, "false",

818 FormatStyle::TrailingCommentsAlignmentStyle(

819 {FormatStyle::TCAS_Never, 0}));

820 }

821

823 FormatStyle::TrailingCommentsAlignmentStyle &Value) {

824 IO.mapOptional("Kind", Value.Kind);

825 IO.mapOptional("OverEmptyLines", Value.OverEmptyLines);

826 }

827};

828

829template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {

831 IO.enumCase(Value, "Never", FormatStyle::UT_Never);

832 IO.enumCase(Value, "false", FormatStyle::UT_Never);

833 IO.enumCase(Value, "Always", FormatStyle::UT_Always);

834 IO.enumCase(Value, "true", FormatStyle::UT_Always);

835 IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);

836 IO.enumCase(Value, "ForContinuationAndIndentation",

837 FormatStyle::UT_ForContinuationAndIndentation);

838 IO.enumCase(Value, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces);

839 }

840};

841

842template <>

843struct ScalarEnumerationTraits<

844 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle> {

845 static void

847 FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &Value) {

848 IO.enumCase(Value, "Never", FormatStyle::WNBWELS_Never);

849 IO.enumCase(Value, "Always", FormatStyle::WNBWELS_Always);

850 IO.enumCase(Value, "Leave", FormatStyle::WNBWELS_Leave);

851 }

852};

853

856

857 IO.mapOptional("Language", Style.Language);

858

859 StringRef BasedOnStyle;

860 if (IO.outputting()) {

861 StringRef Styles[] = {"LLVM", "Google", "Chromium", "Mozilla",

862 "WebKit", "GNU", "Microsoft", "clang-format"};

863 for (StringRef StyleName : Styles) {

865 if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&

866 Style == PredefinedStyle) {

867 BasedOnStyle = StyleName;

868 break;

869 }

870 }

871 } else {

872 IO.mapOptional("BasedOnStyle", BasedOnStyle);

873 if (!BasedOnStyle.empty()) {

874 FormatStyle::LanguageKind OldLanguage = Style.Language;

875 FormatStyle::LanguageKind Language =

876 ((FormatStyle *)IO.getContext())->Language;

877 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {

878 IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));

879 return;

880 }

881 Style.Language = OldLanguage;

882 }

883 }

884

885

886

887

888

889

890

891

892

893

894

895

896 const bool IsGoogleOrChromium = BasedOnStyle.equals_insensitive("google") ||

897 BasedOnStyle.equals_insensitive("chromium");

898 bool OnCurrentLine = IsGoogleOrChromium;

899 bool OnNextLine = true;

900

901 bool BreakBeforeInheritanceComma = false;

902 bool BreakConstructorInitializersBeforeComma = false;

903

904 bool DeriveLineEnding = true;

905 bool UseCRLF = false;

906

907 bool SpaceInEmptyParentheses = false;

908 bool SpacesInConditionalStatement = false;

909 bool SpacesInCStyleCastParentheses = false;

910 bool SpacesInParentheses = false;

911

912

913 if (!IO.outputting()) {

915 IO.mapOptional("AllowAllConstructorInitializersOnNextLine", OnNextLine);

917 IO.mapOptional("AlwaysBreakTemplateDeclarations",

919 IO.mapOptional("BreakBeforeInheritanceComma",

920 BreakBeforeInheritanceComma);

921 IO.mapOptional("BreakConstructorInitializersBeforeComma",

922 BreakConstructorInitializersBeforeComma);

923 IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",

924 OnCurrentLine);

925 IO.mapOptional("DeriveLineEnding", DeriveLineEnding);

928 IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",

930 IO.mapOptional("IndentFunctionDeclarationAfterType",

933 IO.mapOptional("PointerBindsToType", Style.PointerAlignment);

934 IO.mapOptional("SpaceAfterControlStatementKeyword",

936 IO.mapOptional("SpaceInEmptyParentheses", SpaceInEmptyParentheses);

937 IO.mapOptional("SpacesInConditionalStatement",

938 SpacesInConditionalStatement);

939 IO.mapOptional("SpacesInCStyleCastParentheses",

940 SpacesInCStyleCastParentheses);

941 IO.mapOptional("SpacesInParentheses", SpacesInParentheses);

942 IO.mapOptional("UseCRLF", UseCRLF);

943 }

944

948 IO.mapOptional("AlignConsecutiveAssignments",

950 IO.mapOptional("AlignConsecutiveBitFields",

952 IO.mapOptional("AlignConsecutiveDeclarations",

955 IO.mapOptional("AlignConsecutiveShortCaseStatements",

957 IO.mapOptional("AlignConsecutiveTableGenBreakingDAGArgColons",

959 IO.mapOptional("AlignConsecutiveTableGenCondOperatorColons",

961 IO.mapOptional("AlignConsecutiveTableGenDefinitionColons",

964 IO.mapOptional("AlignOperands", Style.AlignOperands);

966 IO.mapOptional("AllowAllArgumentsOnNextLine",

968 IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",

970 IO.mapOptional("AllowBreakBeforeNoexceptSpecifier",

972 IO.mapOptional("AllowShortBlocksOnASingleLine",

974 IO.mapOptional("AllowShortCaseExpressionOnASingleLine",

976 IO.mapOptional("AllowShortCaseLabelsOnASingleLine",

978 IO.mapOptional("AllowShortCompoundRequirementOnASingleLine",

980 IO.mapOptional("AllowShortEnumsOnASingleLine",

982 IO.mapOptional("AllowShortFunctionsOnASingleLine",

984 IO.mapOptional("AllowShortIfStatementsOnASingleLine",

986 IO.mapOptional("AllowShortLambdasOnASingleLine",

988 IO.mapOptional("AllowShortLoopsOnASingleLine",

990 IO.mapOptional("AllowShortNamespacesOnASingleLine",

992 IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",

994 IO.mapOptional("AlwaysBreakBeforeMultilineStrings",

996 IO.mapOptional("AttributeMacros", Style.AttributeMacros);

1000 IO.mapOptional("BracedInitializerIndentWidth",

1002 IO.mapOptional("BraceWrapping", Style.BraceWrapping);

1003 IO.mapOptional("BreakAdjacentStringLiterals",

1006 IO.mapOptional("BreakAfterJavaFieldAnnotations",

1009 IO.mapOptional("BreakArrays", Style.BreakArrays);

1010 IO.mapOptional("BreakBeforeBinaryOperators",

1012 IO.mapOptional("BreakBeforeConceptDeclarations",

1015 IO.mapOptional("BreakBeforeInlineASMColon",

1017 IO.mapOptional("BreakBeforeTernaryOperators",

1020 IO.mapOptional("BreakConstructorInitializers",

1022 IO.mapOptional("BreakFunctionDefinitionParameters",

1026 IO.mapOptional("BreakTemplateDeclarations",

1028 IO.mapOptional("ColumnLimit", Style.ColumnLimit);

1029 IO.mapOptional("CommentPragmas", Style.CommentPragmas);

1031 IO.mapOptional("ConstructorInitializerIndentWidth",

1036 IO.mapOptional("DisableFormat", Style.DisableFormat);

1037 IO.mapOptional("EmptyLineAfterAccessModifier",

1039 IO.mapOptional("EmptyLineBeforeAccessModifier",

1041 IO.mapOptional("ExperimentalAutoDetectBinPacking",

1044 IO.mapOptional("ForEachMacros", Style.ForEachMacros);

1045 IO.mapOptional("IfMacros", Style.IfMacros);

1049 IO.mapOptional("IncludeIsMainSourceRegex",

1059 IO.mapOptional("IndentWidth", Style.IndentWidth);

1060 IO.mapOptional("IndentWrappedFunctionNames",

1062 IO.mapOptional("InsertBraces", Style.InsertBraces);

1069 IO.mapOptional("KeepEmptyLines", Style.KeepEmptyLines);

1070 IO.mapOptional("KeepFormFeed", Style.KeepFormFeed);

1072 IO.mapOptional("LineEnding", Style.LineEnding);

1073 IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin);

1074 IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd);

1075 IO.mapOptional("Macros", Style.Macros);

1079 IO.mapOptional("NamespaceMacros", Style.NamespaceMacros);

1082 IO.mapOptional("ObjCBreakBeforeNestedBlockParam",

1084 IO.mapOptional("ObjCPropertyAttributeOrder",

1087 IO.mapOptional("ObjCSpaceBeforeProtocolList",

1089 IO.mapOptional("PackConstructorInitializers",

1092 IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",

1095 IO.mapOptional("PenaltyBreakFirstLessLess",

1097 IO.mapOptional("PenaltyBreakOpenParenthesis",

1099 IO.mapOptional("PenaltyBreakScopeResolution",

1102 IO.mapOptional("PenaltyBreakTemplateDeclaration",

1105 IO.mapOptional("PenaltyIndentedWhitespace",

1107 IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",

1110 IO.mapOptional("PPIndentWidth", Style.PPIndentWidth);

1112

1114 Style.QualifierOrder = {"type", "const", "volatile"};

1116 Style.QualifierOrder = {"const", "volatile", "type"};

1118 IO.mapOptional("QualifierOrder", Style.QualifierOrder);

1121 IO.mapOptional("ReflowComments", Style.ReflowComments);

1123 IO.mapOptional("RemoveEmptyLinesInUnwrappedLines",

1126 IO.mapOptional("RemoveSemicolon", Style.RemoveSemicolon);

1128 IO.mapOptional("RequiresExpressionIndentation",

1133 IO.mapOptional("SortIncludes", Style.SortIncludes);

1138 IO.mapOptional("SpaceAfterTemplateKeyword",

1140 IO.mapOptional("SpaceAroundPointerQualifiers",

1142 IO.mapOptional("SpaceBeforeAssignmentOperators",

1145 IO.mapOptional("SpaceBeforeCpp11BracedList",

1147 IO.mapOptional("SpaceBeforeCtorInitializerColon",

1149 IO.mapOptional("SpaceBeforeInheritanceColon",

1154 IO.mapOptional("SpaceBeforeRangeBasedForLoopColon",

1156 IO.mapOptional("SpaceBeforeSquareBrackets",

1159 IO.mapOptional("SpacesBeforeTrailingComments",

1161 IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);

1162 IO.mapOptional("SpacesInContainerLiterals",

1164 IO.mapOptional("SpacesInLineCommentPrefix",

1166 IO.mapOptional("SpacesInParens", Style.SpacesInParens);

1169 IO.mapOptional("Standard", Style.Standard);

1170 IO.mapOptional("StatementAttributeLikeMacros",

1172 IO.mapOptional("StatementMacros", Style.StatementMacros);

1173 IO.mapOptional("TableGenBreakingDAGArgOperators",

1175 IO.mapOptional("TableGenBreakInsideDAGArg",

1177 IO.mapOptional("TabWidth", Style.TabWidth);

1178 IO.mapOptional("TemplateNames", Style.TemplateNames);

1179 IO.mapOptional("TypeNames", Style.TypeNames);

1180 IO.mapOptional("TypenameMacros", Style.TypenameMacros);

1181 IO.mapOptional("UseTab", Style.UseTab);

1183 IO.mapOptional("VerilogBreakBetweenInstancePorts",

1185 IO.mapOptional("WhitespaceSensitiveMacros",

1187 IO.mapOptional("WrapNamespaceBodyWithEmptyLines",

1189

1190

1191

1192

1196 FormatStyle::DRTBS_All) {

1199 FormatStyle::DRTBS_TopLevel) {

1201 }

1202 }

1203

1204

1205

1206 if (BreakBeforeInheritanceComma &&

1209 }

1210

1211

1212

1213

1214 if (BreakConstructorInitializersBeforeComma &&

1217 }

1218

1219 if (!IsGoogleOrChromium) {

1221 OnCurrentLine) {

1223 ? FormatStyle::PCIS_NextLine

1224 : FormatStyle::PCIS_CurrentLine;

1225 }

1227 FormatStyle::PCIS_NextLine) {

1228 if (!OnCurrentLine)

1230 else if (!OnNextLine)

1232 }

1233

1234 if (Style.LineEnding == FormatStyle::LE_DeriveLF) {

1235 if (!DeriveLineEnding)

1236 Style.LineEnding = UseCRLF ? FormatStyle::LE_CRLF : FormatStyle::LE_LF;

1237 else if (UseCRLF)

1238 Style.LineEnding = FormatStyle::LE_DeriveCRLF;

1239 }

1240

1241 if (Style.SpacesInParens != FormatStyle::SIPO_Custom &&

1242 (SpacesInParentheses || SpaceInEmptyParentheses ||

1243 SpacesInConditionalStatement || SpacesInCStyleCastParentheses)) {

1244 if (SpacesInParentheses) {

1245

1249 SpacesInCStyleCastParentheses;

1251 SpaceInEmptyParentheses;

1253 } else {

1256 SpacesInConditionalStatement;

1258 SpacesInCStyleCastParentheses;

1260 SpaceInEmptyParentheses;

1261 }

1263 }

1264 }

1265};

1266

1267

1268

1269

1270

1271

1272template <> struct DocumentListTraits<std::vector> {

1273 static size_t size(IO &IO, std::vector &Seq) {

1274 return Seq.size();

1275 }

1277 size_t Index) {

1278 if (Index >= Seq.size()) {

1279 assert(Index == Seq.size());

1281 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {

1282 Template = Seq[0];

1283 } else {

1284 Template = *((const FormatStyle *)IO.getContext());

1285 Template.Language = FormatStyle::LK_None;

1286 }

1287 Seq.resize(Index + 1, Template);

1288 }

1289 return Seq[Index];

1290 }

1291};

1292}

1293}

1294

1295namespace clang {

1296namespace format {

1297

1300 return C;

1301}

1303 return std::error_code(static_cast<int>(e), getParseCategory());

1304}

1305

1307 return llvm::make_errorllvm::StringError(Message,

1308 llvm::inconvertibleErrorCode());

1309}

1310

1312 return "clang-format.parse_error";

1313}

1314

1316 switch (static_cast<ParseError>(EV)) {

1318 return "Success";

1320 return "Invalid argument";

1322 return "Unsuitable";

1324 return "trailing comma insertion cannot be used with bin packing";

1326 return "Invalid qualifier specified in QualifierOrder";

1328 return "Duplicate qualifier specified in QualifierOrder";

1330 return "Missing type in QualifierOrder";

1332 return "Missing QualifierOrder";

1333 }

1334 llvm_unreachable("unexpected parse error");

1335}

1336

1339 return;

1340 Expanded.BraceWrapping = {false,

1341 false,

1343 false,

1344 false,

1345 false,

1346 false,

1347 false,

1348 false,

1349 false,

1350 false,

1351 false,

1352 false,

1353 false,

1354 false,

1355 true,

1356 true,

1357 true};

1363 break;

1373 break;

1378 break;

1393 break;

1407 break;

1410 true,

1411 true,

1413 true,

1414 true,

1415 true,

1416 true,

1417 true,

1418 true,

1419 true,

1420 true,

1421 true,

1422 false,

1423 true,

1424 true,

1425 true,

1426 true,

1427 true};

1428 break;

1431 break;

1432 default:

1433 break;

1434 }

1435}

1436

1439 return;

1440

1443

1449 break;

1452 break;

1455 break;

1456 default:

1457 break;

1458 }

1459}

1460

1463 return;

1465

1467}

1468

1509 LLVMStyle.BraceWrapping = {false,

1510 false,

1512 false,

1513 false,

1514 false,

1515 false,

1516 false,

1517 false,

1518 false,

1519 false,

1520 false,

1521 false,

1522 false,

1523 false,

1524 true,

1525 true,

1526 true};

1557 LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");

1558 LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE");

1561 {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},

1562 {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},

1563 {".*", 1, 0, false}};

1581 0, 0,

1582 0, 0,

1583 0, 0};

1587 false,

1588 true,

1589 true,

1590 };

1647 LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");

1659

1671

1672

1676 break;

1679 break;

1683 break;

1684 default:

1685 break;

1686 }

1687

1688 return LLVMStyle;

1689}

1690

1695

1696 return GoogleStyle;

1697 }

1698

1700

1711 {"^<.*\\.h>", 1, 0, false},

1712 {"^<.*", 2, 0, false},

1713 {".*", 3, 0, false}};

1723 {

1725

1726 {

1727 "cc",

1728 "CC",

1729 "cpp",

1730 "Cpp",

1731 "CPP",

1732 "c++",

1733 "C++",

1734 },

1735

1736 {},

1737 "",

1738 "google",

1739 },

1740 {

1742

1743 {

1744 "pb",

1745 "PB",

1746 "proto",

1747 "PROTO",

1748 },

1749

1750 {

1751 "EqualsProto",

1752 "EquivToProto",

1753 "PARSE_PARTIAL_TEXT_PROTO",

1754 "PARSE_TEST_PROTO",

1755 "PARSE_TEXT_PROTO",

1756 "ParseTextOrDie",

1757 "ParseTextProtoOrDie",

1758 "ParseTestProto",

1759 "ParsePartialTestProto",

1760 },

1761 "pb",

1762 "google",

1763 },

1764 };

1765

1768

1771

1788

1792

1793

1794 GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)";

1795

1796

1797

1806

1807

1808

1809

1810

1817

1818

1819

1828 }

1829

1830 return GoogleStyle;

1831}

1832

1835

1836

1837

1838

1839

1840

1841

1842

1843

1844

1845

1846

1847

1848

1849

1850

1851

1852

1855

1862

1863

1865 "android",

1866 "androidx",

1867 "com",

1868 "dalvik",

1869 "junit",

1870 "org",

1871 "com.google.android.apps.chrome",

1872 "org.chromium",

1873 "java",

1874 "javax",

1875 };

1880 } else {

1889 }

1890 return ChromiumStyle;

1891}

1892

1916 return MozillaStyle;

1917}

1918

1940 return Style;

1941}

1942

1955 return Style;

1956}

1957

1984 return Style;

1985}

1986

1998 return Style;

1999}

2000

2006 return NoStyle;

2007}

2008

2011 if (Name.equals_insensitive("llvm"))

2013 else if (Name.equals_insensitive("chromium"))

2015 else if (Name.equals_insensitive("mozilla"))

2017 else if (Name.equals_insensitive("google"))

2019 else if (Name.equals_insensitive("webkit"))

2021 else if (Name.equals_insensitive("gnu"))

2023 else if (Name.equals_insensitive("microsoft"))

2025 else if (Name.equals_insensitive("clang-format"))

2027 else if (Name.equals_insensitive("none"))

2029 else if (Name.equals_insensitive("inheritparentconfig"))

2031 else

2032 return false;

2033

2035 return true;

2036}

2037

2039

2042

2043

2044 for (const auto &Qualifier : Style->QualifierOrder) {

2045 if (Qualifier == "type")

2046 continue;

2047 auto token =

2049 if (token == tok::identifier)

2051 }

2052

2053

2054 std::setstd::string UniqueQualifiers(Style->QualifierOrder.begin(),

2056 if (Style->QualifierOrder.size() != UniqueQualifiers.size()) {

2057 LLVM_DEBUG(llvm::dbgs()

2058 << "Duplicate Qualifiers " << Style->QualifierOrder.size()

2059 << " vs " << UniqueQualifiers.size() << "\n");

2061 }

2062

2063

2064 if (!llvm::is_contained(Style->QualifierOrder, "type"))

2066

2068}

2069

2071 FormatStyle *Style, bool AllowUnknownOptions,

2072 llvm::SourceMgr::DiagHandlerTy DiagHandler,

2073 void *DiagHandlerCtxt) {

2074 assert(Style);

2077 if (Config.getBuffer().trim().empty())

2079 Style->StyleSet.Clear();

2080 std::vector Styles;

2081 llvm::yaml::Input Input(Config, nullptr, DiagHandler,

2082 DiagHandlerCtxt);

2083

2084

2085

2086

2087 Input.setContext(Style);

2088 Input.setAllowUnknownKeys(AllowUnknownOptions);

2089 Input >> Styles;

2090 if (Input.error())

2091 return Input.error();

2092

2093 for (unsigned i = 0; i < Styles.size(); ++i) {

2094

2097

2098 for (unsigned j = 0; j < i; ++j) {

2100 LLVM_DEBUG(llvm::dbgs()

2101 << "Duplicate languages in the config file on positions "

2102 << j << " and " << i << "\n");

2104 }

2105 }

2106 }

2107

2108

2109

2111 bool LanguageFound = false;

2112 for (const FormatStyle &Style : llvm::reverse(Styles)) {

2114 StyleSet.Add(Style);

2116 LanguageFound = true;

2117 }

2118 if (!LanguageFound) {

2123 StyleSet.Add(std::move(DefaultStyle));

2124 }

2128

2130 }

2134}

2135

2137 std::string Text;

2138 llvm::raw_string_ostream Stream(Text);

2139 llvm::yaml::Output Output(Stream);

2140

2141

2146 Output << NonConstStyle;

2147

2148 return Stream.str();

2149}

2150

2151std::optional

2153 if (!Styles)

2154 return std::nullopt;

2155 auto It = Styles->find(Language);

2156 if (It == Styles->end())

2157 return std::nullopt;

2159 Style.StyleSet = *this;

2160 return Style;

2161}

2162

2165 "Cannot add a style for LK_None to a StyleSet");

2166 assert(

2167 !Style.StyleSet.Styles &&

2168 "Cannot add a style associated with an existing StyleSet to a StyleSet");

2169 if (!Styles)

2170 Styles = std::make_shared();

2171 (*Styles)[Style.Language] = std::move(Style);

2172}

2173

2175

2176std::optional

2179}

2180

2181namespace {

2182

2184public:

2187

2188 std::pair<tooling::Replacements, unsigned>

2189 analyze(TokenAnnotator &Annotator,

2191 FormatTokenLexer &Tokens) override {

2192 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);

2194 removeParens(AnnotatedLines, Result);

2195 return {Result, 0};

2196 }

2197

2198private:

2199 void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,

2200 tooling::Replacements &Result) {

2201 const auto &SourceMgr = Env.getSourceManager();

2202 for (auto *Line : Lines) {

2203 if (!Line->Children.empty())

2204 removeParens(Line->Children, Result);

2205 if (!Line->Affected)

2206 continue;

2207 for (const auto *Token = Line->First; Token && !Token->Finalized;

2208 Token = Token->Next) {

2209 if (!Token->Optional || !Token->isOneOf(tok::l_paren, tok::r_paren))

2210 continue;

2211 auto *Next = Token->Next;

2212 assert(Next && Next->isNot(tok::eof));

2213 SourceLocation Start;

2214 if (Next->NewlinesBefore == 0) {

2215 Start = Token->Tok.getLocation();

2216 Next->WhitespaceRange = Token->WhitespaceRange;

2217 } else {

2218 Start = Token->WhitespaceRange.getBegin();

2219 }

2220 const auto &Range =

2221 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());

2222 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, " ")));

2223 }

2224 }

2225 }

2226};

2227

2228class BracesInserter : public TokenAnalyzer {

2229public:

2230 BracesInserter(const Environment &Env, const FormatStyle &Style)

2231 : TokenAnalyzer(Env, Style) {}

2232

2233 std::pair<tooling::Replacements, unsigned>

2234 analyze(TokenAnnotator &Annotator,

2235 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2236 FormatTokenLexer &Tokens) override {

2237 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);

2238 tooling::Replacements Result;

2239 insertBraces(AnnotatedLines, Result);

2240 return {Result, 0};

2241 }

2242

2243private:

2244 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,

2245 tooling::Replacements &Result) {

2246 const auto &SourceMgr = Env.getSourceManager();

2247 int OpeningBraceSurplus = 0;

2248 for (AnnotatedLine *Line : Lines) {

2249 if (!Line->Children.empty())

2250 insertBraces(Line->Children, Result);

2251 if (!Line->Affected && OpeningBraceSurplus == 0)

2252 continue;

2253 for (FormatToken *Token = Line->First; Token && !Token->Finalized;

2254 Token = Token->Next) {

2255 int BraceCount = Token->BraceCount;

2256 if (BraceCount == 0)

2257 continue;

2258 std::string Brace;

2259 if (BraceCount < 0) {

2260 assert(BraceCount == -1);

2261 if (!Line->Affected)

2262 break;

2263 Brace = Token->is(tok::comment) ? "\n{" : "{";

2264 ++OpeningBraceSurplus;

2265 } else {

2266 if (OpeningBraceSurplus == 0)

2267 break;

2268 if (OpeningBraceSurplus < BraceCount)

2269 BraceCount = OpeningBraceSurplus;

2270 Brace = '\n' + std::string(BraceCount, '}');

2271 OpeningBraceSurplus -= BraceCount;

2272 }

2273 Token->BraceCount = 0;

2274 const auto Start = Token->Tok.getEndLoc();

2275 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0, Brace)));

2276 }

2277 }

2278 assert(OpeningBraceSurplus == 0);

2279 }

2280};

2281

2282class BracesRemover : public TokenAnalyzer {

2283public:

2284 BracesRemover(const Environment &Env, const FormatStyle &Style)

2285 : TokenAnalyzer(Env, Style) {}

2286

2287 std::pair<tooling::Replacements, unsigned>

2288 analyze(TokenAnnotator &Annotator,

2289 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2290 FormatTokenLexer &Tokens) override {

2291 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);

2292 tooling::Replacements Result;

2293 removeBraces(AnnotatedLines, Result);

2294 return {Result, 0};

2295 }

2296

2297private:

2298 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,

2299 tooling::Replacements &Result) {

2300 const auto &SourceMgr = Env.getSourceManager();

2301 const auto *End = Lines.end();

2302 for (const auto *I = Lines.begin(); I != End; ++I) {

2303 const auto &Line = *I;

2304 if (!Line->Children.empty())

2305 removeBraces(Line->Children, Result);

2306 if (!Line->Affected)

2307 continue;

2308 const auto *NextLine = I + 1 == End ? nullptr : I[1];

2309 for (const auto *Token = Line->First; Token && !Token->Finalized;

2310 Token = Token->Next) {

2311 if (!Token->Optional)

2312 continue;

2313 if (!Token->isOneOf(tok::l_brace, tok::r_brace))

2314 continue;

2315 auto *Next = Token->Next;

2316 assert(Next || Token == Line->Last);

2317 if (!Next && NextLine)

2318 Next = NextLine->First;

2319 SourceLocation Start;

2320 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {

2321 Start = Token->Tok.getLocation();

2322 Next->WhitespaceRange = Token->WhitespaceRange;

2323 } else {

2324 Start = Token->WhitespaceRange.getBegin();

2325 }

2326 const auto &Range =

2327 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());

2328 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));

2329 }

2330 }

2331 }

2332};

2333

2334class SemiRemover : public TokenAnalyzer {

2335public:

2336 SemiRemover(const Environment &Env, const FormatStyle &Style)

2337 : TokenAnalyzer(Env, Style) {}

2338

2339 std::pair<tooling::Replacements, unsigned>

2340 analyze(TokenAnnotator &Annotator,

2341 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2342 FormatTokenLexer &Tokens) override {

2343 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);

2344 tooling::Replacements Result;

2345 removeSemi(Annotator, AnnotatedLines, Result);

2346 return {Result, 0};

2347 }

2348

2349private:

2350 void removeSemi(TokenAnnotator &Annotator,

2351 SmallVectorImpl<AnnotatedLine *> &Lines,

2352 tooling::Replacements &Result) {

2353 auto PrecededByFunctionRBrace = [](const FormatToken &Tok) {

2354 const auto *Prev = Tok.Previous;

2355 if (!Prev || Prev->isNot(tok::r_brace))

2356 return false;

2357 const auto *LBrace = Prev->MatchingParen;

2358 return LBrace && LBrace->is(TT_FunctionLBrace);

2359 };

2360 const auto &SourceMgr = Env.getSourceManager();

2361 const auto *End = Lines.end();

2362 for (const auto *I = Lines.begin(); I != End; ++I) {

2363 const auto &Line = *I;

2364 if (!Line->Children.empty())

2365 removeSemi(Annotator, Line->Children, Result);

2366 if (!Line->Affected)

2367 continue;

2368 Annotator.calculateFormattingInformation(*Line);

2369 const auto *NextLine = I + 1 == End ? nullptr : I[1];

2370 for (const auto *Token = Line->First; Token && !Token->Finalized;

2371 Token = Token->Next) {

2372 if (Token->isNot(tok::semi) ||

2373 (!Token->Optional && !PrecededByFunctionRBrace(*Token))) {

2374 continue;

2375 }

2376 auto *Next = Token->Next;

2377 assert(Next || Token == Line->Last);

2378 if (!Next && NextLine)

2379 Next = NextLine->First;

2380 SourceLocation Start;

2381 if (Next && Next->NewlinesBefore == 0 && Next->isNot(tok::eof)) {

2382 Start = Token->Tok.getLocation();

2383 Next->WhitespaceRange = Token->WhitespaceRange;

2384 } else {

2385 Start = Token->WhitespaceRange.getBegin();

2386 }

2387 const auto &Range =

2388 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc());

2389 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, "")));

2390 }

2391 }

2392 }

2393};

2394

2395class JavaScriptRequoter : public TokenAnalyzer {

2396public:

2397 JavaScriptRequoter(const Environment &Env, const FormatStyle &Style)

2398 : TokenAnalyzer(Env, Style) {}

2399

2400 std::pair<tooling::Replacements, unsigned>

2401 analyze(TokenAnnotator &Annotator,

2402 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2403 FormatTokenLexer &Tokens) override {

2404 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);

2405 tooling::Replacements Result;

2406 requoteJSStringLiteral(AnnotatedLines, Result);

2407 return {Result, 0};

2408 }

2409

2410private:

2411

2412

2413 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,

2414 tooling::Replacements &Result) {

2415 for (AnnotatedLine *Line : Lines) {

2416 requoteJSStringLiteral(Line->Children, Result);

2417 if (!Line->Affected)

2418 continue;

2419 for (FormatToken *FormatTok = Line->First; FormatTok;

2420 FormatTok = FormatTok->Next) {

2421 StringRef Input = FormatTok->TokenText;

2422 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||

2423

2424

2426 !Input.starts_with("\"")) ||

2428 !Input.starts_with("\'"))) {

2429 continue;

2430 }

2431

2432

2433 bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single;

2434 SourceLocation Start = FormatTok->Tok.getLocation();

2435 auto Replace = [&](SourceLocation Start, unsigned Length,

2436 StringRef ReplacementText) {

2437 auto Err = Result.add(tooling::Replacement(

2438 Env.getSourceManager(), Start, Length, ReplacementText));

2439

2440

2441 if (Err) {

2442 llvm::errs() << toString(std::move(Err)) << "\n";

2443 assert(false);

2444 }

2445 };

2446 Replace(Start, 1, IsSingle ? "'" : "\"");

2447 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,

2448 IsSingle ? "'" : "\"");

2449

2450

2451 bool Escaped = false;

2452 for (size_t i = 1; i < Input.size() - 1; i++) {

2453 switch (Input[i]) {

2454 case '\\':

2455 if (!Escaped && i + 1 < Input.size() &&

2456 ((IsSingle && Input[i + 1] == '"') ||

2457 (!IsSingle && Input[i + 1] == '\''))) {

2458

2459

2460 Replace(Start.getLocWithOffset(i), 1, "");

2461 continue;

2462 }

2463 Escaped = !Escaped;

2464 break;

2465 case '\"':

2466 case '\'':

2467 if (!Escaped && IsSingle == (Input[i] == '\'')) {

2468

2469 Replace(Start.getLocWithOffset(i), 0, "\\");

2470 }

2471 Escaped = false;

2472 break;

2473 default:

2474 Escaped = false;

2475 break;

2476 }

2477 }

2478 }

2479 }

2480 }

2481};

2482

2483class Formatter : public TokenAnalyzer {

2484public:

2485 Formatter(const Environment &Env, const FormatStyle &Style,

2486 FormattingAttemptStatus *Status)

2487 : TokenAnalyzer(Env, Style), Status(Status) {}

2488

2489 std::pair<tooling::Replacements, unsigned>

2490 analyze(TokenAnnotator &Annotator,

2491 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2492 FormatTokenLexer &Tokens) override {

2493 tooling::Replacements Result;

2494 deriveLocalStyle(AnnotatedLines);

2495 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);

2496 for (AnnotatedLine *Line : AnnotatedLines)

2497 Annotator.calculateFormattingInformation(*Line);

2498 Annotator.setCommentLineLevels(AnnotatedLines);

2499

2500 WhitespaceManager Whitespaces(

2501 Env.getSourceManager(), Style,

2502 Style.LineEnding > FormatStyle::LE_CRLF

2503 ? WhitespaceManager::inputUsesCRLF(

2504 Env.getSourceManager().getBufferData(Env.getFileID()),

2505 Style.LineEnding == FormatStyle::LE_DeriveCRLF)

2506 : Style.LineEnding == FormatStyle::LE_CRLF);

2507 ContinuationIndenter Indenter(Style, Tokens.getKeywords(),

2508 Env.getSourceManager(), Whitespaces, Encoding,

2509 BinPackInconclusiveFunctions);

2510 unsigned Penalty =

2511 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style,

2512 Tokens.getKeywords(), Env.getSourceManager(),

2513 Status)

2514 .format(AnnotatedLines, false,

2515 0,

2516 false,

2517 Env.getFirstStartColumn(),

2518 Env.getNextStartColumn(),

2519 Env.getLastStartColumn());

2520 for (const auto &R : Whitespaces.generateReplacements())

2521 if (Result.add(R))

2522 return std::make_pair(Result, 0);

2523 return std::make_pair(Result, Penalty);

2524 }

2525

2526private:

2527 bool

2528 hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {

2529 for (const AnnotatedLine *Line : Lines) {

2530 if (hasCpp03IncompatibleFormat(Line->Children))

2531 return true;

2532 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) {

2533 if (!Tok->hasWhitespaceBefore()) {

2534 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener))

2535 return true;

2536 if (Tok->is(TT_TemplateCloser) &&

2537 Tok->Previous->is(TT_TemplateCloser)) {

2538 return true;

2539 }

2540 }

2541 }

2542 }

2543 return false;

2544 }

2545

2546 int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {

2547 int AlignmentDiff = 0;

2548 for (const AnnotatedLine *Line : Lines) {

2549 AlignmentDiff += countVariableAlignments(Line->Children);

2550 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) {

2551 if (Tok->isNot(TT_PointerOrReference))

2552 continue;

2553

2554 if (const auto *Prev = Tok->getPreviousNonComment()) {

2555 if (Prev->is(tok::r_paren) && Prev->MatchingParen) {

2556 if (const auto *Func =

2557 Prev->MatchingParen->getPreviousNonComment()) {

2558 if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName,

2559 TT_OverloadedOperator)) {

2560 continue;

2561 }

2562 }

2563 }

2564 }

2565 bool SpaceBefore = Tok->hasWhitespaceBefore();

2566 bool SpaceAfter = Tok->Next->hasWhitespaceBefore();

2567 if (SpaceBefore && !SpaceAfter)

2568 ++AlignmentDiff;

2569 if (!SpaceBefore && SpaceAfter)

2570 --AlignmentDiff;

2571 }

2572 }

2573 return AlignmentDiff;

2574 }

2575

2576 void

2577 deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {

2578 bool HasBinPackedFunction = false;

2579 bool HasOnePerLineFunction = false;

2580 for (AnnotatedLine *Line : AnnotatedLines) {

2581 if (!Line->First->Next)

2582 continue;

2583 FormatToken *Tok = Line->First->Next;

2584 while (Tok->Next) {

2585 if (Tok->is(PPK_BinPacked))

2586 HasBinPackedFunction = true;

2587 if (Tok->is(PPK_OnePerLine))

2588 HasOnePerLineFunction = true;

2589

2590 Tok = Tok->Next;

2591 }

2592 }

2594 const auto NetRightCount = countVariableAlignments(AnnotatedLines);

2595 if (NetRightCount > 0)

2597 else if (NetRightCount < 0)

2600 }

2601 if (Style.Standard == FormatStyle::LS_Auto) {

2602 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines)

2603 ? FormatStyle::LS_Latest

2604 : FormatStyle::LS_Cpp03;

2605 }

2606 BinPackInconclusiveFunctions =

2607 HasBinPackedFunction || !HasOnePerLineFunction;

2608 }

2609

2610 bool BinPackInconclusiveFunctions;

2611 FormattingAttemptStatus *Status;

2612};

2613

2614

2615

2616

2617

2618

2619

2620

2621

2622

2623

2624

2625class TrailingCommaInserter : public TokenAnalyzer {

2626public:

2627 TrailingCommaInserter(const Environment &Env, const FormatStyle &Style)

2628 : TokenAnalyzer(Env, Style) {}

2629

2630 std::pair<tooling::Replacements, unsigned>

2631 analyze(TokenAnnotator &Annotator,

2632 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2633 FormatTokenLexer &Tokens) override {

2634 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);

2635 tooling::Replacements Result;

2636 insertTrailingCommas(AnnotatedLines, Result);

2637 return {Result, 0};

2638 }

2639

2640private:

2641

2642

2643 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,

2644 tooling::Replacements &Result) {

2645 for (AnnotatedLine *Line : Lines) {

2646 insertTrailingCommas(Line->Children, Result);

2647 if (!Line->Affected)

2648 continue;

2649 for (FormatToken *FormatTok = Line->First; FormatTok;

2650 FormatTok = FormatTok->Next) {

2651 if (FormatTok->NewlinesBefore == 0)

2652 continue;

2653 FormatToken *Matching = FormatTok->MatchingParen;

2654 if (!Matching || !FormatTok->getPreviousNonComment())

2655 continue;

2656 if (!(FormatTok->is(tok::r_square) &&

2657 Matching->is(TT_ArrayInitializerLSquare)) &&

2658 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) {

2659 continue;

2660 }

2661 FormatToken *Prev = FormatTok->getPreviousNonComment();

2662 if (Prev->is(tok::comma) || Prev->is(tok::semi))

2663 continue;

2664

2665

2666 SourceLocation Start =

2667 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size());

2668

2669

2670

2671 unsigned ColumnNumber =

2672 Env.getSourceManager().getSpellingColumnNumber(Start);

2674 continue;

2675

2676

2677 cantFail(Result.add(

2678 tooling::Replacement(Env.getSourceManager(), Start, 0, ",")));

2679 }

2680 }

2681 }

2682};

2683

2684

2685

2686class Cleaner : public TokenAnalyzer {

2687public:

2688 Cleaner(const Environment &Env, const FormatStyle &Style)

2689 : TokenAnalyzer(Env, Style),

2690 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {}

2691

2692

2693 std::pair<tooling::Replacements, unsigned>

2694 analyze(TokenAnnotator &Annotator,

2695 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2696 FormatTokenLexer &Tokens) override {

2697

2698

2699

2700

2701

2702

2703

2704 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);

2705

2706 checkEmptyNamespace(AnnotatedLines);

2707

2708 for (auto *Line : AnnotatedLines)

2709 cleanupLine(Line);

2710

2711 return {generateFixes(), 0};

2712 }

2713

2714private:

2715 void cleanupLine(AnnotatedLine *Line) {

2716 for (auto *Child : Line->Children)

2717 cleanupLine(Child);

2718

2719 if (Line->Affected) {

2720 cleanupRight(Line->First, tok::comma, tok::comma);

2721 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);

2722 cleanupRight(Line->First, tok::l_paren, tok::comma);

2723 cleanupLeft(Line->First, tok::comma, tok::r_paren);

2724 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);

2725 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);

2726 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);

2727 }

2728 }

2729

2730 bool containsOnlyComments(const AnnotatedLine &Line) {

2731 for (FormatToken *Tok = Line.First; Tok; Tok = Tok->Next)

2732 if (Tok->isNot(tok::comment))

2733 return false;

2734 return true;

2735 }

2736

2737

2738 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {

2739 std::set DeletedLines;

2740 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {

2741 auto &Line = *AnnotatedLines[i];

2742 if (Line.startsWithNamespace())

2743 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);

2744 }

2745

2746 for (auto Line : DeletedLines) {

2747 FormatToken *Tok = AnnotatedLines[Line]->First;

2748 while (Tok) {

2749 deleteToken(Tok);

2750 Tok = Tok->Next;

2751 }

2752 }

2753 }

2754

2755

2756

2757

2758

2759 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2760 unsigned CurrentLine, unsigned &NewLine,

2761 std::set &DeletedLines) {

2762 unsigned InitLine = CurrentLine, End = AnnotatedLines.size();

2764

2765

2766

2767 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {

2769 return false;

2770 }

2771 } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {

2772 return false;

2773 }

2774 while (++CurrentLine < End) {

2775 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))

2776 break;

2777

2778 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {

2779 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,

2780 DeletedLines)) {

2781 return false;

2782 }

2784 continue;

2785 }

2786

2787 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))

2788 continue;

2789

2790

2791

2793 return false;

2794 }

2795

2797 if (CurrentLine >= End)

2798 return false;

2799

2800

2801 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(

2802 AnnotatedLines[InitLine]->First->Tok.getLocation(),

2803 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) {

2804 return false;

2805 }

2806

2807 for (unsigned i = InitLine; i <= CurrentLine; ++i)

2808 DeletedLines.insert(i);

2809

2810 return true;

2811 }

2812

2813

2814

2815

2816

2817 template <typename LeftKind, typename RightKind>

2818 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK,

2819 bool DeleteLeft) {

2820 auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * {

2821 for (auto *Res = Tok.Next; Res; Res = Res->Next) {

2822 if (Res->isNot(tok::comment) &&

2823 DeletedTokens.find(Res) == DeletedTokens.end()) {

2824 return Res;

2825 }

2826 }

2827 return nullptr;

2828 };

2829 for (auto *Left = Start; Left;) {

2830 auto *Right = NextNotDeleted(*Left);

2831 if (!Right)

2832 break;

2833 if (Left->is(LK) && Right->is(RK)) {

2834 deleteToken(DeleteLeft ? Left : Right);

2835 for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next)

2836 deleteToken(Tok);

2837

2838

2839 if (!DeleteLeft)

2840 continue;

2841 }

2843 }

2844 }

2845

2846 template <typename LeftKind, typename RightKind>

2847 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) {

2848 cleanupPair(Start, LK, RK, true);

2849 }

2850

2851 template <typename LeftKind, typename RightKind>

2852 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) {

2853 cleanupPair(Start, LK, RK, false);

2854 }

2855

2856

2857 inline void deleteToken(FormatToken *Tok) {

2858 if (Tok)

2859 DeletedTokens.insert(Tok);

2860 }

2861

2862 tooling::Replacements generateFixes() {

2863 tooling::Replacements Fixes;

2864 SmallVector<FormatToken *> Tokens;

2865 std::copy(DeletedTokens.begin(), DeletedTokens.end(),

2866 std::back_inserter(Tokens));

2867

2868

2869

2870

2871 unsigned Idx = 0;

2872 while (Idx < Tokens.size()) {

2873 unsigned St = Idx, End = Idx;

2874 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1])

2875 ++End;

2876 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),

2877 Tokens[End]->Tok.getEndLoc());

2878 auto Err =

2879 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, ""));

2880

2881

2882 if (Err) {

2883 llvm::errs() << toString(std::move(Err)) << "\n";

2884 assert(false && "Fixes must not conflict!");

2885 }

2886 Idx = End + 1;

2887 }

2888

2889 return Fixes;

2890 }

2891

2892

2893

2894

2895 struct FormatTokenLess {

2896 FormatTokenLess(const SourceManager &SM) : SM(SM) {}

2897

2898 bool operator()(const FormatToken *LHS, const FormatToken *RHS) const {

2899 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(),

2900 RHS->Tok.getLocation());

2901 }

2902 const SourceManager &SM;

2903 };

2904

2905

2906 std::set<FormatToken *, FormatTokenLess> DeletedTokens;

2907};

2908

2909class ObjCHeaderStyleGuesser : public TokenAnalyzer {

2910public:

2911 ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style)

2912 : TokenAnalyzer(Env, Style), IsObjC(false) {}

2913

2914 std::pair<tooling::Replacements, unsigned>

2915 analyze(TokenAnnotator &Annotator,

2916 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2917 FormatTokenLexer &Tokens) override {

2918 assert(Style.Language == FormatStyle::LK_Cpp);

2919 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,

2920 Tokens.getKeywords());

2921 tooling::Replacements Result;

2922 return {Result, 0};

2923 }

2924

2925 bool isObjC() { return IsObjC; }

2926

2927private:

2928 static bool

2929 guessIsObjC(const SourceManager &SourceManager,

2930 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,

2931 const AdditionalKeywords &Keywords) {

2932

2933 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {

2934 "CGFloat",

2935 "CGPoint",

2936 "CGPointMake",

2937 "CGPointZero",

2938 "CGRect",

2939 "CGRectEdge",

2940 "CGRectInfinite",

2941 "CGRectMake",

2942 "CGRectNull",

2943 "CGRectZero",

2944 "CGSize",

2945 "CGSizeMake",

2946 "CGVector",

2947 "CGVectorMake",

2948 "FOUNDATION_EXPORT",

2949 "FOUNDATION_EXTERN",

2950 "NSAffineTransform",

2951 "NSArray",

2952 "NSAttributedString",

2953 "NSBlockOperation",

2954 "NSBundle",

2955 "NSCache",

2956 "NSCalendar",

2957 "NSCharacterSet",

2958 "NSCountedSet",

2959 "NSData",

2960 "NSDataDetector",

2961 "NSDecimal",

2962 "NSDecimalNumber",

2963 "NSDictionary",

2964 "NSEdgeInsets",

2965 "NSError",

2966 "NSErrorDomain",

2967 "NSHashTable",

2968 "NSIndexPath",

2969 "NSIndexSet",

2970 "NSInteger",

2971 "NSInvocationOperation",

2972 "NSLocale",

2973 "NSMapTable",

2974 "NSMutableArray",

2975 "NSMutableAttributedString",

2976 "NSMutableCharacterSet",

2977 "NSMutableData",

2978 "NSMutableDictionary",

2979 "NSMutableIndexSet",

2980 "NSMutableOrderedSet",

2981 "NSMutableSet",

2982 "NSMutableString",

2983 "NSNumber",

2984 "NSNumberFormatter",

2985 "NSObject",

2986 "NSOperation",

2987 "NSOperationQueue",

2988 "NSOperationQueuePriority",

2989 "NSOrderedSet",

2990 "NSPoint",

2991 "NSPointerArray",

2992 "NSQualityOfService",

2993 "NSRange",

2994 "NSRect",

2995 "NSRegularExpression",

2996 "NSSet",

2997 "NSSize",

2998 "NSString",

2999 "NSTimeZone",

3000 "NSUInteger",

3001 "NSURL",

3002 "NSURLComponents",

3003 "NSURLQueryItem",

3004 "NSUUID",

3005 "NSValue",

3006 "NS_ASSUME_NONNULL_BEGIN",

3007 "UIImage",

3008 "UIView",

3009 };

3010

3011 for (auto *Line : AnnotatedLines) {

3012 if (Line->First && (Line->First->TokenText.starts_with("#") ||

3013 Line->First->TokenText == "__pragma" ||

3014 Line->First->TokenText == "_Pragma")) {

3015 continue;

3016 }

3017 for (const FormatToken *FormatTok = Line->First; FormatTok;

3018 FormatTok = FormatTok->Next) {

3019 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&

3020 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||

3021 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,

3022 tok::l_brace))) ||

3023 (FormatTok->Tok.isAnyIdentifier() &&

3024 std::binary_search(std::begin(FoundationIdentifiers),

3025 std::end(FoundationIdentifiers),

3026 FormatTok->TokenText)) ||

3027 FormatTok->is(TT_ObjCStringLiteral) ||

3028 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM,

3029 Keywords.kw_NS_ERROR_ENUM,

3030 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace,

3031 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn,

3032 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier,

3033 TT_ObjCProperty)) {

3034 LLVM_DEBUG(llvm::dbgs()

3035 << "Detected ObjC at location "

3036 << FormatTok->Tok.getLocation().printToString(

3037 SourceManager)

3038 << " token: " << FormatTok->TokenText << " token type: "

3040 return true;

3041 }

3042 }

3043 if (guessIsObjC(SourceManager, Line->Children, Keywords))

3044 return true;

3045 }

3046 return false;

3047 }

3048

3049 bool IsObjC;

3050};

3051

3055 unsigned Offset;

3058};

3059

3060struct JavaImportDirective {

3062 StringRef Text;

3063 unsigned Offset;

3066};

3067

3068}

3069

3070

3072 unsigned End) {

3073 for (const auto &Range : Ranges) {

3074 if (Range.getOffset() < End &&

3075 Range.getOffset() + Range.getLength() > Start) {

3076 return true;

3077 }

3078 }

3079 return false;

3080}

3081

3082

3083

3084

3085

3086

3087

3088

3089static std::pair<unsigned, unsigned>

3092 unsigned CursorIndex = UINT_MAX;

3093 unsigned OffsetToEOL = 0;

3094 for (int i = 0, e = Includes.size(); i != e; ++i) {

3095 unsigned Start = Includes[Indices[i]].Offset;

3096 unsigned End = Start + Includes[Indices[i]].Text.size();

3097 if (!(Cursor >= Start && Cursor < End))

3098 continue;

3099 CursorIndex = Indices[i];

3100 OffsetToEOL = End - Cursor;

3101

3102

3103 while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text)

3104 CursorIndex = i;

3105 break;

3106 }

3107 return std::make_pair(CursorIndex, OffsetToEOL);

3108}

3109

3110

3112 std::string NewCode;

3113 size_t Pos = 0, LastPos = 0;

3114

3115 do {

3116 Pos = Code.find("\r\n", LastPos);

3117 if (Pos == LastPos) {

3118 ++LastPos;

3119 continue;

3120 }

3121 if (Pos == std:🧵:npos) {

3122 NewCode += Code.substr(LastPos);

3123 break;

3124 }

3125 NewCode += Code.substr(LastPos, Pos - LastPos) + "\n";

3126 LastPos = Pos + 2;

3127 } while (Pos != std:🧵:npos);

3128

3129 return NewCode;

3130}

3131

3132

3133

3134

3135

3136

3137

3138

3143 unsigned *Cursor) {

3145 const unsigned IncludesBeginOffset = Includes.front().Offset;

3146 const unsigned IncludesEndOffset =

3147 Includes.back().Offset + Includes.back().Text.size();

3148 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;

3149 if (affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))

3150 return;

3152 llvm::to_vector<16>(llvm::seq(0, Includes.size()));

3153

3155 stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {

3156 const auto LHSFilenameLower = Includes[LHSI].Filename.lower();

3157 const auto RHSFilenameLower = Includes[RHSI].Filename.lower();

3158 return std::tie(Includes[LHSI].Priority, LHSFilenameLower,

3160 std::tie(Includes[RHSI].Priority, RHSFilenameLower,

3162 });

3163 } else {

3164 stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {

3165 return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <

3167 });

3168 }

3169

3170

3171

3172 unsigned CursorIndex;

3173

3174 unsigned CursorToEOLOffset;

3175 if (Cursor) {

3176 std::tie(CursorIndex, CursorToEOLOffset) =

3178 }

3179

3180

3181 Indices.erase(std::unique(Indices.begin(), Indices.end(),

3182 [&](unsigned LHSI, unsigned RHSI) {

3183 return Includes[LHSI].Text.trim() ==

3184 Includes[RHSI].Text.trim();

3185 }),

3186 Indices.end());

3187

3188 int CurrentCategory = Includes.front().Category;

3189

3190

3191

3192

3193

3194

3195

3196 if (Indices.size() == Includes.size() && is_sorted(Indices) &&

3198 return;

3199 }

3200

3201 const auto OldCursor = Cursor ? *Cursor : 0;

3202 std::string result;

3203 for (unsigned Index : Indices) {

3204 if (!result.empty()) {

3205 result += "\n";

3208 CurrentCategory != Includes[Index].Category) {

3209 result += "\n";

3210 }

3211 }

3212 result += Includes[Index].Text;

3213 if (Cursor && CursorIndex == Index)

3214 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;

3215 CurrentCategory = Includes[Index].Category;

3216 }

3217

3218 if (Cursor && *Cursor >= IncludesEndOffset)

3219 *Cursor += result.size() - IncludesBlockSize;

3220

3221

3222

3224 IncludesBeginOffset, IncludesBlockSize)))) {

3225 if (Cursor)

3226 *Cursor = OldCursor;

3227 return;

3228 }

3229

3231 FileName, Includes.front().Offset, IncludesBlockSize, result));

3232

3233

3234 if (Err) {

3235 llvm::errs() << toString(std::move(Err)) << "\n";

3236 assert(false);

3237 }

3238}

3239

3244 unsigned *Cursor) {

3245 unsigned Prev = llvm::StringSwitch<size_t>(Code)

3246 .StartsWith("\xEF\xBB\xBF", 3)

3247 .Default(0);

3248 unsigned SearchFrom = 0;

3251

3252

3253

3254

3255

3256

3257

3258

3260 bool FirstIncludeBlock = true;

3261 bool MainIncludeFound = false;

3262 bool FormattingOff = false;

3263

3264

3265 llvm::Regex RawStringRegex(

3266 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\(");

3268 std::string RawStringTermination = ")\"";

3269

3270 for (const auto Size = Code.size(); SearchFrom < Size;) {

3271 size_t Pos = SearchFrom;

3272 if (Code[SearchFrom] != '\n') {

3273 do {

3274 ++Pos;

3275 Pos = Code.find('\n', Pos);

3276 } while (Pos != StringRef::npos && Code[Pos - 1] == '\\');

3277 }

3278

3279 StringRef Line =

3280 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);

3281

3282 StringRef Trimmed = Line.trim();

3283

3284

3285

3286

3287 if (RawStringRegex.match(Trimmed, &RawStringMatches)) {

3288 std::string CharSequence = RawStringMatches[1].str();

3289 RawStringTermination = ")" + CharSequence + "\"";

3290 FormattingOff = true;

3291 }

3292

3293 if (Trimmed.contains(RawStringTermination))

3294 FormattingOff = false;

3295

3296 bool IsBlockComment = false;

3297

3299 FormattingOff = true;

3301 FormattingOff = false;

3302 } else if (Trimmed.starts_with("/*")) {

3303 IsBlockComment = true;

3304 Pos = Code.find("*/", SearchFrom + 2);

3305 }

3306

3307 const bool EmptyLineSkipped =

3308 Trimmed.empty() &&

3312

3313 bool MergeWithNextLine = Trimmed.ends_with("\\");

3314 if (!FormattingOff && !MergeWithNextLine) {

3315 if (!IsBlockComment &&

3317 StringRef IncludeName = Matches[2];

3318 if (Trimmed.contains("/*") && !Trimmed.contains("*/")) {

3319

3320

3321

3322

3323 Pos = Code.find("*/", SearchFrom);

3324 Line = Code.substr(

3325 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev);

3326 }

3328 IncludeName,

3329 !MainIncludeFound && FirstIncludeBlock);

3331 IncludeName, !MainIncludeFound && FirstIncludeBlock);

3333 MainIncludeFound = true;

3334 IncludesInBlock.push_back(

3336 } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {

3338 Replaces, Cursor);

3339 IncludesInBlock.clear();

3340 if (Trimmed.starts_with("#pragma hdrstop"))

3341 FirstIncludeBlock = true;

3342 else

3343 FirstIncludeBlock = false;

3344 }

3345 }

3346 if (Pos == StringRef::npos || Pos + 1 == Code.size())

3347 break;

3348

3349 if (!MergeWithNextLine)

3350 Prev = Pos + 1;

3351 SearchFrom = Pos + 1;

3352 }

3353 if (!IncludesInBlock.empty()) {

3355 Cursor);

3356 }

3357 return Replaces;

3358}

3359

3360

3361

3363 StringRef ImportIdentifier) {

3364 unsigned LongestMatchIndex = UINT_MAX;

3365 unsigned LongestMatchLength = 0;

3366 for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) {

3368 if (ImportIdentifier.starts_with(GroupPrefix) &&

3369 GroupPrefix.length() > LongestMatchLength) {

3370 LongestMatchIndex = I;

3371 LongestMatchLength = GroupPrefix.length();

3372 }

3373 }

3374 return LongestMatchIndex;

3375}

3376

3377

3378

3379

3380

3381

3386 unsigned ImportsBeginOffset = Imports.front().Offset;

3387 unsigned ImportsEndOffset =

3388 Imports.back().Offset + Imports.back().Text.size();

3389 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;

3390 if (affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))

3391 return;

3392

3394 llvm::to_vector<16>(llvm::seq(0, Imports.size()));

3397 for (const JavaImportDirective &Import : Imports)

3399

3400 bool StaticImportAfterNormalImport =

3402 sort(Indices, [&](unsigned LHSI, unsigned RHSI) {

3403

3404 return std::make_tuple(!Imports[LHSI].IsStatic ^

3405 StaticImportAfterNormalImport,

3407 std::make_tuple(!Imports[RHSI].IsStatic ^

3408 StaticImportAfterNormalImport,

3410 });

3411

3412

3413 Indices.erase(std::unique(Indices.begin(), Indices.end(),

3414 [&](unsigned LHSI, unsigned RHSI) {

3415 return Imports[LHSI].Text == Imports[RHSI].Text;

3416 }),

3417 Indices.end());

3418

3419 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;

3420 unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];

3421

3422 std::string result;

3423 for (unsigned Index : Indices) {

3424 if (!result.empty()) {

3425 result += "\n";

3426 if (CurrentIsStatic != Imports[Index].IsStatic ||

3428 result += "\n";

3429 }

3430 }

3432 result += CommentLine;

3433 result += "\n";

3434 }

3435 result += Imports[Index].Text;

3436 CurrentIsStatic = Imports[Index].IsStatic;

3438 }

3439

3440

3441

3443 Imports.front().Offset, ImportsBlockSize)))) {

3444 return;

3445 }

3446

3448 ImportsBlockSize, result));

3449

3450

3451 if (Err) {

3452 llvm::errs() << toString(std::move(Err)) << "\n";

3453 assert(false);

3454 }

3455}

3456

3457namespace {

3458

3459const char JavaImportRegexPattern[] =

3460 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";

3461

3462}

3463

3468 unsigned Prev = 0;

3469 unsigned SearchFrom = 0;

3470 llvm::Regex ImportRegex(JavaImportRegexPattern);

3474

3475 bool FormattingOff = false;

3476

3477 for (;;) {

3478 auto Pos = Code.find('\n', SearchFrom);

3479 StringRef Line =

3480 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);

3481

3482 StringRef Trimmed = Line.trim();

3484 FormattingOff = true;

3486 FormattingOff = false;

3487

3488 if (ImportRegex.match(Line, &Matches)) {

3489 if (FormattingOff) {

3490

3491

3492 return Replaces;

3493 }

3494 StringRef Static = Matches[1];

3497 if (Static.contains("static"))

3499 ImportsInBlock.push_back(

3502 } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {

3503

3505 }

3506 Prev = Pos + 1;

3507 if (Pos == StringRef::npos || Pos + 1 == Code.size())

3508 break;

3509 SearchFrom = Pos + 1;

3510 }

3511 if (!ImportsInBlock.empty())

3513 return Replaces;

3514}

3515

3517

3518

3519

3520 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;

3521}

3522

3523bool isLikelyXml(StringRef Code) { return Code.ltrim().starts_with("<"); }

3524

3527 StringRef FileName, unsigned *Cursor) {

3530 return Replaces;

3532 return Replaces;

3535 return Replaces;

3536 }

3542 return Replaces;

3543}

3544

3545template

3550 if (Replaces.empty())

3552

3553 auto NewCode = applyAllReplacements(Code, Replaces);

3554 if (!NewCode)

3555 return NewCode.takeError();

3556 std::vectortooling::Range ChangedRanges = Replaces.getAffectedRanges();

3557 StringRef FileName = Replaces.begin()->getFilePath();

3558

3560 ProcessFunc(Style, *NewCode, ChangedRanges, FileName);

3561

3562 return Replaces.merge(FormatReplaces);

3563}

3564

3568

3569

3571 std::vectortooling::Range Ranges,

3574 };

3575 auto SortedReplaces =

3577 if (!SortedReplaces)

3578 return SortedReplaces.takeError();

3579

3580

3581

3582 auto Reformat = [](const FormatStyle &Style, StringRef Code,

3583 std::vectortooling::Range Ranges,

3586 };

3588}

3589

3590namespace {

3591

3596}

3597

3598inline bool isHeaderDeletion(const tooling::Replacement &Replace) {

3599 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1;

3600}

3601

3602

3603tooling::Replacements

3604fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,

3606 if (!Style.isCpp())

3607 return Replaces;

3608

3609 tooling::Replacements HeaderInsertions;

3610 std::set HeadersToDelete;

3611 tooling::Replacements Result;

3612 for (const auto &R : Replaces) {

3613 if (isHeaderInsertion(R)) {

3614

3615

3616 consumeError(HeaderInsertions.add(R));

3617 } else if (isHeaderDeletion(R)) {

3618 HeadersToDelete.insert(R.getReplacementText());

3619 } else if (R.getOffset() == UINT_MAX) {

3620 llvm::errs() << "Insertions other than header #include insertion are "

3621 "not supported! "

3622 << R.getReplacementText() << "\n";

3623 } else {

3624 consumeError(Result.add(R));

3625 }

3626 }

3627 if (HeaderInsertions.empty() && HeadersToDelete.empty())

3628 return Replaces;

3629

3630 StringRef FileName = Replaces.begin()->getFilePath();

3632

3633 for (const auto &Header : HeadersToDelete) {

3634 tooling::Replacements Replaces =

3635 Includes.remove(Header.trim("\"<>"), Header.starts_with("<"));

3636 for (const auto &R : Replaces) {

3637 auto Err = Result.add(R);

3638 if (Err) {

3639

3640 llvm::errs() << "Failed to add header deletion replacement for "

3641 << Header << ": " << toString(std::move(Err)) << "\n";

3642 }

3643 }

3644 }

3645

3646 SmallVector<StringRef, 4> Matches;

3647 for (const auto &R : HeaderInsertions) {

3649 bool Matched =

3651 assert(Matched && "Header insertion replacement must have replacement text "

3652 "'#include ...'");

3653 (void)Matched;

3654 auto IncludeName = Matches[2];

3655 auto Replace =

3656 Includes.insert(IncludeName.trim("\"<>"), IncludeName.starts_with("<"),

3658 if (Replace) {

3659 auto Err = Result.add(*Replace);

3660 if (Err) {

3661 consumeError(std::move(Err));

3662 unsigned NewOffset =

3663 Result.getShiftedCodePosition(Replace->getOffset());

3664 auto Shifted = tooling::Replacement(FileName, NewOffset, 0,

3665 Replace->getReplacementText());

3666 Result = Result.merge(tooling::Replacements(Shifted));

3667 }

3668 }

3669 }

3671}

3672

3673}

3674

3675Expectedtooling::Replacements

3678

3679

3680 auto Cleanup = [](const FormatStyle &Style, StringRef Code,

3684 };

3685

3687 fixCppIncludeInsertions(Code, Replaces, Style);

3688 return cantFail(processReplacements(Cleanup, Code, NewReplaces, Style));

3689}

3690

3691namespace internal {

3692std::pair<tooling::Replacements, unsigned>

3695 unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName,

3706 case FormatStyle::RCPS_SingleLine:

3707 case FormatStyle::RCPS_WithPreceding:

3709 break;

3710 default:

3711 break;

3712 }

3713

3718 if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code))

3720

3721

3722 if (Style.isJson()) {

3723 std::vectortooling::Range Ranges(1, tooling::Range(0, Code.size()));

3724 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,

3725 NextStartColumn, LastStartColumn);

3726 if (Env)

3727 return {};

3728

3730 Formatter(*Env, Style, Status).process().first;

3731

3732 Replaces = Replaces.merge(

3734

3735 if (applyAllReplacements(Code, Replaces))

3736 return {Replaces, 0};

3738 }

3739

3740 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn,

3741 NextStartColumn, LastStartColumn);

3742 if (Env)

3743 return {};

3744

3745 typedef std::function<std::pair<tooling::Replacements, unsigned>(

3748

3750

3753 });

3754

3755 if (Style.isCpp()) {

3758

3762 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {

3763 return ParensRemover(Env, S).process(true);

3764 });

3765 }

3766

3769 S.InsertBraces = true;

3770 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {

3771 return BracesInserter(Env, S).process(true);

3772 });

3773 }

3774

3777 S.RemoveBracesLLVM = true;

3778 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {

3779 return BracesRemover(Env, S).process(true);

3780 });

3781 }

3782

3785 S.RemoveSemicolon = true;

3786 Passes.emplace_back([&, S = std::move(S)](const Environment &Env) {

3787 return SemiRemover(Env, S).process();

3788 });

3789 }

3790

3794 });

3795 }

3796

3800 });

3801 }

3802 }

3803

3807 });

3808 }

3809

3810 if (Style.Language == FormatStyle::LK_ObjC &&

3814 });

3815 }

3816

3820 return JavaScriptRequoter(Env, Expanded).process(true);

3821 });

3822 }

3823

3825 return Formatter(Env, Expanded, Status).process();

3826 });

3827

3831 return TrailingCommaInserter(Env, Expanded).process();

3832 });

3833 }

3834

3835 std::optionalstd::string CurrentCode;

3837 unsigned Penalty = 0;

3838 for (size_t I = 0, E = Passes.size(); I < E; ++I) {

3839 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);

3840 auto NewCode = applyAllReplacements(

3841 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);

3842 if (NewCode) {

3843 Fixes = Fixes.merge(PassFixes.first);

3844 Penalty += PassFixes.second;

3845 if (I + 1 < E) {

3846 CurrentCode = std::move(*NewCode);

3847 Env = Environment::make(

3849 tooling::calculateRangesAfterReplacements(Fixes, Ranges),

3850 FirstStartColumn, NextStartColumn, LastStartColumn);

3851 if (Env)

3852 return {};

3853 }

3854 }

3855 }

3856

3858

3859

3860

3863 StringRef OriginalCode = Code.substr(Fix.getOffset(), Fix.getLength());

3864 if (OriginalCode != Fix.getReplacementText()) {

3865 auto Err = NonNoOpFixes.add(Fix);

3866 if (Err) {

3867 llvm::errs() << "Error adding replacements : "

3868 << toString(std::move(Err)) << "\n";

3869 }

3870 }

3871 }

3872 Fixes = std::move(NonNoOpFixes);

3873 }

3874

3875 return {Fixes, Penalty};

3876}

3877}

3878

3884 0,

3885 0,

3886 0, FileName, Status)

3887 .first;

3888}

3889

3893

3897 if (Env)

3898 return {};

3899 return Cleaner(*Env, Style).process().first;

3900}

3901

3904 StringRef FileName, bool *IncompleteFormat) {

3907 if (!Status.FormatComplete)

3908 *IncompleteFormat = true;

3910}

3911

3913 StringRef Code,

3917 if (Env)

3918 return {};

3920}

3921

3923 StringRef Code,

3927 if (Env)

3928 return {};

3930}

3931

3934

3940 LangOpts.CPlusPlus = 1;

3946

3947

3948

3950

3951 LangOpts.LineComment = 1;

3952 LangOpts.CXXOperatorNames = Style.isCpp();

3953 LangOpts.Bool = 1;

3954 LangOpts.ObjC = 1;

3955 LangOpts.MicrosoftExt = 1;

3956 LangOpts.DeclSpecKeyword = 1;

3957 LangOpts.C99 = 1;

3958 return LangOpts;

3959}

3960

3962 "Set coding style. can be:\n"

3963 "1. A preset: LLVM, GNU, Google, Chromium, Microsoft,\n"

3964 " Mozilla, WebKit.\n"

3965 "2. 'file' to load style configuration from a\n"

3966 " .clang-format file in one of the parent directories\n"

3967 " of the source file (for stdin, see --assume-filename).\n"

3968 " If no .clang-format file is found, falls back to\n"

3969 " --fallback-style.\n"

3970 " --style=file is the default.\n"

3971 "3. 'file:<format_file_path>' to explicitly specify\n"

3972 " the configuration file.\n"

3973 "4. \"{key: value, ...}\" to set specific parameters, e.g.:\n"

3974 " --style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";

3975

3977 if (FileName.ends_with(".java"))

3979 if (FileName.ends_with_insensitive(".js") ||

3980 FileName.ends_with_insensitive(".mjs") ||

3981 FileName.ends_with_insensitive(".cjs") ||

3982 FileName.ends_with_insensitive(".ts")) {

3984 }

3987 if (FileName.ends_with_insensitive(".proto") ||

3988 FileName.ends_with_insensitive(".protodevel")) {

3990 }

3991

3992

3993

3994 if (FileName.ends_with_insensitive(".txtpb") ||

3995 FileName.ends_with_insensitive(".textpb") ||

3996 FileName.ends_with_insensitive(".pb.txt") ||

3997 FileName.ends_with_insensitive(".textproto") ||

3998 FileName.ends_with_insensitive(".asciipb")) {

4000 }

4001 if (FileName.ends_with_insensitive(".td"))

4003 if (FileName.ends_with_insensitive(".cs"))

4005 if (FileName.ends_with_insensitive(".json"))

4007 if (FileName.ends_with_insensitive(".sv") ||

4008 FileName.ends_with_insensitive(".svh") ||

4009 FileName.ends_with_insensitive(".v") ||

4010 FileName.ends_with_insensitive(".vh")) {

4012 }

4014}

4015

4019 auto Extension = llvm::sys::path::extension(FileName);

4020

4021

4022 if (!Code.empty() && (Extension.empty() || Extension == ".h")) {

4023 auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName;

4024 Environment Env(Code, NonEmptyFileName, {});

4026 Guesser.process();

4027 if (Guesser.isObjC())

4029 }

4030 }

4031 return GuessedLanguage;

4032}

4033

4034

4036

4038

4039llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer>

4041 FormatStyle *Style, bool AllowUnknownOptions,

4042 llvm::SourceMgr::DiagHandlerTy DiagHandler) {

4043 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> Text =

4044 FS->getBufferForFile(ConfigFile.str());

4045 if (auto EC = Text.getError())

4046 return EC;

4048 DiagHandler)) {

4049 return EC;

4050 }

4051 return Text;

4052}

4053

4055 StringRef FallbackStyleName, StringRef Code,

4056 llvm::vfs::FileSystem *FS,

4057 bool AllowUnknownOptions,

4058 llvm::SourceMgr::DiagHandlerTy DiagHandler) {

4062 return make_string_error("Invalid fallback style: " + FallbackStyleName);

4063

4065

4066 if (StyleName.starts_with("{")) {

4067

4068 StringRef Source = "";

4069 if (std::error_code ec =

4070 parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style,

4071 AllowUnknownOptions, DiagHandler)) {

4072 return make_string_error("Error parsing -style: " + ec.message());

4073 }

4074

4076 return Style;

4077

4078 ChildFormatTextToApply.emplace_back(

4079 llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false));

4080 }

4081

4082 if (!FS)

4083 FS = llvm::vfs::getRealFileSystem().get();

4084 assert(FS);

4085

4086

4088 StyleName.starts_with_insensitive("file:")) {

4089 auto ConfigFile = StyleName.substr(5);

4090 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> Text =

4092 DiagHandler);

4093 if (auto EC = Text.getError()) {

4095 EC.message());

4096 }

4097

4098 LLVM_DEBUG(llvm::dbgs()

4099 << "Using configuration file " << ConfigFile << "\n");

4100

4102 return Style;

4103

4104

4105

4107 ChildFormatTextToApply.emplace_back(std::move(*Text));

4108 }

4109

4110

4111

4112

4117 return Style;

4118 }

4119

4121 if (std::error_code EC = FS->makeAbsolute(Path))

4123

4124

4126

4127 auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {};

4128

4129 auto applyChildFormatTexts = [&](FormatStyle *Style) {

4130 for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {

4131 auto EC =

4133 DiagHandler ? DiagHandler : dropDiagnosticHandler);

4134

4135 assert(!EC);

4136 static_cast<void>(EC);

4137 }

4138 };

4139

4140

4142 FilesToLookFor.push_back(".clang-format");

4143 FilesToLookFor.push_back("_clang-format");

4144

4146 for (StringRef Directory = Path; !Directory.empty();

4147 Directory = llvm::sys::path::parent_path(Directory)) {

4148 auto Status = FS->status(Directory);

4149 if (!Status ||

4150 Status->getType() != llvm::sys::fs::file_type::directory_file) {

4151 continue;

4152 }

4153

4154 for (const auto &F : FilesToLookFor) {

4156

4157 llvm::sys::path::append(ConfigFile, F);

4158 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");

4159

4160 Status = FS->status(ConfigFile);

4161 if (!Status ||

4162 Status->getType() != llvm::sys::fs::file_type::regular_file) {

4163 continue;

4164 }

4165

4166 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> Text =

4168 DiagHandler);

4169 if (auto EC = Text.getError()) {

4172 EC.message());

4173 }

4174 if (!UnsuitableConfigFiles.empty())

4175 UnsuitableConfigFiles.append(", ");

4176 UnsuitableConfigFiles.append(ConfigFile);

4177 continue;

4178 }

4179

4180 LLVM_DEBUG(llvm::dbgs()

4181 << "Using configuration file " << ConfigFile << "\n");

4182

4184 if (!ChildFormatTextToApply.empty()) {

4185 LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n");

4186 applyChildFormatTexts(&Style);

4187 }

4188 return Style;

4189 }

4190

4191 LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n");

4192

4193

4195

4196 ChildFormatTextToApply.emplace_back(std::move(*Text));

4197

4198

4199

4200

4201

4202 break;

4203 }

4204 }

4205

4206 if (!UnsuitableConfigFiles.empty()) {

4207 return make_string_error("Configuration file(s) do(es) not support " +

4209 UnsuitableConfigFiles);

4210 }

4211

4212 if (!ChildFormatTextToApply.empty()) {

4213 LLVM_DEBUG(llvm::dbgs()

4214 << "Applying child configurations on fallback style\n");

4215 applyChildFormatTexts(&FallbackStyle);

4216 }

4217

4218 return FallbackStyle;

4219}

4220

4222 if (Comment == (On ? "/* clang-format on */" : "/* clang-format off */"))

4223 return true;

4224

4225 static const char ClangFormatOn[] = "// clang-format on";

4226 static const char ClangFormatOff[] = "// clang-format off";

4227 const unsigned Size = (On ? sizeof ClangFormatOn : sizeof ClangFormatOff) - 1;

4228

4229 return Comment.starts_with(On ? ClangFormatOn : ClangFormatOff) &&

4230 (Comment.size() == Size || Comment[Size] == ':');

4231}

4232

4235}

4236

4239}

4240

4241}

4242}

This file declares DefinitionBlockSeparator, a TokenAnalyzer that inserts or removes empty lines sepa...

SmallVector< StringRef > AssociatedCommentLines

Various functions to configurably format source code.

This file declares IntegerLiteralSeparatorFixer that fixes C++ integer literal separators.

This file declares ObjCPropertyAttributeOrderFixer, a TokenAnalyzer that adjusts the order of attribu...

This file declares QualifierAlignmentFixer, a TokenAnalyzer that enforces either east or west const d...

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

This file implements a sorter for JavaScript ES6 imports.

ContinuationIndenter * Indenter

Implements a combinatorial exploration of all the different linebreaks unwrapped lines can be formatt...

This file declares UsingDeclarationsSorter, a TokenAnalyzer that sorts consecutive using declarations...

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

static std::unique_ptr< Environment > make(StringRef Code, StringRef FileName, ArrayRef< tooling::Range > Ranges, unsigned FirstStartColumn=0, unsigned NextStartColumn=0, unsigned LastStartColumn=0)

std::pair< tooling::Replacements, unsigned > process(const Environment &Env, const FormatStyle &Style)

static tok::TokenKind getTokenFromQualifier(const std::string &Qualifier)

const char * name() const noexcept override

std::string message(int EV) const override

std::pair< tooling::Replacements, unsigned > process(bool SkipAnnotation=false)

SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)

Returns the results of matching Matcher on Node.

bool isObjC(ID Id)

isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).

std::pair< tooling::Replacements, unsigned > reformat(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, unsigned FirstStartColumn, unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, FormattingAttemptStatus *Status)

Reformats the given Ranges in the code fragment Code.

const char * StyleOptionHelpDescription

Description to be used for help text for a llvm::cl option for specifying format style.

void addQualifierAlignmentFixerPasses(const FormatStyle &Style, SmallVectorImpl< AnalyzerPass > &Passes)

static void expandPresetsSpaceBeforeParens(FormatStyle &Expanded)

const char * DefaultFallbackStyle

The suggested predefined style to use as the fallback style in getStyle.

static bool affectsRange(ArrayRef< tooling::Range > Ranges, unsigned Start, unsigned End)

const char * getTokenTypeName(TokenType Type)

Determines the name of a token type.

FormatStyle getWebKitStyle()

Returns a format style complying with Webkit's style guide: http://www.webkit.org/coding/coding-style...

bool isLikelyXml(StringRef Code)

static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName)

static unsigned findJavaImportGroup(const FormatStyle &Style, StringRef ImportIdentifier)

std::string replaceCRLF(const std::string &Code)

std::error_code make_error_code(ParseError e)

FormatStyle getClangFormatStyle()

std::function< std::pair< tooling::Replacements, unsigned >(const Environment &)> AnalyzerPass

FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language=FormatStyle::LanguageKind::LK_Cpp)

Returns a format style complying with the LLVM coding standards: http://llvm.org/docs/CodingStandards...

FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language)

Returns a format style complying with one of Google's style guides: http://google-styleguide....

std::string configurationAsText(const FormatStyle &Style)

Gets configuration in a YAML string.

FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language)

Returns a format style complying with Microsoft style guide: https://docs.microsoft....

std::error_code parseConfiguration(llvm::MemoryBufferRef Config, FormatStyle *Style, bool AllowUnknownOptions=false, llvm::SourceMgr::DiagHandlerTy DiagHandler=nullptr, void *DiagHandlerCtx=nullptr)

Parse configuration from YAML-formatted text.

const std::error_category & getParseCategory()

tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")

Fix namespace end comments in the given Ranges in Code.

FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code)

Expected< FormatStyle > getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyle, StringRef Code="", llvm::vfs::FileSystem *FS=nullptr, bool AllowUnknownOptions=false, llvm::SourceMgr::DiagHandlerTy DiagHandler=nullptr)

Construct a FormatStyle based on StyleName.

bool isMpegTS(StringRef Code)

@ DuplicateQualifierSpecified

@ BinPackTrailingCommaConflict

@ InvalidQualifierSpecified

static std::pair< unsigned, unsigned > FindCursorIndex(const ArrayRef< IncludeDirective > &Includes, const ArrayRef< unsigned > &Indices, unsigned Cursor)

const char * DefaultFormatStyle

The suggested format style to use by default.

FormatStyle getGNUStyle()

Returns a format style complying with GNU Coding Standards: http://www.gnu.org/prep/standards/standar...

bool isClangFormatOff(StringRef Comment)

LangOptions getFormattingLangOpts(const FormatStyle &Style=getLLVMStyle())

Returns the LangOpts that the formatter expects you to set.

static bool isClangFormatOnOff(StringRef Comment, bool On)

tooling::Replacements sortJavaScriptImports(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName)

static void sortJavaImports(const FormatStyle &Style, const ArrayRef< JavaImportDirective > &Imports, ArrayRef< tooling::Range > Ranges, StringRef FileName, StringRef Code, tooling::Replacements &Replaces)

FormatStyle getMozillaStyle()

Returns a format style complying with Mozilla's style guide: https://firefox-source-docs....

bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, FormatStyle *Style)

Gets a predefined style for the specified language by name.

Expected< tooling::Replacements > cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces, const FormatStyle &Style)

Returns the replacements corresponding to applying Replaces and cleaning up the code after that on su...

static void expandPresetsBraceWrapping(FormatStyle &Expanded)

static void sortCppIncludes(const FormatStyle &Style, const ArrayRef< IncludeDirective > &Includes, ArrayRef< tooling::Range > Ranges, StringRef FileName, StringRef Code, tooling::Replacements &Replaces, unsigned *Cursor)

tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="", FormattingAttemptStatus *Status=nullptr)

Reformats the given Ranges in Code.

bool isClangFormatOn(StringRef Comment)

llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS, FormatStyle *Style, bool AllowUnknownOptions, llvm::SourceMgr::DiagHandlerTy DiagHandler)

tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")

Sort consecutive using declarations in the given Ranges in Code.

llvm::Error make_string_error(const Twine &Message)

ParseError validateQualifierOrder(FormatStyle *Style)

FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language)

Returns a format style complying with Chromium's style guide: http://www.chromium....

static void expandPresetsSpacesInParens(FormatStyle &Expanded)

tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")

Clean up any erroneous/redundant code in the given Ranges in Code.

Expected< tooling::Replacements > formatReplacements(StringRef Code, const tooling::Replacements &Replaces, const FormatStyle &Style)

Returns the replacements corresponding to applying and formatting Replaces on success; otheriwse,...

FormatStyle getNoStyle()

Returns style indicating formatting should be not applied at all.

tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName, unsigned *Cursor=nullptr)

Returns the replacements necessary to sort all #include blocks that are affected by Ranges.

static Expected< tooling::Replacements > processReplacements(T ProcessFunc, StringRef Code, const tooling::Replacements &Replaces, const FormatStyle &Style)

StringRef getLanguageName(FormatStyle::LanguageKind Language)

The JSON file list parser is used to communicate input to InstallAPI.

Language

The language for the input, used to select and validate the language standard and possible actions.

@ Result

The result type of a method or function.

const FunctionProtoType * T

Diagnostic wrappers for TextAPI types for error reporting.

bool PadOperators

Only for AlignConsecutiveAssignments.

bool AlignFunctionDeclarations

Only for AlignConsecutiveDeclarations.

bool SplitEmptyRecord

If false, empty record (e.g.

bool AfterClass

Wrap class definitions.

bool AfterCaseLabel

Wrap case labels.

bool AfterStruct

Wrap struct definitions.

bool BeforeLambdaBody

Wrap lambda block.

bool AfterUnion

Wrap union definitions.

bool AfterEnum

Wrap enum definitions.

bool AfterObjCDeclaration

Wrap ObjC definitions (interfaces, implementations...).

bool BeforeElse

Wrap before else.

bool AfterNamespace

Wrap namespace definitions.

bool BeforeWhile

Wrap before while.

BraceWrappingAfterControlStatementStyle AfterControlStatement

Wrap control statements (if/for/while/switch/..).

bool AfterFunction

Wrap function definitions.

bool BeforeCatch

Wrap before catch.

bool SplitEmptyFunction

If false, empty function body can be put on a single line.

bool AfterExternBlock

Wrap extern blocks.

void Add(FormatStyle Style)

std::optional< FormatStyle > Get(FormatStyle::LanguageKind Language) const

int8_t DecimalMinDigits

Format separators in decimal literals with a minimum number of digits.

int8_t Decimal

Format separators in decimal literals.

bool AtEndOfFile

Keep empty lines at end of file.

bool AtStartOfBlock

Keep empty lines at start of a block.

bool AfterControlStatements

If true, put space between control statement keywords (for/if/while...) and opening parentheses.

bool AfterForeachMacros

If true, put space between foreach macros and opening parentheses.

bool BeforeNonEmptyParentheses

If true, put a space before opening parentheses only if the parentheses are not empty.

bool AfterIfMacros

If true, put space between if macros and opening parentheses.

bool AfterPlacementOperator

If true, put a space between operator new/delete and opening parenthesis.

bool ExceptDoubleParentheses

Override any of the following options to prevent addition of space when both opening and closing pare...

bool Other

Put a space in parentheses not covered by preceding options.

bool InEmptyParentheses

Insert a space in empty parentheses, i.e.

bool InCStyleCasts

Put a space in C style casts.

bool InConditionalStatements

Put a space in parentheses only inside conditional statements (for/if/while/switch....

The FormatStyle is used to configure the formatting to follow specific guidelines.

bool SpaceBeforeInheritanceColon

If false, spaces will be removed before inheritance colon.

unsigned ContinuationIndentWidth

Indent width for line continuations.

bool AlwaysBreakBeforeMultilineStrings

This option is renamed to BreakAfterReturnType.

LanguageStandard Standard

Parse and format C++ constructs compatible with this standard.

bool BreakAdjacentStringLiterals

Break between adjacent string literals.

ReturnTypeBreakingStyle BreakAfterReturnType

The function declaration return type breaking style to use.

LanguageKind

Supported languages.

@ LK_CSharp

Should be used for C#.

@ LK_Java

Should be used for Java.

@ LK_Cpp

Should be used for C, C++.

@ LK_JavaScript

Should be used for JavaScript.

@ LK_ObjC

Should be used for Objective-C, Objective-C++.

@ LK_Verilog

Should be used for Verilog and SystemVerilog.

@ LK_TableGen

Should be used for TableGen code.

@ LK_Proto

Should be used for Protocol Buffers (https://developers.google.com/protocol-buffers/).

@ LK_Json

Should be used for JSON.

@ LK_TextProto

Should be used for Protocol Buffer messages in text format (https://developers.google....

bool Cpp11BracedListStyle

If true, format braced lists as best suited for C++11 braced lists.

SortIncludesOptions SortIncludes

Controls if and how clang-format will sort #includes.

BreakInheritanceListStyle BreakInheritanceList

The inheritance list style to use.

unsigned IndentWidth

The number of columns to use for indentation.

std::vector< std::string > AttributeMacros

This option is renamed to BreakTemplateDeclarations.

@ SLS_All

Merge all lambdas fitting on a single line.

@ SLS_Empty

Only merge empty lambdas.

@ SDS_Leave

Leave definition blocks as they are.

bool IndentRequiresClause

Indent the requires clause in a template.

SpacesInAnglesStyle SpacesInAngles

The SpacesInAnglesStyle to use for template argument lists.

bool KeepFormFeed

This option is deprecated.

bool IndentCaseLabels

Indent case labels one level from the switch statement.

std::vector< RawStringFormat > RawStringFormats

Defines hints for detecting supported languages code blocks in raw strings.

std::vector< std::string > VariableTemplates

A vector of non-keyword identifiers that should be interpreted as variable template names.

@ SJSIO_Before

Static imports are placed before non-static imports.

@ SJSIO_After

Static imports are placed after non-static imports.

PPDirectiveIndentStyle IndentPPDirectives

The preprocessor directive indenting style to use.

bool RemoveSemicolon

Remove semicolons after the closing braces of functions and constructors/destructors.

std::vector< std::string > Macros

A list of macros of the form = .

bool SpaceBeforeJsonColon

If true, a space will be added before a JSON colon.

@ TCS_None

Do not insert trailing commas.

unsigned PenaltyBreakBeforeFirstCallParameter

The penalty for breaking a function call after call(.

bool SpaceBeforeCtorInitializerColon

If false, spaces will be removed before constructor initializer colon.

@ BPPS_OnePerLine

Put all parameters on the current line if they fit.

@ BPPS_BinPack

Bin-pack parameters.

BinaryOperatorStyle BreakBeforeBinaryOperators

The way to wrap binary operators.

@ SI_Never

Includes are never sorted.

@ SI_CaseSensitive

Includes are sorted in an ASCIIbetical or case sensitive fashion.

@ SI_CaseInsensitive

Includes are sorted in an alphabetical or case insensitive fashion.

bool IndentExportBlock

If true, clang-format will indent the body of an export { ... } block.

@ BPS_Never

Never bin-pack parameters.

@ BPS_Auto

Automatically determine parameter bin-packing behavior.

BitFieldColonSpacingStyle BitFieldColonSpacing

The BitFieldColonSpacingStyle to use for bitfields.

@ RCS_Always

Apply indentation rules and reflow long comments into new lines, trying to obey the ColumnLimit.

@ ELBAMS_LogicalBlock

Add empty line only when access modifier starts a new logical block.

unsigned SpacesBeforeTrailingComments

If true, spaces may be inserted into ().

@ BCIS_BeforeColon

Break constructor initializers before the colon and after the commas.

@ BCIS_BeforeComma

Break constructor initializers before the colon and commas, and align the commas with the colon.

@ IEBS_AfterExternBlock

Backwards compatible with AfterExternBlock's indenting.

bool IndentCaseBlocks

Indent case label blocks one level from the case label.

bool InsertBraces

Insert braces after control statements (if, else, for, do, and while) in C++ unless the control state...

BreakBeforeConceptDeclarationsStyle BreakBeforeConceptDeclarations

The concept declaration style to use.

BreakTemplateDeclarationsStyle BreakTemplateDeclarations

The template declaration breaking style to use.

bool DerivePointerAlignment

This option is deprecated.

@ BOS_All

Break before operators.

@ BOS_None

Break after operators.

@ BOS_NonAssignment

Break before operators that aren't assignments.

@ LE_DeriveLF

Use \n unless the input has more lines ending in \r\n.

bool SpacesInSquareBrackets

If true, spaces will be inserted after [ and before ].

bool IndentWrappedFunctionNames

Indent if a function definition or declaration is wrapped after the type.

AlignConsecutiveStyle AlignConsecutiveTableGenBreakingDAGArgColons

Style of aligning consecutive TableGen DAGArg operator colons.

WrapNamespaceBodyWithEmptyLinesStyle WrapNamespaceBodyWithEmptyLines

Wrap namespace body with empty lines.

bool FixNamespaceComments

If true, clang-format adds missing namespace end comments for namespaces and fixes invalid existing o...

bool ObjCSpaceBeforeProtocolList

Add a space in front of an Objective-C protocol list, i.e.

@ TCAS_Never

Don't align trailing comments but other formatter applies.

@ TCAS_Always

Align trailing comments.

RemoveParenthesesStyle RemoveParentheses

Remove redundant parentheses.

std::string MacroBlockBegin

A regular expression matching macros that start a block.

bool SpaceInEmptyBlock

If true, spaces will be inserted into {}.

LanguageKind Language

Language, this format style is targeted at.

@ SIPO_Custom

Configure each individual space in parentheses in SpacesInParensOptions.

@ SIPO_Never

Never put a space in parentheses.

bool RemoveBracesLLVM

Remove optional braces of control statements (if, else, for, and while) in C++ according to the LLVM ...

@ BAS_DontAlign

Don't align, instead use ContinuationIndentWidth, e.g.:

@ BAS_AlwaysBreak

Always break after an open bracket, if the parameters don't fit on a single line, e....

@ BAS_Align

Align parameters on the open bracket, e.g.:

@ BBIAS_OnlyMultiline

Break before inline ASM colon if the line length is longer than column limit.

bool VerilogBreakBetweenInstancePorts

For Verilog, put each port on its own line in module instantiations.

unsigned TabWidth

The number of columns used for tab stops.

@ PPDIS_None

Does not indent any directives.

@ LBI_Signature

Align lambda body relative to the lambda signature.

std::vector< std::string > JavaImportGroups

A vector of prefixes ordered by the desired groups for Java imports.

bool AllowShortCaseLabelsOnASingleLine

If true, short case labels will be contracted to a single line.

unsigned PenaltyBreakFirstLessLess

The penalty for breaking before the first <<.

std::vector< std::string > StatementAttributeLikeMacros

Macros which are ignored in front of a statement, as if they were an attribute.

unsigned ObjCBlockIndentWidth

The number of characters to use for indentation of ObjC blocks.

bool AllowShortLoopsOnASingleLine

If true, while (true) continue; can be put on a single line.

int AccessModifierOffset

The extra indent or outdent of access modifiers, e.g.

std::vector< std::string > QualifierOrder

The order in which the qualifiers appear.

bool AllowShortEnumsOnASingleLine

Allow short enums on a single line.

@ SBS_Empty

Only merge empty blocks.

@ SBS_Never

Never merge blocks into a single line.

std::optional< FormatStyle > GetLanguageStyle(LanguageKind Language) const

std::vector< std::string > IfMacros

A vector of macros that should be interpreted as conditionals instead of as function calls.

NamespaceIndentationKind NamespaceIndentation

The indentation used for namespaces.

bool BreakArrays

If true, clang-format will always break after a Json array [ otherwise it will scan until the closing...

bool BreakAfterJavaFieldAnnotations

Break after each annotation on a field in Java files.

@ SIS_WithoutElse

Put short ifs on the same line only if there is no else statement.

@ SIS_Never

Never put short ifs on the same line.

std::optional< unsigned > BracedInitializerIndentWidth

The number of columns to use to indent the contents of braced init lists.

std::vector< std::string > ObjCPropertyAttributeOrder

The order in which ObjC property attributes should appear.

bool ExperimentalAutoDetectBinPacking

If true, clang-format detects whether function calls and definitions are formatted with one parameter...

bool ObjCBreakBeforeNestedBlockParam

Break parameters list into lines when there is nested block parameters in a function call.

OperandAlignmentStyle AlignOperands

If true, horizontally align operands of binary and ternary expressions.

unsigned PenaltyBreakOpenParenthesis

The penalty for breaking after (.

@ BTDS_MultiLine

Force break after template declaration only when the following declaration spans multiple lines.

@ BTDS_Yes

Always break after template declaration.

bool AllowShortCompoundRequirementOnASingleLine

Allow short compound requirement on a single line.

friend std::error_code parseConfiguration(llvm::MemoryBufferRef Config, FormatStyle *Style, bool AllowUnknownOptions, llvm::SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)

Parse configuration from YAML-formatted text.

SpacesInParensStyle SpacesInParens

If true, spaces will be inserted after ( and before ).

SpacesInParensCustom SpacesInParensOptions

Control of individual spaces in parentheses.

std::vector< std::string > ForEachMacros

A vector of macros that should be interpreted as foreach loops instead of as function calls.

ReferenceAlignmentStyle ReferenceAlignment

Reference alignment style (overrides PointerAlignment for references).

BreakBinaryOperationsStyle BreakBinaryOperations

The break binary operations style to use.

AlignConsecutiveStyle AlignConsecutiveTableGenDefinitionColons

Style of aligning consecutive TableGen definition colons.

TrailingCommaStyle InsertTrailingCommas

If set to TCS_Wrapped will insert trailing commas in container literals (arrays and objects) that wra...

unsigned PenaltyBreakTemplateDeclaration

The penalty for breaking after template declaration.

SpaceBeforeParensCustom SpaceBeforeParensOptions

Control of individual space before parentheses.

BreakConstructorInitializersStyle BreakConstructorInitializers

The break constructor initializers style to use.

bool RemoveEmptyLinesInUnwrappedLines

Remove empty lines within unwrapped lines.

bool BreakStringLiterals

Allow breaking string literals when formatting.

bool SpaceAfterLogicalNot

If true, a space is inserted after the logical not operator (!).

@ SBPO_Custom

Configure each individual space before parentheses in SpaceBeforeParensOptions.

@ SBPO_NonEmptyParentheses

Put a space before opening parentheses only if the parentheses are not empty.

@ SBPO_ControlStatementsExceptControlMacros

Same as SBPO_ControlStatements except this option doesn't apply to ForEach and If macros.

@ SBPO_ControlStatements

Put a space before opening parentheses only after control statement keywords (for/if/while....

@ SBPO_Always

Always put a space before opening parentheses, except when it's prohibited by the syntax rules (in fu...

@ PCIS_BinPack

Bin-pack constructor initializers.

@ PCIS_NextLine

Same as PCIS_CurrentLine except that if all constructor initializers do not fit on the current line,...

std::vector< std::string > TypeNames

A vector of non-keyword identifiers that should be interpreted as type names.

bool ObjCSpaceAfterProperty

Add a space after @property in Objective-C, i.e.

BraceBreakingStyle BreakBeforeBraces

The brace breaking style to use.

@ BILS_BeforeColon

Break inheritance list before the colon and after the commas.

@ BILS_BeforeComma

Break inheritance list before the colon and commas, and align the commas with the colon.

unsigned PenaltyExcessCharacter

The penalty for each character outside of the column limit.

std::vector< std::string > WhitespaceSensitiveMacros

A vector of macros which are whitespace-sensitive and should not be touched.

std::vector< std::string > TemplateNames

A vector of non-keyword identifiers that should be interpreted as template names.

@ DAS_DontBreak

Never break inside DAGArg.

unsigned ConstructorInitializerIndentWidth

This option is deprecated.

@ BBNSS_Never

No line break allowed.

bool CompactNamespaces

If true, consecutive namespace declarations will be on the same line.

@ RCPS_OwnLine

Always put the requires clause on its own line (possibly followed by a semicolon).

LanguageStandard

Supported language standards for parsing and formatting C++ constructs.

@ LS_Cpp17

Parse and format as C++17.

@ LS_Latest

Parse and format using the latest supported language version.

@ LS_Cpp11

Parse and format as C++11.

@ LS_Auto

Automatic detection based on the input.

@ LS_Cpp14

Parse and format as C++14.

@ LS_Cpp20

Parse and format as C++20.

@ BWACS_Always

Always wrap braces after a control statement.

@ BWACS_Never

Never wrap braces after a control statement.

RequiresClausePositionStyle RequiresClausePosition

The position of the requires clause.

@ JSQS_Single

Always use single quotes.

@ JSQS_Leave

Leave string quotes as they are.

bool SpaceAfterCStyleCast

If true, a space is inserted after C style casts.

AlignConsecutiveStyle AlignConsecutiveBitFields

Style of aligning consecutive bit fields.

int PPIndentWidth

The number of columns to use for indentation of preprocessor statements.

AlignConsecutiveStyle AlignConsecutiveDeclarations

Style of aligning consecutive declarations.

IntegerLiteralSeparatorStyle IntegerLiteralSeparator

Format integer literal separators (' for C++ and _ for C#, Java, and JavaScript).

SpaceAroundPointerQualifiersStyle SpaceAroundPointerQualifiers

Defines in which cases to put a space before or after pointer qualifiers.

DefinitionReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType

The function definition return type breaking style to use.

bool SpaceBeforeAssignmentOperators

If false, spaces will be removed before assignment operators.

BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon

The inline ASM colon style to use.

@ WNBWELS_Leave

Keep existing newlines at the beginning and the end of namespace body.

@ BS_Mozilla

Like Attach, but break before braces on enum, function, and record definitions.

@ BS_Whitesmiths

Like Allman but always indent braces and line up code with braces.

@ BS_Allman

Always break before braces.

@ BS_Stroustrup

Like Attach, but break before function definitions, catch, and else.

@ BS_Linux

Like Attach, but break before braces on function, namespace and class definitions.

@ BS_WebKit

Like Attach, but break before functions.

@ BS_Custom

Configure each individual brace in BraceWrapping.

@ BS_GNU

Always break before braces and add an extra level of indentation to braces of control statements,...

@ BS_Attach

Always attach braces to surrounding context.

@ ABS_Leave

Leave the line breaking after attributes as is.

bool BinPackArguments

If false, a function call's arguments will either be all on the same line or will have one line each.

ShortLambdaStyle AllowShortLambdasOnASingleLine

Dependent on the value, auto lambda []() { return 0; } can be put on a single line.

unsigned PenaltyBreakScopeResolution

The penalty for breaking after ::.

unsigned PenaltyReturnTypeOnItsOwnLine

Penalty for putting the return type of a function onto its own line.

@ BFCS_Both

Add one space on each side of the :

PointerAlignmentStyle PointerAlignment

Pointer and reference alignment style.

@ SFS_Inline

Only merge functions defined inside a class.

@ SFS_All

Merge all functions fitting on a single line.

@ SFS_Empty

Only merge empty functions.

@ SFS_None

Never merge functions into a single line.

bool BreakFunctionDefinitionParameters

If true, clang-format will always break before function definition parameters.

@ REI_OuterScope

Align requires expression body relative to the indentation level of the outer scope the requires expr...

PackConstructorInitializersStyle PackConstructorInitializers

The pack constructor initializers style to use.

@ BBCDS_Always

Always break before concept, putting it in the line after the template declaration.

ReflowCommentsStyle ReflowComments

Comment reformatting style.

KeepEmptyLinesStyle KeepEmptyLines

Which empty lines are kept.

bool AllowAllParametersOfDeclarationOnNextLine

This option is deprecated.

BracketAlignmentStyle AlignAfterOpenBracket

If true, horizontally aligns arguments after an open bracket.

AlignConsecutiveStyle AlignConsecutiveTableGenCondOperatorColons

Style of aligning consecutive TableGen cond operator colons.

BinPackParametersStyle BinPackParameters

The bin pack parameters style to use.

bool AllowShortCaseExpressionOnASingleLine

Whether to merge a short switch labeled rule into a single line.

unsigned MaxEmptyLinesToKeep

The maximum number of consecutive empty lines to keep.

bool SpaceBeforeSquareBrackets

If true, spaces will be before [.

BinPackStyle ObjCBinPackProtocolList

Controls bin-packing Objective-C protocol conformance list items into as few lines as possible when t...

ShortCaseStatementsAlignmentStyle AlignConsecutiveShortCaseStatements

Style of aligning consecutive short case labels.

EscapedNewlineAlignmentStyle AlignEscapedNewlines

Options for aligning backslashes in escaped newlines.

SpacesInLineComment SpacesInLineCommentPrefix

How many spaces are allowed at the start of a line comment.

std::string CommentPragmas

A regular expression that describes comments with special meaning, which should not be split into lin...

bool isJavaScript() const

DAGArgStyle TableGenBreakInsideDAGArg

The styles of the line break inside the DAGArg in TableGen.

JavaScriptQuoteStyle JavaScriptQuotes

The JavaScriptQuoteStyle to use for JavaScript strings.

bool SpacesInContainerLiterals

If true, spaces will be inserted around if/for/switch/while conditions.

SortJavaStaticImportOptions SortJavaStaticImport

When sorting Java imports, by default static imports are placed before non-static imports.

@ SAPQ_Default

Don't ensure spaces around pointer qualifiers and use PointerAlignment instead.

bool SpaceBeforeRangeBasedForLoopColon

If false, spaces will be removed before range-based for loop colon.

bool DisableFormat

Disables formatting completely.

@ ELAAMS_Never

Remove all empty lines after access modifiers.

@ DRTBS_All

Always break after the return type.

@ DRTBS_TopLevel

Always break after the return types of top-level functions.

@ DRTBS_None

Break after return type automatically.

bool AllowShortNamespacesOnASingleLine

If true, namespace a { class b; } can be put on a single line.

std::vector< std::string > NamespaceMacros

A vector of macros which are used to open namespace blocks.

AttributeBreakingStyle BreakAfterAttributes

Break after a group of C++11 attributes before variable or function (including constructor/destructor...

TrailingCommentsAlignmentStyle AlignTrailingComments

Control of trailing comments.

@ AIAS_None

Don't align array initializer columns.

LambdaBodyIndentationKind LambdaBodyIndentation

The indentation style of lambda bodies.

QualifierAlignmentStyle QualifierAlignment

Different ways to arrange specifiers and qualifiers (e.g.

@ BBO_Never

Don't break binary operations.

bool IndentGotoLabels

Indent goto labels.

BraceWrappingFlags BraceWrapping

Control of individual brace wrapping cases.

@ ENAS_Left

Align escaped newlines as far left as possible.

@ ENAS_Right

Align escaped newlines in the right-most column.

AlignConsecutiveStyle AlignConsecutiveMacros

Style of aligning consecutive macro definitions.

std::vector< std::string > StatementMacros

A vector of macros that should be interpreted as complete statements.

@ SIAS_Never

Remove spaces after < and before >.

@ SUD_LexicographicNumeric

Using declarations are sorted in the order defined as follows: Split the strings by :: and discard an...

@ SUD_Never

Using declarations are never sorted.

AlignConsecutiveStyle AlignConsecutiveAssignments

Style of aligning consecutive assignments.

ShortIfStyle AllowShortIfStatementsOnASingleLine

Dependent on the value, if (a) return; can be put on a single line.

@ RPS_Leave

Do not remove parentheses.

@ RPS_ReturnStatement

Also remove parentheses enclosing the expression in a return/co_return statement.

std::vector< std::string > TableGenBreakingDAGArgOperators

Works only when TableGenBreakInsideDAGArg is not DontBreak.

EmptyLineBeforeAccessModifierStyle EmptyLineBeforeAccessModifier

Defines in which cases to put empty line before access modifiers.

bool SpaceBeforeCaseColon

If false, spaces will be removed before case colon.

BreakBeforeNoexceptSpecifierStyle AllowBreakBeforeNoexceptSpecifier

Controls if there could be a line break before a noexcept specifier.

bool JavaScriptWrapImports

Whether to wrap JavaScript import/export statements.

bool SkipMacroDefinitionBody

Do not format macro definition body.

unsigned PenaltyBreakAssignment

The penalty for breaking around an assignment operator.

@ PAS_Left

Align pointer to the left.

@ PAS_Right

Align pointer to the right.

unsigned PenaltyBreakString

The penalty for each line break introduced inside a string literal.

RequiresExpressionIndentationKind RequiresExpressionIndentation

The indentation used for requires expression bodies.

bool SpaceAfterTemplateKeyword

If true, a space will be inserted after the template keyword.

unsigned PenaltyIndentedWhitespace

Penalty for each character of whitespace indentation (counted relative to leading non-whitespace colu...

ArrayInitializerAlignmentStyle AlignArrayOfStructures

If not None, when using initialization for an array of structs aligns the fields into columns.

@ NI_None

Don't indent in namespaces.

@ NI_All

Indent in all namespaces.

@ NI_Inner

Indent only in inner namespaces (nested in other namespaces).

ShortBlockStyle AllowShortBlocksOnASingleLine

Dependent on the value, while (true) { continue; } can be put on a single line.

std::string MacroBlockEnd

A regular expression matching macros that end a block.

ShortFunctionStyle AllowShortFunctionsOnASingleLine

Dependent on the value, int f() { return 0; } can be put on a single line.

bool AllowAllArgumentsOnNextLine

If a function call or braced initializer list doesn't fit on a line, allow putting all arguments onto...

unsigned PenaltyBreakComment

The penalty for each line break introduced inside a comment.

bool InheritsParentConfig

@ RTBS_TopLevel

Always break after the return types of top-level functions.

@ RTBS_None

This is deprecated. See Automatic below.

@ RTBS_AllDefinitions

Always break after the return type of function definitions.

@ RAS_Pointer

Align reference like PointerAlignment.

EmptyLineAfterAccessModifierStyle EmptyLineAfterAccessModifier

Defines when to put an empty line after access modifiers.

bool IndentAccessModifiers

Specify whether access modifiers should have their own indentation level.

bool InsertNewlineAtEOF

Insert a newline at end of file if missing.

SpaceBeforeParensStyle SpaceBeforeParens

Defines in which cases to put a space before opening parentheses.

bool SpaceBeforeCpp11BracedList

If true, a space will be inserted before a C++11 braced list used to initialize an object (after the ...

UseTabStyle UseTab

The way to use tab characters in the resulting file.

@ QAS_Leave

Don't change specifiers/qualifiers to either Left or Right alignment (default).

std::vector< std::string > TypenameMacros

A vector of macros that should be interpreted as type declarations instead of as function calls.

@ OAS_Align

Horizontally align operands of binary and ternary expressions.

@ OAS_DontAlign

Do not align operands of binary and ternary expressions.

LineEndingStyle LineEnding

Line ending style (\n or \r\n) to use.

bool BreakBeforeTernaryOperators

If true, ternary operators will be placed after line breaks.

unsigned ShortNamespaceLines

The maximal number of unwrapped lines that a short namespace spans.

SortUsingDeclarationsOptions SortUsingDeclarations

Controls if and how clang-format will sort using declarations.

IndentExternBlockStyle IndentExternBlock

IndentExternBlockStyle is the type of indenting of extern blocks.

SeparateDefinitionStyle SeparateDefinitionBlocks

Specifies the use of empty lines to separate definition blocks, including classes,...

tooling::IncludeStyle IncludeStyle

unsigned ColumnLimit

The column limit.

Represents the status of a formatting attempt.

static FormatStyle & element(IO &IO, std::vector< FormatStyle > &Seq, size_t Index)

static size_t size(IO &IO, std::vector< FormatStyle > &Seq)

static void mapping(IO &IO, FormatStyle &Style)

static void enumInput(IO &IO, FormatStyle::AlignConsecutiveStyle &Value)

static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &Value)

static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping)

static void mapping(IO &IO, FormatStyle::IntegerLiteralSeparatorStyle &Base)

static void mapping(IO &IO, FormatStyle::KeepEmptyLinesStyle &Value)

static void mapping(IO &IO, FormatStyle::RawStringFormat &Format)

static void mapping(IO &IO, FormatStyle::ShortCaseStatementsAlignmentStyle &Value)

static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing)

static void mapping(IO &IO, FormatStyle::SpacesInParensCustom &Spaces)

static void enumeration(IO &IO, FormatStyle::ArrayInitializerAlignmentStyle &Value)

static void enumeration(IO &IO, FormatStyle::AttributeBreakingStyle &Value)

static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value)

static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value)

static void enumeration(IO &IO, FormatStyle::BitFieldColonSpacingStyle &Value)

static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value)

static void enumeration(IO &IO, FormatStyle::BraceWrappingAfterControlStatementStyle &Value)

static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value)

static void enumeration(IO &IO, FormatStyle::BreakBeforeConceptDeclarationsStyle &Value)

static void enumeration(IO &IO, FormatStyle::BreakBeforeInlineASMColonStyle &Value)

static void enumeration(IO &IO, FormatStyle::BreakBeforeNoexceptSpecifierStyle &Value)

static void enumeration(IO &IO, FormatStyle::BreakBinaryOperationsStyle &Value)

static void enumeration(IO &IO, FormatStyle::BreakInheritanceListStyle &Value)

static void enumeration(IO &IO, FormatStyle::BreakTemplateDeclarationsStyle &Value)

static void enumeration(IO &IO, FormatStyle::DAGArgStyle &Value)

static void enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value)

static void enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value)

static void enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value)

static void enumeration(IO &IO, FormatStyle::EscapedNewlineAlignmentStyle &Value)

static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value)

static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value)

static void enumeration(IO &IO, FormatStyle::LambdaBodyIndentationKind &Value)

static void enumeration(IO &IO, FormatStyle::LanguageKind &Value)

static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value)

static void enumeration(IO &IO, FormatStyle::LineEndingStyle &Value)

static void enumeration(IO &IO, FormatStyle::NamespaceIndentationKind &Value)

static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value)

static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value)

static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value)

static void enumeration(IO &IO, FormatStyle::QualifierAlignmentStyle &Value)

static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value)

static void enumeration(IO &IO, FormatStyle::RemoveParenthesesStyle &Value)

static void enumeration(IO &IO, FormatStyle::RequiresClausePositionStyle &Value)

static void enumeration(IO &IO, FormatStyle::RequiresExpressionIndentationKind &Value)

static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value)

static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value)

static void enumeration(IO &IO, FormatStyle::ShortBlockStyle &Value)

static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value)

static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value)

static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value)

static void enumeration(IO &IO, FormatStyle::SortIncludesOptions &Value)

static void enumeration(IO &IO, FormatStyle::SortJavaStaticImportOptions &Value)

static void enumeration(IO &IO, FormatStyle::SortUsingDeclarationsOptions &Value)

static void enumeration(IO &IO, FormatStyle::SpaceBeforeParensStyle &Value)

static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value)

static void enumeration(IO &IO, FormatStyle::SpacesInParensStyle &Value)

static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value)

static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value)

static void enumeration(IO &IO, FormatStyle::WrapNamespaceBodyWithEmptyLinesStyle &Value)