1 //===--- Format.cpp - Format C++ code -------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file implements functions declared in Format.h. This will be 11 /// split into separate files as we go. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/Format/Format.h" 16 #include "AffectedRangeManager.h" 17 #include "BreakableToken.h" 18 #include "ContinuationIndenter.h" 19 #include "DefinitionBlockSeparator.h" 20 #include "FormatInternal.h" 21 #include "FormatToken.h" 22 #include "FormatTokenLexer.h" 23 #include "NamespaceEndCommentsFixer.h" 24 #include "QualifierAlignmentFixer.h" 25 #include "SortJavaScriptImports.h" 26 #include "TokenAnalyzer.h" 27 #include "TokenAnnotator.h" 28 #include "UnwrappedLineFormatter.h" 29 #include "UnwrappedLineParser.h" 30 #include "UsingDeclarationsSorter.h" 31 #include "WhitespaceManager.h" 32 #include "clang/Basic/Diagnostic.h" 33 #include "clang/Basic/DiagnosticOptions.h" 34 #include "clang/Basic/SourceManager.h" 35 #include "clang/Lex/Lexer.h" 36 #include "clang/Tooling/Inclusions/HeaderIncludes.h" 37 #include "llvm/ADT/STLExtras.h" 38 #include "llvm/ADT/Sequence.h" 39 #include "llvm/ADT/StringRef.h" 40 #include "llvm/Support/Allocator.h" 41 #include "llvm/Support/Debug.h" 42 #include "llvm/Support/Path.h" 43 #include "llvm/Support/Regex.h" 44 #include "llvm/Support/VirtualFileSystem.h" 45 #include "llvm/Support/YAMLTraits.h" 46 #include <algorithm> 47 #include <memory> 48 #include <mutex> 49 #include <string> 50 #include <unordered_map> 51 52 #define DEBUG_TYPE "format-formatter" 53 54 using clang::format::FormatStyle; 55 56 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::format::FormatStyle::RawStringFormat) 57 58 namespace llvm { 59 namespace yaml { 60 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> { 61 static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) { 62 IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp); 63 IO.enumCase(Value, "Java", FormatStyle::LK_Java); 64 IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript); 65 IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC); 66 IO.enumCase(Value, "Proto", FormatStyle::LK_Proto); 67 IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen); 68 IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto); 69 IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp); 70 IO.enumCase(Value, "Json", FormatStyle::LK_Json); 71 } 72 }; 73 74 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> { 75 static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) { 76 IO.enumCase(Value, "c++03", FormatStyle::LS_Cpp03); 77 IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03); // Legacy alias 78 IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03); // Legacy alias 79 80 IO.enumCase(Value, "c++11", FormatStyle::LS_Cpp11); 81 IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11); // Legacy alias 82 83 IO.enumCase(Value, "c++14", FormatStyle::LS_Cpp14); 84 IO.enumCase(Value, "c++17", FormatStyle::LS_Cpp17); 85 IO.enumCase(Value, "c++20", FormatStyle::LS_Cpp20); 86 87 IO.enumCase(Value, "Latest", FormatStyle::LS_Latest); 88 IO.enumCase(Value, "Cpp11", FormatStyle::LS_Latest); // Legacy alias 89 IO.enumCase(Value, "Auto", FormatStyle::LS_Auto); 90 } 91 }; 92 93 template <> 94 struct ScalarEnumerationTraits<FormatStyle::LambdaBodyIndentationKind> { 95 static void enumeration(IO &IO, 96 FormatStyle::LambdaBodyIndentationKind &Value) { 97 IO.enumCase(Value, "Signature", FormatStyle::LBI_Signature); 98 IO.enumCase(Value, "OuterScope", FormatStyle::LBI_OuterScope); 99 } 100 }; 101 102 template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> { 103 static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) { 104 IO.enumCase(Value, "Never", FormatStyle::UT_Never); 105 IO.enumCase(Value, "false", FormatStyle::UT_Never); 106 IO.enumCase(Value, "Always", FormatStyle::UT_Always); 107 IO.enumCase(Value, "true", FormatStyle::UT_Always); 108 IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation); 109 IO.enumCase(Value, "ForContinuationAndIndentation", 110 FormatStyle::UT_ForContinuationAndIndentation); 111 IO.enumCase(Value, "AlignWithSpaces", FormatStyle::UT_AlignWithSpaces); 112 } 113 }; 114 115 template <> struct ScalarEnumerationTraits<FormatStyle::JavaScriptQuoteStyle> { 116 static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value) { 117 IO.enumCase(Value, "Leave", FormatStyle::JSQS_Leave); 118 IO.enumCase(Value, "Single", FormatStyle::JSQS_Single); 119 IO.enumCase(Value, "Double", FormatStyle::JSQS_Double); 120 } 121 }; 122 123 template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> { 124 static void enumeration(IO &IO, FormatStyle::ShortBlockStyle &Value) { 125 IO.enumCase(Value, "Never", FormatStyle::SBS_Never); 126 IO.enumCase(Value, "false", FormatStyle::SBS_Never); 127 IO.enumCase(Value, "Always", FormatStyle::SBS_Always); 128 IO.enumCase(Value, "true", FormatStyle::SBS_Always); 129 IO.enumCase(Value, "Empty", FormatStyle::SBS_Empty); 130 } 131 }; 132 133 template <> 134 struct ScalarEnumerationTraits<FormatStyle::QualifierAlignmentStyle> { 135 static void enumeration(IO &IO, FormatStyle::QualifierAlignmentStyle &Value) { 136 IO.enumCase(Value, "Leave", FormatStyle::QAS_Leave); 137 IO.enumCase(Value, "Left", FormatStyle::QAS_Left); 138 IO.enumCase(Value, "Right", FormatStyle::QAS_Right); 139 IO.enumCase(Value, "Custom", FormatStyle::QAS_Custom); 140 } 141 }; 142 143 template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> { 144 static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) { 145 IO.enumCase(Value, "None", FormatStyle::SFS_None); 146 IO.enumCase(Value, "false", FormatStyle::SFS_None); 147 IO.enumCase(Value, "All", FormatStyle::SFS_All); 148 IO.enumCase(Value, "true", FormatStyle::SFS_All); 149 IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline); 150 IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly); 151 IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty); 152 } 153 }; 154 155 template <> struct MappingTraits<FormatStyle::AlignConsecutiveStyle> { 156 static void enumInput(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) { 157 IO.enumCase(Value, "None", 158 FormatStyle::AlignConsecutiveStyle( 159 {/*Enabled=*/false, /*AcrossEmptyLines=*/false, 160 /*AcrossComments=*/false, /*AlignCompound=*/false, 161 /*PadOperators=*/true})); 162 IO.enumCase(Value, "Consecutive", 163 FormatStyle::AlignConsecutiveStyle( 164 {/*Enabled=*/true, /*AcrossEmptyLines=*/false, 165 /*AcrossComments=*/false, /*AlignCompound=*/false, 166 /*PadOperators=*/true})); 167 IO.enumCase(Value, "AcrossEmptyLines", 168 FormatStyle::AlignConsecutiveStyle( 169 {/*Enabled=*/true, /*AcrossEmptyLines=*/true, 170 /*AcrossComments=*/false, /*AlignCompound=*/false, 171 /*PadOperators=*/true})); 172 IO.enumCase(Value, "AcrossComments", 173 FormatStyle::AlignConsecutiveStyle({/*Enabled=*/true, 174 /*AcrossEmptyLines=*/false, 175 /*AcrossComments=*/true, 176 /*AlignCompound=*/false, 177 /*PadOperators=*/true})); 178 IO.enumCase(Value, "AcrossEmptyLinesAndComments", 179 FormatStyle::AlignConsecutiveStyle({/*Enabled=*/true, 180 /*AcrossEmptyLines=*/true, 181 /*AcrossComments=*/true, 182 /*AlignCompound=*/false, 183 /*PadOperators=*/true})); 184 185 // For backward compatibility. 186 IO.enumCase(Value, "true", 187 FormatStyle::AlignConsecutiveStyle( 188 {/*Enabled=*/true, /*AcrossEmptyLines=*/false, 189 /*AcrossComments=*/false, /*AlignCompound=*/false, 190 /*PadOperators=*/true})); 191 IO.enumCase(Value, "false", 192 FormatStyle::AlignConsecutiveStyle( 193 {/*Enabled=*/false, /*AcrossEmptyLines=*/false, 194 /*AcrossComments=*/false, /*AlignCompound=*/false, 195 /*PadOperators=*/true})); 196 } 197 198 static void mapping(IO &IO, FormatStyle::AlignConsecutiveStyle &Value) { 199 IO.mapOptional("Enabled", Value.Enabled); 200 IO.mapOptional("AcrossEmptyLines", Value.AcrossEmptyLines); 201 IO.mapOptional("AcrossComments", Value.AcrossComments); 202 IO.mapOptional("AlignCompound", Value.AlignCompound); 203 IO.mapOptional("PadOperators", Value.PadOperators); 204 } 205 }; 206 207 template <> 208 struct ScalarEnumerationTraits<FormatStyle::ArrayInitializerAlignmentStyle> { 209 static void enumeration(IO &IO, 210 FormatStyle::ArrayInitializerAlignmentStyle &Value) { 211 IO.enumCase(Value, "None", FormatStyle::AIAS_None); 212 IO.enumCase(Value, "Left", FormatStyle::AIAS_Left); 213 IO.enumCase(Value, "Right", FormatStyle::AIAS_Right); 214 } 215 }; 216 217 template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> { 218 static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) { 219 IO.enumCase(Value, "Never", FormatStyle::SIS_Never); 220 IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse); 221 IO.enumCase(Value, "OnlyFirstIf", FormatStyle::SIS_OnlyFirstIf); 222 IO.enumCase(Value, "AllIfsAndElse", FormatStyle::SIS_AllIfsAndElse); 223 224 // For backward compatibility. 225 IO.enumCase(Value, "Always", FormatStyle::SIS_OnlyFirstIf); 226 IO.enumCase(Value, "false", FormatStyle::SIS_Never); 227 IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse); 228 } 229 }; 230 231 template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> { 232 static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value) { 233 IO.enumCase(Value, "None", FormatStyle::SLS_None); 234 IO.enumCase(Value, "false", FormatStyle::SLS_None); 235 IO.enumCase(Value, "Empty", FormatStyle::SLS_Empty); 236 IO.enumCase(Value, "Inline", FormatStyle::SLS_Inline); 237 IO.enumCase(Value, "All", FormatStyle::SLS_All); 238 IO.enumCase(Value, "true", FormatStyle::SLS_All); 239 } 240 }; 241 242 template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> { 243 static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value) { 244 IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto); 245 IO.enumCase(Value, "Always", FormatStyle::BPS_Always); 246 IO.enumCase(Value, "Never", FormatStyle::BPS_Never); 247 } 248 }; 249 250 template <> struct ScalarEnumerationTraits<FormatStyle::TrailingCommaStyle> { 251 static void enumeration(IO &IO, FormatStyle::TrailingCommaStyle &Value) { 252 IO.enumCase(Value, "None", FormatStyle::TCS_None); 253 IO.enumCase(Value, "Wrapped", FormatStyle::TCS_Wrapped); 254 } 255 }; 256 257 template <> struct ScalarEnumerationTraits<FormatStyle::BinaryOperatorStyle> { 258 static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) { 259 IO.enumCase(Value, "All", FormatStyle::BOS_All); 260 IO.enumCase(Value, "true", FormatStyle::BOS_All); 261 IO.enumCase(Value, "None", FormatStyle::BOS_None); 262 IO.enumCase(Value, "false", FormatStyle::BOS_None); 263 IO.enumCase(Value, "NonAssignment", FormatStyle::BOS_NonAssignment); 264 } 265 }; 266 267 template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> { 268 static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) { 269 IO.enumCase(Value, "Attach", FormatStyle::BS_Attach); 270 IO.enumCase(Value, "Linux", FormatStyle::BS_Linux); 271 IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla); 272 IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup); 273 IO.enumCase(Value, "Allman", FormatStyle::BS_Allman); 274 IO.enumCase(Value, "Whitesmiths", FormatStyle::BS_Whitesmiths); 275 IO.enumCase(Value, "GNU", FormatStyle::BS_GNU); 276 IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit); 277 IO.enumCase(Value, "Custom", FormatStyle::BS_Custom); 278 } 279 }; 280 281 template <> 282 struct ScalarEnumerationTraits< 283 FormatStyle::BraceWrappingAfterControlStatementStyle> { 284 static void 285 enumeration(IO &IO, 286 FormatStyle::BraceWrappingAfterControlStatementStyle &Value) { 287 IO.enumCase(Value, "Never", FormatStyle::BWACS_Never); 288 IO.enumCase(Value, "MultiLine", FormatStyle::BWACS_MultiLine); 289 IO.enumCase(Value, "Always", FormatStyle::BWACS_Always); 290 291 // For backward compatibility. 292 IO.enumCase(Value, "false", FormatStyle::BWACS_Never); 293 IO.enumCase(Value, "true", FormatStyle::BWACS_Always); 294 } 295 }; 296 297 template <> 298 struct ScalarEnumerationTraits< 299 FormatStyle::BreakBeforeConceptDeclarationsStyle> { 300 static void 301 enumeration(IO &IO, FormatStyle::BreakBeforeConceptDeclarationsStyle &Value) { 302 IO.enumCase(Value, "Never", FormatStyle::BBCDS_Never); 303 IO.enumCase(Value, "Allowed", FormatStyle::BBCDS_Allowed); 304 IO.enumCase(Value, "Always", FormatStyle::BBCDS_Always); 305 306 // For backward compatibility. 307 IO.enumCase(Value, "true", FormatStyle::BBCDS_Always); 308 IO.enumCase(Value, "false", FormatStyle::BBCDS_Allowed); 309 } 310 }; 311 312 template <> 313 struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> { 314 static void 315 enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value) { 316 IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon); 317 IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma); 318 IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon); 319 } 320 }; 321 322 template <> 323 struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> { 324 static void enumeration(IO &IO, 325 FormatStyle::BreakInheritanceListStyle &Value) { 326 IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon); 327 IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma); 328 IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon); 329 IO.enumCase(Value, "AfterComma", FormatStyle::BILS_AfterComma); 330 } 331 }; 332 333 template <> 334 struct ScalarEnumerationTraits<FormatStyle::PackConstructorInitializersStyle> { 335 static void 336 enumeration(IO &IO, FormatStyle::PackConstructorInitializersStyle &Value) { 337 IO.enumCase(Value, "Never", FormatStyle::PCIS_Never); 338 IO.enumCase(Value, "BinPack", FormatStyle::PCIS_BinPack); 339 IO.enumCase(Value, "CurrentLine", FormatStyle::PCIS_CurrentLine); 340 IO.enumCase(Value, "NextLine", FormatStyle::PCIS_NextLine); 341 } 342 }; 343 344 template <> 345 struct ScalarEnumerationTraits<FormatStyle::EmptyLineAfterAccessModifierStyle> { 346 static void 347 enumeration(IO &IO, FormatStyle::EmptyLineAfterAccessModifierStyle &Value) { 348 IO.enumCase(Value, "Never", FormatStyle::ELAAMS_Never); 349 IO.enumCase(Value, "Leave", FormatStyle::ELAAMS_Leave); 350 IO.enumCase(Value, "Always", FormatStyle::ELAAMS_Always); 351 } 352 }; 353 354 template <> 355 struct ScalarEnumerationTraits< 356 FormatStyle::EmptyLineBeforeAccessModifierStyle> { 357 static void 358 enumeration(IO &IO, FormatStyle::EmptyLineBeforeAccessModifierStyle &Value) { 359 IO.enumCase(Value, "Never", FormatStyle::ELBAMS_Never); 360 IO.enumCase(Value, "Leave", FormatStyle::ELBAMS_Leave); 361 IO.enumCase(Value, "LogicalBlock", FormatStyle::ELBAMS_LogicalBlock); 362 IO.enumCase(Value, "Always", FormatStyle::ELBAMS_Always); 363 } 364 }; 365 366 template <> 367 struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> { 368 static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) { 369 IO.enumCase(Value, "None", FormatStyle::PPDIS_None); 370 IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash); 371 IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash); 372 } 373 }; 374 375 template <> 376 struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> { 377 static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) { 378 IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock); 379 IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent); 380 IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent); 381 IO.enumCase(Value, "true", FormatStyle::IEBS_Indent); 382 IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent); 383 } 384 }; 385 386 template <> 387 struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> { 388 static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) { 389 IO.enumCase(Value, "None", FormatStyle::RTBS_None); 390 IO.enumCase(Value, "All", FormatStyle::RTBS_All); 391 IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel); 392 IO.enumCase(Value, "TopLevelDefinitions", 393 FormatStyle::RTBS_TopLevelDefinitions); 394 IO.enumCase(Value, "AllDefinitions", FormatStyle::RTBS_AllDefinitions); 395 } 396 }; 397 398 template <> 399 struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> { 400 static void enumeration(IO &IO, 401 FormatStyle::BreakTemplateDeclarationsStyle &Value) { 402 IO.enumCase(Value, "No", FormatStyle::BTDS_No); 403 IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine); 404 IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes); 405 406 // For backward compatibility. 407 IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine); 408 IO.enumCase(Value, "true", FormatStyle::BTDS_Yes); 409 } 410 }; 411 412 template <> 413 struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> { 414 static void 415 enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) { 416 IO.enumCase(Value, "None", FormatStyle::DRTBS_None); 417 IO.enumCase(Value, "All", FormatStyle::DRTBS_All); 418 IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel); 419 420 // For backward compatibility. 421 IO.enumCase(Value, "false", FormatStyle::DRTBS_None); 422 IO.enumCase(Value, "true", FormatStyle::DRTBS_All); 423 } 424 }; 425 426 template <> 427 struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> { 428 static void enumeration(IO &IO, 429 FormatStyle::NamespaceIndentationKind &Value) { 430 IO.enumCase(Value, "None", FormatStyle::NI_None); 431 IO.enumCase(Value, "Inner", FormatStyle::NI_Inner); 432 IO.enumCase(Value, "All", FormatStyle::NI_All); 433 } 434 }; 435 436 template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> { 437 static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) { 438 IO.enumCase(Value, "Align", FormatStyle::BAS_Align); 439 IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign); 440 IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak); 441 IO.enumCase(Value, "BlockIndent", FormatStyle::BAS_BlockIndent); 442 443 // For backward compatibility. 444 IO.enumCase(Value, "true", FormatStyle::BAS_Align); 445 IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign); 446 } 447 }; 448 449 template <> 450 struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> { 451 static void enumeration(IO &IO, 452 FormatStyle::EscapedNewlineAlignmentStyle &Value) { 453 IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign); 454 IO.enumCase(Value, "Left", FormatStyle::ENAS_Left); 455 IO.enumCase(Value, "Right", FormatStyle::ENAS_Right); 456 457 // For backward compatibility. 458 IO.enumCase(Value, "true", FormatStyle::ENAS_Left); 459 IO.enumCase(Value, "false", FormatStyle::ENAS_Right); 460 } 461 }; 462 463 template <> struct ScalarEnumerationTraits<FormatStyle::OperandAlignmentStyle> { 464 static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value) { 465 IO.enumCase(Value, "DontAlign", FormatStyle::OAS_DontAlign); 466 IO.enumCase(Value, "Align", FormatStyle::OAS_Align); 467 IO.enumCase(Value, "AlignAfterOperator", 468 FormatStyle::OAS_AlignAfterOperator); 469 470 // For backward compatibility. 471 IO.enumCase(Value, "true", FormatStyle::OAS_Align); 472 IO.enumCase(Value, "false", FormatStyle::OAS_DontAlign); 473 } 474 }; 475 476 template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> { 477 static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) { 478 IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle); 479 IO.enumCase(Value, "Left", FormatStyle::PAS_Left); 480 IO.enumCase(Value, "Right", FormatStyle::PAS_Right); 481 482 // For backward compatibility. 483 IO.enumCase(Value, "true", FormatStyle::PAS_Left); 484 IO.enumCase(Value, "false", FormatStyle::PAS_Right); 485 } 486 }; 487 488 template <> 489 struct ScalarEnumerationTraits<FormatStyle::SeparateDefinitionStyle> { 490 static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value) { 491 IO.enumCase(Value, "Leave", FormatStyle::SDS_Leave); 492 IO.enumCase(Value, "Always", FormatStyle::SDS_Always); 493 IO.enumCase(Value, "Never", FormatStyle::SDS_Never); 494 } 495 }; 496 497 template <> 498 struct ScalarEnumerationTraits<FormatStyle::SpaceAroundPointerQualifiersStyle> { 499 static void 500 enumeration(IO &IO, FormatStyle::SpaceAroundPointerQualifiersStyle &Value) { 501 IO.enumCase(Value, "Default", FormatStyle::SAPQ_Default); 502 IO.enumCase(Value, "Before", FormatStyle::SAPQ_Before); 503 IO.enumCase(Value, "After", FormatStyle::SAPQ_After); 504 IO.enumCase(Value, "Both", FormatStyle::SAPQ_Both); 505 } 506 }; 507 508 template <> 509 struct ScalarEnumerationTraits<FormatStyle::ReferenceAlignmentStyle> { 510 static void enumeration(IO &IO, FormatStyle::ReferenceAlignmentStyle &Value) { 511 IO.enumCase(Value, "Pointer", FormatStyle::RAS_Pointer); 512 IO.enumCase(Value, "Middle", FormatStyle::RAS_Middle); 513 IO.enumCase(Value, "Left", FormatStyle::RAS_Left); 514 IO.enumCase(Value, "Right", FormatStyle::RAS_Right); 515 } 516 }; 517 518 template <> 519 struct ScalarEnumerationTraits<FormatStyle::RequiresClausePositionStyle> { 520 static void enumeration(IO &IO, 521 FormatStyle::RequiresClausePositionStyle &Value) { 522 IO.enumCase(Value, "OwnLine", FormatStyle::RCPS_OwnLine); 523 IO.enumCase(Value, "WithPreceding", FormatStyle::RCPS_WithPreceding); 524 IO.enumCase(Value, "WithFollowing", FormatStyle::RCPS_WithFollowing); 525 IO.enumCase(Value, "SingleLine", FormatStyle::RCPS_SingleLine); 526 } 527 }; 528 529 template <> 530 struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensStyle> { 531 static void enumeration(IO &IO, FormatStyle::SpaceBeforeParensStyle &Value) { 532 IO.enumCase(Value, "Never", FormatStyle::SBPO_Never); 533 IO.enumCase(Value, "ControlStatements", 534 FormatStyle::SBPO_ControlStatements); 535 IO.enumCase(Value, "ControlStatementsExceptControlMacros", 536 FormatStyle::SBPO_ControlStatementsExceptControlMacros); 537 IO.enumCase(Value, "NonEmptyParentheses", 538 FormatStyle::SBPO_NonEmptyParentheses); 539 IO.enumCase(Value, "Always", FormatStyle::SBPO_Always); 540 IO.enumCase(Value, "Custom", FormatStyle::SBPO_Custom); 541 542 // For backward compatibility. 543 IO.enumCase(Value, "false", FormatStyle::SBPO_Never); 544 IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements); 545 IO.enumCase(Value, "ControlStatementsExceptForEachMacros", 546 FormatStyle::SBPO_ControlStatementsExceptControlMacros); 547 } 548 }; 549 550 template <> 551 struct ScalarEnumerationTraits<FormatStyle::BitFieldColonSpacingStyle> { 552 static void enumeration(IO &IO, 553 FormatStyle::BitFieldColonSpacingStyle &Value) { 554 IO.enumCase(Value, "Both", FormatStyle::BFCS_Both); 555 IO.enumCase(Value, "None", FormatStyle::BFCS_None); 556 IO.enumCase(Value, "Before", FormatStyle::BFCS_Before); 557 IO.enumCase(Value, "After", FormatStyle::BFCS_After); 558 } 559 }; 560 561 template <> struct ScalarEnumerationTraits<FormatStyle::SortIncludesOptions> { 562 static void enumeration(IO &IO, FormatStyle::SortIncludesOptions &Value) { 563 IO.enumCase(Value, "Never", FormatStyle::SI_Never); 564 IO.enumCase(Value, "CaseInsensitive", FormatStyle::SI_CaseInsensitive); 565 IO.enumCase(Value, "CaseSensitive", FormatStyle::SI_CaseSensitive); 566 567 // For backward compatibility. 568 IO.enumCase(Value, "false", FormatStyle::SI_Never); 569 IO.enumCase(Value, "true", FormatStyle::SI_CaseSensitive); 570 } 571 }; 572 573 template <> 574 struct ScalarEnumerationTraits<FormatStyle::SortJavaStaticImportOptions> { 575 static void enumeration(IO &IO, 576 FormatStyle::SortJavaStaticImportOptions &Value) { 577 IO.enumCase(Value, "Before", FormatStyle::SJSIO_Before); 578 IO.enumCase(Value, "After", FormatStyle::SJSIO_After); 579 } 580 }; 581 582 template <> struct ScalarEnumerationTraits<FormatStyle::SpacesInAnglesStyle> { 583 static void enumeration(IO &IO, FormatStyle::SpacesInAnglesStyle &Value) { 584 IO.enumCase(Value, "Never", FormatStyle::SIAS_Never); 585 IO.enumCase(Value, "Always", FormatStyle::SIAS_Always); 586 IO.enumCase(Value, "Leave", FormatStyle::SIAS_Leave); 587 588 // For backward compatibility. 589 IO.enumCase(Value, "false", FormatStyle::SIAS_Never); 590 IO.enumCase(Value, "true", FormatStyle::SIAS_Always); 591 } 592 }; 593 594 template <> struct MappingTraits<FormatStyle> { 595 static void mapping(IO &IO, FormatStyle &Style) { 596 // When reading, read the language first, we need it for getPredefinedStyle. 597 IO.mapOptional("Language", Style.Language); 598 599 if (IO.outputting()) { 600 StringRef Styles[] = {"LLVM", "Google", "Chromium", "Mozilla", 601 "WebKit", "GNU", "Microsoft"}; 602 for (StringRef StyleName : Styles) { 603 FormatStyle PredefinedStyle; 604 if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) && 605 Style == PredefinedStyle) { 606 IO.mapOptional("# BasedOnStyle", StyleName); 607 break; 608 } 609 } 610 } else { 611 StringRef BasedOnStyle; 612 IO.mapOptional("BasedOnStyle", BasedOnStyle); 613 if (!BasedOnStyle.empty()) { 614 FormatStyle::LanguageKind OldLanguage = Style.Language; 615 FormatStyle::LanguageKind Language = 616 ((FormatStyle *)IO.getContext())->Language; 617 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) { 618 IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle)); 619 return; 620 } 621 Style.Language = OldLanguage; 622 } 623 } 624 625 // For backward compatibility. 626 if (!IO.outputting()) { 627 IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines); 628 IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment); 629 IO.mapOptional("IndentFunctionDeclarationAfterType", 630 Style.IndentWrappedFunctionNames); 631 IO.mapOptional("IndentRequires", Style.IndentRequiresClause); 632 IO.mapOptional("PointerBindsToType", Style.PointerAlignment); 633 IO.mapOptional("SpaceAfterControlStatementKeyword", 634 Style.SpaceBeforeParens); 635 } 636 637 IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); 638 IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket); 639 IO.mapOptional("AlignArrayOfStructures", Style.AlignArrayOfStructures); 640 IO.mapOptional("AlignConsecutiveAssignments", 641 Style.AlignConsecutiveAssignments); 642 IO.mapOptional("AlignConsecutiveBitFields", 643 Style.AlignConsecutiveBitFields); 644 IO.mapOptional("AlignConsecutiveDeclarations", 645 Style.AlignConsecutiveDeclarations); 646 IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros); 647 IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines); 648 IO.mapOptional("AlignOperands", Style.AlignOperands); 649 IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); 650 IO.mapOptional("AllowAllArgumentsOnNextLine", 651 Style.AllowAllArgumentsOnNextLine); 652 IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine", 653 Style.AllowAllParametersOfDeclarationOnNextLine); 654 IO.mapOptional("AllowShortEnumsOnASingleLine", 655 Style.AllowShortEnumsOnASingleLine); 656 IO.mapOptional("AllowShortBlocksOnASingleLine", 657 Style.AllowShortBlocksOnASingleLine); 658 IO.mapOptional("AllowShortCaseLabelsOnASingleLine", 659 Style.AllowShortCaseLabelsOnASingleLine); 660 IO.mapOptional("AllowShortFunctionsOnASingleLine", 661 Style.AllowShortFunctionsOnASingleLine); 662 IO.mapOptional("AllowShortLambdasOnASingleLine", 663 Style.AllowShortLambdasOnASingleLine); 664 IO.mapOptional("AllowShortIfStatementsOnASingleLine", 665 Style.AllowShortIfStatementsOnASingleLine); 666 IO.mapOptional("AllowShortLoopsOnASingleLine", 667 Style.AllowShortLoopsOnASingleLine); 668 IO.mapOptional("AlwaysBreakAfterDefinitionReturnType", 669 Style.AlwaysBreakAfterDefinitionReturnType); 670 IO.mapOptional("AlwaysBreakAfterReturnType", 671 Style.AlwaysBreakAfterReturnType); 672 673 // If AlwaysBreakAfterDefinitionReturnType was specified but 674 // AlwaysBreakAfterReturnType was not, initialize the latter from the 675 // former for backwards compatibility. 676 if (Style.AlwaysBreakAfterDefinitionReturnType != FormatStyle::DRTBS_None && 677 Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_None) { 678 if (Style.AlwaysBreakAfterDefinitionReturnType == 679 FormatStyle::DRTBS_All) { 680 Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions; 681 } else if (Style.AlwaysBreakAfterDefinitionReturnType == 682 FormatStyle::DRTBS_TopLevel) { 683 Style.AlwaysBreakAfterReturnType = 684 FormatStyle::RTBS_TopLevelDefinitions; 685 } 686 } 687 688 IO.mapOptional("AlwaysBreakBeforeMultilineStrings", 689 Style.AlwaysBreakBeforeMultilineStrings); 690 IO.mapOptional("AlwaysBreakTemplateDeclarations", 691 Style.AlwaysBreakTemplateDeclarations); 692 IO.mapOptional("AttributeMacros", Style.AttributeMacros); 693 IO.mapOptional("BinPackArguments", Style.BinPackArguments); 694 IO.mapOptional("BinPackParameters", Style.BinPackParameters); 695 IO.mapOptional("BraceWrapping", Style.BraceWrapping); 696 IO.mapOptional("BreakBeforeBinaryOperators", 697 Style.BreakBeforeBinaryOperators); 698 IO.mapOptional("BreakBeforeConceptDeclarations", 699 Style.BreakBeforeConceptDeclarations); 700 IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); 701 702 bool BreakBeforeInheritanceComma = false; 703 IO.mapOptional("BreakBeforeInheritanceComma", BreakBeforeInheritanceComma); 704 IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList); 705 // If BreakBeforeInheritanceComma was specified but 706 // BreakInheritance was not, initialize the latter from the 707 // former for backwards compatibility. 708 if (BreakBeforeInheritanceComma && 709 Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon) { 710 Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma; 711 } 712 713 IO.mapOptional("BreakBeforeTernaryOperators", 714 Style.BreakBeforeTernaryOperators); 715 716 bool BreakConstructorInitializersBeforeComma = false; 717 IO.mapOptional("BreakConstructorInitializersBeforeComma", 718 BreakConstructorInitializersBeforeComma); 719 IO.mapOptional("BreakConstructorInitializers", 720 Style.BreakConstructorInitializers); 721 // If BreakConstructorInitializersBeforeComma was specified but 722 // BreakConstructorInitializers was not, initialize the latter from the 723 // former for backwards compatibility. 724 if (BreakConstructorInitializersBeforeComma && 725 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon) { 726 Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 727 } 728 729 IO.mapOptional("BreakAfterJavaFieldAnnotations", 730 Style.BreakAfterJavaFieldAnnotations); 731 IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals); 732 IO.mapOptional("ColumnLimit", Style.ColumnLimit); 733 IO.mapOptional("CommentPragmas", Style.CommentPragmas); 734 IO.mapOptional("QualifierAlignment", Style.QualifierAlignment); 735 736 // Default Order for Left/Right based Qualifier alignment. 737 if (Style.QualifierAlignment == FormatStyle::QAS_Right) 738 Style.QualifierOrder = {"type", "const", "volatile"}; 739 else if (Style.QualifierAlignment == FormatStyle::QAS_Left) 740 Style.QualifierOrder = {"const", "volatile", "type"}; 741 else if (Style.QualifierAlignment == FormatStyle::QAS_Custom) 742 IO.mapOptional("QualifierOrder", Style.QualifierOrder); 743 744 IO.mapOptional("CompactNamespaces", Style.CompactNamespaces); 745 IO.mapOptional("ConstructorInitializerIndentWidth", 746 Style.ConstructorInitializerIndentWidth); 747 IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth); 748 IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle); 749 IO.mapOptional("DeriveLineEnding", Style.DeriveLineEnding); 750 IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment); 751 IO.mapOptional("DisableFormat", Style.DisableFormat); 752 IO.mapOptional("EmptyLineAfterAccessModifier", 753 Style.EmptyLineAfterAccessModifier); 754 IO.mapOptional("EmptyLineBeforeAccessModifier", 755 Style.EmptyLineBeforeAccessModifier); 756 IO.mapOptional("ExperimentalAutoDetectBinPacking", 757 Style.ExperimentalAutoDetectBinPacking); 758 759 IO.mapOptional("PackConstructorInitializers", 760 Style.PackConstructorInitializers); 761 // For backward compatibility: 762 // The default value of ConstructorInitializerAllOnOneLineOrOnePerLine was 763 // false unless BasedOnStyle was Google or Chromium whereas that of 764 // AllowAllConstructorInitializersOnNextLine was always true, so the 765 // equivalent default value of PackConstructorInitializers is PCIS_NextLine 766 // for Google/Chromium or PCIS_BinPack otherwise. If the deprecated options 767 // had a non-default value while PackConstructorInitializers has a default 768 // value, set the latter to an equivalent non-default value if needed. 769 StringRef BasedOn; 770 IO.mapOptional("BasedOnStyle", BasedOn); 771 const bool IsGoogleOrChromium = BasedOn.equals_insensitive("google") || 772 BasedOn.equals_insensitive("chromium"); 773 bool OnCurrentLine = IsGoogleOrChromium; 774 bool OnNextLine = true; 775 IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine", 776 OnCurrentLine); 777 IO.mapOptional("AllowAllConstructorInitializersOnNextLine", OnNextLine); 778 if (!IsGoogleOrChromium) { 779 if (Style.PackConstructorInitializers == FormatStyle::PCIS_BinPack && 780 OnCurrentLine) { 781 Style.PackConstructorInitializers = OnNextLine 782 ? FormatStyle::PCIS_NextLine 783 : FormatStyle::PCIS_CurrentLine; 784 } 785 } else if (Style.PackConstructorInitializers == 786 FormatStyle::PCIS_NextLine) { 787 if (!OnCurrentLine) 788 Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack; 789 else if (!OnNextLine) 790 Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine; 791 } 792 793 IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments); 794 IO.mapOptional("ForEachMacros", Style.ForEachMacros); 795 IO.mapOptional("IfMacros", Style.IfMacros); 796 797 IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks); 798 IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories); 799 IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex); 800 IO.mapOptional("IncludeIsMainSourceRegex", 801 Style.IncludeStyle.IncludeIsMainSourceRegex); 802 IO.mapOptional("IndentAccessModifiers", Style.IndentAccessModifiers); 803 IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels); 804 IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks); 805 IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels); 806 IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives); 807 IO.mapOptional("IndentExternBlock", Style.IndentExternBlock); 808 IO.mapOptional("IndentRequiresClause", Style.IndentRequiresClause); 809 IO.mapOptional("IndentWidth", Style.IndentWidth); 810 IO.mapOptional("IndentWrappedFunctionNames", 811 Style.IndentWrappedFunctionNames); 812 IO.mapOptional("InsertBraces", Style.InsertBraces); 813 IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas); 814 IO.mapOptional("JavaImportGroups", Style.JavaImportGroups); 815 IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes); 816 IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports); 817 IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks", 818 Style.KeepEmptyLinesAtTheStartOfBlocks); 819 IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation); 820 IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin); 821 IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd); 822 IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); 823 IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); 824 IO.mapOptional("NamespaceMacros", Style.NamespaceMacros); 825 IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList); 826 IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth); 827 IO.mapOptional("ObjCBreakBeforeNestedBlockParam", 828 Style.ObjCBreakBeforeNestedBlockParam); 829 IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); 830 IO.mapOptional("ObjCSpaceBeforeProtocolList", 831 Style.ObjCSpaceBeforeProtocolList); 832 IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment); 833 IO.mapOptional("PenaltyBreakBeforeFirstCallParameter", 834 Style.PenaltyBreakBeforeFirstCallParameter); 835 IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment); 836 IO.mapOptional("PenaltyBreakFirstLessLess", 837 Style.PenaltyBreakFirstLessLess); 838 IO.mapOptional("PenaltyBreakOpenParenthesis", 839 Style.PenaltyBreakOpenParenthesis); 840 IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString); 841 IO.mapOptional("PenaltyBreakTemplateDeclaration", 842 Style.PenaltyBreakTemplateDeclaration); 843 IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter); 844 IO.mapOptional("PenaltyReturnTypeOnItsOwnLine", 845 Style.PenaltyReturnTypeOnItsOwnLine); 846 IO.mapOptional("PenaltyIndentedWhitespace", 847 Style.PenaltyIndentedWhitespace); 848 IO.mapOptional("PointerAlignment", Style.PointerAlignment); 849 IO.mapOptional("PPIndentWidth", Style.PPIndentWidth); 850 IO.mapOptional("RawStringFormats", Style.RawStringFormats); 851 IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment); 852 IO.mapOptional("ReflowComments", Style.ReflowComments); 853 IO.mapOptional("RemoveBracesLLVM", Style.RemoveBracesLLVM); 854 IO.mapOptional("RequiresClausePosition", Style.RequiresClausePosition); 855 IO.mapOptional("SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks); 856 IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines); 857 IO.mapOptional("SortIncludes", Style.SortIncludes); 858 IO.mapOptional("SortJavaStaticImport", Style.SortJavaStaticImport); 859 IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations); 860 IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast); 861 IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot); 862 IO.mapOptional("SpaceAfterTemplateKeyword", 863 Style.SpaceAfterTemplateKeyword); 864 IO.mapOptional("SpaceBeforeAssignmentOperators", 865 Style.SpaceBeforeAssignmentOperators); 866 IO.mapOptional("SpaceBeforeCaseColon", Style.SpaceBeforeCaseColon); 867 IO.mapOptional("SpaceBeforeCpp11BracedList", 868 Style.SpaceBeforeCpp11BracedList); 869 IO.mapOptional("SpaceBeforeCtorInitializerColon", 870 Style.SpaceBeforeCtorInitializerColon); 871 IO.mapOptional("SpaceBeforeInheritanceColon", 872 Style.SpaceBeforeInheritanceColon); 873 IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens); 874 IO.mapOptional("SpaceBeforeParensOptions", Style.SpaceBeforeParensOptions); 875 IO.mapOptional("SpaceAroundPointerQualifiers", 876 Style.SpaceAroundPointerQualifiers); 877 IO.mapOptional("SpaceBeforeRangeBasedForLoopColon", 878 Style.SpaceBeforeRangeBasedForLoopColon); 879 IO.mapOptional("SpaceInEmptyBlock", Style.SpaceInEmptyBlock); 880 IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses); 881 IO.mapOptional("SpacesBeforeTrailingComments", 882 Style.SpacesBeforeTrailingComments); 883 IO.mapOptional("SpacesInAngles", Style.SpacesInAngles); 884 IO.mapOptional("SpacesInConditionalStatement", 885 Style.SpacesInConditionalStatement); 886 IO.mapOptional("SpacesInContainerLiterals", 887 Style.SpacesInContainerLiterals); 888 IO.mapOptional("SpacesInCStyleCastParentheses", 889 Style.SpacesInCStyleCastParentheses); 890 IO.mapOptional("SpacesInLineCommentPrefix", 891 Style.SpacesInLineCommentPrefix); 892 IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses); 893 IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets); 894 IO.mapOptional("SpaceBeforeSquareBrackets", 895 Style.SpaceBeforeSquareBrackets); 896 IO.mapOptional("BitFieldColonSpacing", Style.BitFieldColonSpacing); 897 IO.mapOptional("Standard", Style.Standard); 898 IO.mapOptional("StatementAttributeLikeMacros", 899 Style.StatementAttributeLikeMacros); 900 IO.mapOptional("StatementMacros", Style.StatementMacros); 901 IO.mapOptional("TabWidth", Style.TabWidth); 902 IO.mapOptional("TypenameMacros", Style.TypenameMacros); 903 IO.mapOptional("UseCRLF", Style.UseCRLF); 904 IO.mapOptional("UseTab", Style.UseTab); 905 IO.mapOptional("WhitespaceSensitiveMacros", 906 Style.WhitespaceSensitiveMacros); 907 } 908 }; 909 910 template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> { 911 static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) { 912 IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel); 913 IO.mapOptional("AfterClass", Wrapping.AfterClass); 914 IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement); 915 IO.mapOptional("AfterEnum", Wrapping.AfterEnum); 916 IO.mapOptional("AfterFunction", Wrapping.AfterFunction); 917 IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace); 918 IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration); 919 IO.mapOptional("AfterStruct", Wrapping.AfterStruct); 920 IO.mapOptional("AfterUnion", Wrapping.AfterUnion); 921 IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock); 922 IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch); 923 IO.mapOptional("BeforeElse", Wrapping.BeforeElse); 924 IO.mapOptional("BeforeLambdaBody", Wrapping.BeforeLambdaBody); 925 IO.mapOptional("BeforeWhile", Wrapping.BeforeWhile); 926 IO.mapOptional("IndentBraces", Wrapping.IndentBraces); 927 IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction); 928 IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord); 929 IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace); 930 } 931 }; 932 933 template <> struct MappingTraits<FormatStyle::SpaceBeforeParensCustom> { 934 static void mapping(IO &IO, FormatStyle::SpaceBeforeParensCustom &Spacing) { 935 IO.mapOptional("AfterControlStatements", Spacing.AfterControlStatements); 936 IO.mapOptional("AfterForeachMacros", Spacing.AfterForeachMacros); 937 IO.mapOptional("AfterFunctionDefinitionName", 938 Spacing.AfterFunctionDefinitionName); 939 IO.mapOptional("AfterFunctionDeclarationName", 940 Spacing.AfterFunctionDeclarationName); 941 IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros); 942 IO.mapOptional("AfterOverloadedOperator", Spacing.AfterOverloadedOperator); 943 IO.mapOptional("AfterRequiresInClause", Spacing.AfterRequiresInClause); 944 IO.mapOptional("AfterRequiresInExpression", 945 Spacing.AfterRequiresInExpression); 946 IO.mapOptional("BeforeNonEmptyParentheses", 947 Spacing.BeforeNonEmptyParentheses); 948 } 949 }; 950 951 template <> struct MappingTraits<FormatStyle::RawStringFormat> { 952 static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) { 953 IO.mapOptional("Language", Format.Language); 954 IO.mapOptional("Delimiters", Format.Delimiters); 955 IO.mapOptional("EnclosingFunctions", Format.EnclosingFunctions); 956 IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter); 957 IO.mapOptional("BasedOnStyle", Format.BasedOnStyle); 958 } 959 }; 960 961 template <> struct MappingTraits<FormatStyle::SpacesInLineComment> { 962 static void mapping(IO &IO, FormatStyle::SpacesInLineComment &Space) { 963 // Transform the maximum to signed, to parse "-1" correctly 964 int signedMaximum = static_cast<int>(Space.Maximum); 965 IO.mapOptional("Minimum", Space.Minimum); 966 IO.mapOptional("Maximum", signedMaximum); 967 Space.Maximum = static_cast<unsigned>(signedMaximum); 968 969 if (Space.Maximum != -1u) 970 Space.Minimum = std::min(Space.Minimum, Space.Maximum); 971 } 972 }; 973 974 // Allows to read vector<FormatStyle> while keeping default values. 975 // IO.getContext() should contain a pointer to the FormatStyle structure, that 976 // will be used to get default values for missing keys. 977 // If the first element has no Language specified, it will be treated as the 978 // default one for the following elements. 979 template <> struct DocumentListTraits<std::vector<FormatStyle>> { 980 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) { 981 return Seq.size(); 982 } 983 static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq, 984 size_t Index) { 985 if (Index >= Seq.size()) { 986 assert(Index == Seq.size()); 987 FormatStyle Template; 988 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) { 989 Template = Seq[0]; 990 } else { 991 Template = *((const FormatStyle *)IO.getContext()); 992 Template.Language = FormatStyle::LK_None; 993 } 994 Seq.resize(Index + 1, Template); 995 } 996 return Seq[Index]; 997 } 998 }; 999 } // namespace yaml 1000 } // namespace llvm 1001 1002 namespace clang { 1003 namespace format { 1004 1005 const std::error_category &getParseCategory() { 1006 static const ParseErrorCategory C{}; 1007 return C; 1008 } 1009 std::error_code make_error_code(ParseError e) { 1010 return std::error_code(static_cast<int>(e), getParseCategory()); 1011 } 1012 1013 inline llvm::Error make_string_error(const llvm::Twine &Message) { 1014 return llvm::make_error<llvm::StringError>(Message, 1015 llvm::inconvertibleErrorCode()); 1016 } 1017 1018 const char *ParseErrorCategory::name() const noexcept { 1019 return "clang-format.parse_error"; 1020 } 1021 1022 std::string ParseErrorCategory::message(int EV) const { 1023 switch (static_cast<ParseError>(EV)) { 1024 case ParseError::Success: 1025 return "Success"; 1026 case ParseError::Error: 1027 return "Invalid argument"; 1028 case ParseError::Unsuitable: 1029 return "Unsuitable"; 1030 case ParseError::BinPackTrailingCommaConflict: 1031 return "trailing comma insertion cannot be used with bin packing"; 1032 case ParseError::InvalidQualifierSpecified: 1033 return "Invalid qualifier specified in QualifierOrder"; 1034 case ParseError::DuplicateQualifierSpecified: 1035 return "Duplicate qualifier specified in QualifierOrder"; 1036 case ParseError::MissingQualifierType: 1037 return "Missing type in QualifierOrder"; 1038 case ParseError::MissingQualifierOrder: 1039 return "Missing QualifierOrder"; 1040 } 1041 llvm_unreachable("unexpected parse error"); 1042 } 1043 1044 static void expandPresetsBraceWrapping(FormatStyle &Expanded) { 1045 if (Expanded.BreakBeforeBraces == FormatStyle::BS_Custom) 1046 return; 1047 Expanded.BraceWrapping = {/*AfterCaseLabel=*/false, 1048 /*AfterClass=*/false, 1049 /*AfterControlStatement=*/FormatStyle::BWACS_Never, 1050 /*AfterEnum=*/false, 1051 /*AfterFunction=*/false, 1052 /*AfterNamespace=*/false, 1053 /*AfterObjCDeclaration=*/false, 1054 /*AfterStruct=*/false, 1055 /*AfterUnion=*/false, 1056 /*AfterExternBlock=*/false, 1057 /*BeforeCatch=*/false, 1058 /*BeforeElse=*/false, 1059 /*BeforeLambdaBody=*/false, 1060 /*BeforeWhile=*/false, 1061 /*IndentBraces=*/false, 1062 /*SplitEmptyFunction=*/true, 1063 /*SplitEmptyRecord=*/true, 1064 /*SplitEmptyNamespace=*/true}; 1065 switch (Expanded.BreakBeforeBraces) { 1066 case FormatStyle::BS_Linux: 1067 Expanded.BraceWrapping.AfterClass = true; 1068 Expanded.BraceWrapping.AfterFunction = true; 1069 Expanded.BraceWrapping.AfterNamespace = true; 1070 break; 1071 case FormatStyle::BS_Mozilla: 1072 Expanded.BraceWrapping.AfterClass = true; 1073 Expanded.BraceWrapping.AfterEnum = true; 1074 Expanded.BraceWrapping.AfterFunction = true; 1075 Expanded.BraceWrapping.AfterStruct = true; 1076 Expanded.BraceWrapping.AfterUnion = true; 1077 Expanded.BraceWrapping.AfterExternBlock = true; 1078 Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; 1079 Expanded.BraceWrapping.SplitEmptyFunction = true; 1080 Expanded.BraceWrapping.SplitEmptyRecord = false; 1081 break; 1082 case FormatStyle::BS_Stroustrup: 1083 Expanded.BraceWrapping.AfterFunction = true; 1084 Expanded.BraceWrapping.BeforeCatch = true; 1085 Expanded.BraceWrapping.BeforeElse = true; 1086 break; 1087 case FormatStyle::BS_Allman: 1088 Expanded.BraceWrapping.AfterCaseLabel = true; 1089 Expanded.BraceWrapping.AfterClass = true; 1090 Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; 1091 Expanded.BraceWrapping.AfterEnum = true; 1092 Expanded.BraceWrapping.AfterFunction = true; 1093 Expanded.BraceWrapping.AfterNamespace = true; 1094 Expanded.BraceWrapping.AfterObjCDeclaration = true; 1095 Expanded.BraceWrapping.AfterStruct = true; 1096 Expanded.BraceWrapping.AfterUnion = true; 1097 Expanded.BraceWrapping.AfterExternBlock = true; 1098 Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; 1099 Expanded.BraceWrapping.BeforeCatch = true; 1100 Expanded.BraceWrapping.BeforeElse = true; 1101 Expanded.BraceWrapping.BeforeLambdaBody = true; 1102 break; 1103 case FormatStyle::BS_Whitesmiths: 1104 Expanded.BraceWrapping.AfterCaseLabel = true; 1105 Expanded.BraceWrapping.AfterClass = true; 1106 Expanded.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; 1107 Expanded.BraceWrapping.AfterEnum = true; 1108 Expanded.BraceWrapping.AfterFunction = true; 1109 Expanded.BraceWrapping.AfterNamespace = true; 1110 Expanded.BraceWrapping.AfterObjCDeclaration = true; 1111 Expanded.BraceWrapping.AfterStruct = true; 1112 Expanded.BraceWrapping.AfterExternBlock = true; 1113 Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; 1114 Expanded.BraceWrapping.BeforeCatch = true; 1115 Expanded.BraceWrapping.BeforeElse = true; 1116 Expanded.BraceWrapping.BeforeLambdaBody = true; 1117 break; 1118 case FormatStyle::BS_GNU: 1119 Expanded.BraceWrapping = { 1120 /*AfterCaseLabel=*/true, 1121 /*AfterClass=*/true, 1122 /*AfterControlStatement=*/FormatStyle::BWACS_Always, 1123 /*AfterEnum=*/true, 1124 /*AfterFunction=*/true, 1125 /*AfterNamespace=*/true, 1126 /*AfterObjCDeclaration=*/true, 1127 /*AfterStruct=*/true, 1128 /*AfterUnion=*/true, 1129 /*AfterExternBlock=*/true, 1130 /*BeforeCatch=*/true, 1131 /*BeforeElse=*/true, 1132 /*BeforeLambdaBody=*/false, 1133 /*BeforeWhile=*/true, 1134 /*IndentBraces=*/true, 1135 /*SplitEmptyFunction=*/true, 1136 /*SplitEmptyRecord=*/true, 1137 /*SplitEmptyNamespace=*/true}; 1138 Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; 1139 break; 1140 case FormatStyle::BS_WebKit: 1141 Expanded.BraceWrapping.AfterFunction = true; 1142 break; 1143 default: 1144 break; 1145 } 1146 } 1147 1148 static void expandPresetsSpaceBeforeParens(FormatStyle &Expanded) { 1149 if (Expanded.SpaceBeforeParens == FormatStyle::SBPO_Custom) 1150 return; 1151 // Reset all flags 1152 Expanded.SpaceBeforeParensOptions = {}; 1153 1154 switch (Expanded.SpaceBeforeParens) { 1155 case FormatStyle::SBPO_Never: 1156 break; 1157 case FormatStyle::SBPO_ControlStatements: 1158 Expanded.SpaceBeforeParensOptions.AfterControlStatements = true; 1159 Expanded.SpaceBeforeParensOptions.AfterForeachMacros = true; 1160 Expanded.SpaceBeforeParensOptions.AfterIfMacros = true; 1161 break; 1162 case FormatStyle::SBPO_ControlStatementsExceptControlMacros: 1163 Expanded.SpaceBeforeParensOptions.AfterControlStatements = true; 1164 break; 1165 case FormatStyle::SBPO_NonEmptyParentheses: 1166 Expanded.SpaceBeforeParensOptions.BeforeNonEmptyParentheses = true; 1167 break; 1168 case FormatStyle::SBPO_Always: 1169 break; 1170 default: 1171 break; 1172 } 1173 } 1174 1175 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { 1176 FormatStyle LLVMStyle; 1177 LLVMStyle.InheritsParentConfig = false; 1178 LLVMStyle.Language = Language; 1179 LLVMStyle.AccessModifierOffset = -2; 1180 LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right; 1181 LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align; 1182 LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None; 1183 LLVMStyle.AlignOperands = FormatStyle::OAS_Align; 1184 LLVMStyle.AlignTrailingComments = true; 1185 LLVMStyle.AlignConsecutiveAssignments = {}; 1186 LLVMStyle.AlignConsecutiveAssignments.Enabled = false; 1187 LLVMStyle.AlignConsecutiveAssignments.AcrossEmptyLines = false; 1188 LLVMStyle.AlignConsecutiveAssignments.AcrossComments = false; 1189 LLVMStyle.AlignConsecutiveAssignments.AlignCompound = false; 1190 LLVMStyle.AlignConsecutiveAssignments.PadOperators = true; 1191 LLVMStyle.AlignConsecutiveBitFields = {}; 1192 LLVMStyle.AlignConsecutiveDeclarations = {}; 1193 LLVMStyle.AlignConsecutiveMacros = {}; 1194 LLVMStyle.AllowAllArgumentsOnNextLine = true; 1195 LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; 1196 LLVMStyle.AllowShortEnumsOnASingleLine = true; 1197 LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; 1198 LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; 1199 LLVMStyle.AllowShortCaseLabelsOnASingleLine = false; 1200 LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 1201 LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All; 1202 LLVMStyle.AllowShortLoopsOnASingleLine = false; 1203 LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None; 1204 LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None; 1205 LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; 1206 LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine; 1207 LLVMStyle.AttributeMacros.push_back("__capability"); 1208 LLVMStyle.BinPackArguments = true; 1209 LLVMStyle.BinPackParameters = true; 1210 LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; 1211 LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always; 1212 LLVMStyle.BreakBeforeTernaryOperators = true; 1213 LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; 1214 LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false, 1215 /*AfterClass=*/false, 1216 /*AfterControlStatement=*/FormatStyle::BWACS_Never, 1217 /*AfterEnum=*/false, 1218 /*AfterFunction=*/false, 1219 /*AfterNamespace=*/false, 1220 /*AfterObjCDeclaration=*/false, 1221 /*AfterStruct=*/false, 1222 /*AfterUnion=*/false, 1223 /*AfterExternBlock=*/false, 1224 /*BeforeCatch=*/false, 1225 /*BeforeElse=*/false, 1226 /*BeforeLambdaBody=*/false, 1227 /*BeforeWhile=*/false, 1228 /*IndentBraces=*/false, 1229 /*SplitEmptyFunction=*/true, 1230 /*SplitEmptyRecord=*/true, 1231 /*SplitEmptyNamespace=*/true}; 1232 LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; 1233 LLVMStyle.BreakAfterJavaFieldAnnotations = false; 1234 LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; 1235 LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; 1236 LLVMStyle.BreakStringLiterals = true; 1237 LLVMStyle.ColumnLimit = 80; 1238 LLVMStyle.CommentPragmas = "^ IWYU pragma:"; 1239 LLVMStyle.CompactNamespaces = false; 1240 LLVMStyle.ConstructorInitializerIndentWidth = 4; 1241 LLVMStyle.ContinuationIndentWidth = 4; 1242 LLVMStyle.Cpp11BracedListStyle = true; 1243 1244 // Off by default Qualifier ordering 1245 LLVMStyle.QualifierAlignment = FormatStyle::QAS_Leave; 1246 1247 LLVMStyle.DeriveLineEnding = true; 1248 LLVMStyle.DerivePointerAlignment = false; 1249 LLVMStyle.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never; 1250 LLVMStyle.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock; 1251 LLVMStyle.ExperimentalAutoDetectBinPacking = false; 1252 LLVMStyle.PackConstructorInitializers = FormatStyle::PCIS_BinPack; 1253 LLVMStyle.FixNamespaceComments = true; 1254 LLVMStyle.ForEachMacros.push_back("foreach"); 1255 LLVMStyle.ForEachMacros.push_back("Q_FOREACH"); 1256 LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH"); 1257 LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE"); 1258 LLVMStyle.IncludeStyle.IncludeCategories = { 1259 {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false}, 1260 {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false}, 1261 {".*", 1, 0, false}}; 1262 LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$"; 1263 LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve; 1264 LLVMStyle.IndentAccessModifiers = false; 1265 LLVMStyle.IndentCaseLabels = false; 1266 LLVMStyle.IndentCaseBlocks = false; 1267 LLVMStyle.IndentGotoLabels = true; 1268 LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None; 1269 LLVMStyle.IndentRequiresClause = true; 1270 LLVMStyle.IndentWrappedFunctionNames = false; 1271 LLVMStyle.IndentWidth = 2; 1272 LLVMStyle.PPIndentWidth = -1; 1273 LLVMStyle.InsertBraces = false; 1274 LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None; 1275 LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave; 1276 LLVMStyle.JavaScriptWrapImports = true; 1277 LLVMStyle.TabWidth = 8; 1278 LLVMStyle.LambdaBodyIndentation = FormatStyle::LBI_Signature; 1279 LLVMStyle.MaxEmptyLinesToKeep = 1; 1280 LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true; 1281 LLVMStyle.NamespaceIndentation = FormatStyle::NI_None; 1282 LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto; 1283 LLVMStyle.ObjCBlockIndentWidth = 2; 1284 LLVMStyle.ObjCBreakBeforeNestedBlockParam = true; 1285 LLVMStyle.ObjCSpaceAfterProperty = false; 1286 LLVMStyle.ObjCSpaceBeforeProtocolList = true; 1287 LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; 1288 LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer; 1289 LLVMStyle.RequiresClausePosition = FormatStyle::RCPS_OwnLine; 1290 LLVMStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Leave; 1291 LLVMStyle.ShortNamespaceLines = 1; 1292 LLVMStyle.SpacesBeforeTrailingComments = 1; 1293 LLVMStyle.Standard = FormatStyle::LS_Latest; 1294 LLVMStyle.UseCRLF = false; 1295 LLVMStyle.UseTab = FormatStyle::UT_Never; 1296 LLVMStyle.ReflowComments = true; 1297 LLVMStyle.RemoveBracesLLVM = false; 1298 LLVMStyle.SpacesInParentheses = false; 1299 LLVMStyle.SpacesInSquareBrackets = false; 1300 LLVMStyle.SpaceInEmptyBlock = false; 1301 LLVMStyle.SpaceInEmptyParentheses = false; 1302 LLVMStyle.SpacesInContainerLiterals = true; 1303 LLVMStyle.SpacesInCStyleCastParentheses = false; 1304 LLVMStyle.SpacesInLineCommentPrefix = {/*Minimum=*/1, /*Maximum=*/-1u}; 1305 LLVMStyle.SpaceAfterCStyleCast = false; 1306 LLVMStyle.SpaceAfterLogicalNot = false; 1307 LLVMStyle.SpaceAfterTemplateKeyword = true; 1308 LLVMStyle.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default; 1309 LLVMStyle.SpaceBeforeCaseColon = false; 1310 LLVMStyle.SpaceBeforeCtorInitializerColon = true; 1311 LLVMStyle.SpaceBeforeInheritanceColon = true; 1312 LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements; 1313 LLVMStyle.SpaceBeforeParensOptions = {}; 1314 LLVMStyle.SpaceBeforeParensOptions.AfterControlStatements = true; 1315 LLVMStyle.SpaceBeforeParensOptions.AfterForeachMacros = true; 1316 LLVMStyle.SpaceBeforeParensOptions.AfterIfMacros = true; 1317 LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true; 1318 LLVMStyle.SpaceBeforeAssignmentOperators = true; 1319 LLVMStyle.SpaceBeforeCpp11BracedList = false; 1320 LLVMStyle.SpaceBeforeSquareBrackets = false; 1321 LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both; 1322 LLVMStyle.SpacesInAngles = FormatStyle::SIAS_Never; 1323 LLVMStyle.SpacesInConditionalStatement = false; 1324 1325 LLVMStyle.PenaltyBreakAssignment = prec::Assignment; 1326 LLVMStyle.PenaltyBreakComment = 300; 1327 LLVMStyle.PenaltyBreakFirstLessLess = 120; 1328 LLVMStyle.PenaltyBreakString = 1000; 1329 LLVMStyle.PenaltyExcessCharacter = 1000000; 1330 LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60; 1331 LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19; 1332 LLVMStyle.PenaltyBreakOpenParenthesis = 0; 1333 LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational; 1334 LLVMStyle.PenaltyIndentedWhitespace = 0; 1335 1336 LLVMStyle.DisableFormat = false; 1337 LLVMStyle.SortIncludes = FormatStyle::SI_CaseSensitive; 1338 LLVMStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before; 1339 LLVMStyle.SortUsingDeclarations = true; 1340 LLVMStyle.StatementAttributeLikeMacros.push_back("Q_EMIT"); 1341 LLVMStyle.StatementMacros.push_back("Q_UNUSED"); 1342 LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION"); 1343 LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE"); 1344 LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE"); 1345 LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE"); 1346 LLVMStyle.WhitespaceSensitiveMacros.push_back("NS_SWIFT_NAME"); 1347 LLVMStyle.WhitespaceSensitiveMacros.push_back("CF_SWIFT_NAME"); 1348 1349 // Defaults that differ when not C++. 1350 if (Language == FormatStyle::LK_TableGen) 1351 LLVMStyle.SpacesInContainerLiterals = false; 1352 if (LLVMStyle.isJson()) 1353 LLVMStyle.ColumnLimit = 0; 1354 1355 return LLVMStyle; 1356 } 1357 1358 FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { 1359 if (Language == FormatStyle::LK_TextProto) { 1360 FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto); 1361 GoogleStyle.Language = FormatStyle::LK_TextProto; 1362 1363 return GoogleStyle; 1364 } 1365 1366 FormatStyle GoogleStyle = getLLVMStyle(Language); 1367 1368 GoogleStyle.AccessModifierOffset = -1; 1369 GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left; 1370 GoogleStyle.AllowShortIfStatementsOnASingleLine = 1371 FormatStyle::SIS_WithoutElse; 1372 GoogleStyle.AllowShortLoopsOnASingleLine = true; 1373 GoogleStyle.AlwaysBreakBeforeMultilineStrings = true; 1374 GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; 1375 GoogleStyle.DerivePointerAlignment = true; 1376 GoogleStyle.IncludeStyle.IncludeCategories = {{"^<ext/.*\\.h>", 2, 0, false}, 1377 {"^<.*\\.h>", 1, 0, false}, 1378 {"^<.*", 2, 0, false}, 1379 {".*", 3, 0, false}}; 1380 GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$"; 1381 GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 1382 GoogleStyle.IndentCaseLabels = true; 1383 GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false; 1384 GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never; 1385 GoogleStyle.ObjCSpaceAfterProperty = false; 1386 GoogleStyle.ObjCSpaceBeforeProtocolList = true; 1387 GoogleStyle.PackConstructorInitializers = FormatStyle::PCIS_NextLine; 1388 GoogleStyle.PointerAlignment = FormatStyle::PAS_Left; 1389 GoogleStyle.RawStringFormats = { 1390 { 1391 FormatStyle::LK_Cpp, 1392 /*Delimiters=*/ 1393 { 1394 "cc", 1395 "CC", 1396 "cpp", 1397 "Cpp", 1398 "CPP", 1399 "c++", 1400 "C++", 1401 }, 1402 /*EnclosingFunctionNames=*/ 1403 {}, 1404 /*CanonicalDelimiter=*/"", 1405 /*BasedOnStyle=*/"google", 1406 }, 1407 { 1408 FormatStyle::LK_TextProto, 1409 /*Delimiters=*/ 1410 { 1411 "pb", 1412 "PB", 1413 "proto", 1414 "PROTO", 1415 }, 1416 /*EnclosingFunctionNames=*/ 1417 { 1418 "EqualsProto", 1419 "EquivToProto", 1420 "PARSE_PARTIAL_TEXT_PROTO", 1421 "PARSE_TEST_PROTO", 1422 "PARSE_TEXT_PROTO", 1423 "ParseTextOrDie", 1424 "ParseTextProtoOrDie", 1425 "ParseTestProto", 1426 "ParsePartialTestProto", 1427 }, 1428 /*CanonicalDelimiter=*/"pb", 1429 /*BasedOnStyle=*/"google", 1430 }, 1431 }; 1432 GoogleStyle.SpacesBeforeTrailingComments = 2; 1433 GoogleStyle.Standard = FormatStyle::LS_Auto; 1434 1435 GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200; 1436 GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1; 1437 1438 if (Language == FormatStyle::LK_Java) { 1439 GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; 1440 GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign; 1441 GoogleStyle.AlignTrailingComments = false; 1442 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 1443 GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 1444 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 1445 GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; 1446 GoogleStyle.ColumnLimit = 100; 1447 GoogleStyle.SpaceAfterCStyleCast = true; 1448 GoogleStyle.SpacesBeforeTrailingComments = 1; 1449 } else if (Language == FormatStyle::LK_JavaScript) { 1450 GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; 1451 GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign; 1452 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 1453 // TODO: still under discussion whether to switch to SLS_All. 1454 GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty; 1455 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 1456 GoogleStyle.BreakBeforeTernaryOperators = false; 1457 // taze:, triple slash directives (`/// <...`), tslint:, and @see, which is 1458 // commonly followed by overlong URLs. 1459 GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|tslint:|@see)"; 1460 // TODO: enable once decided, in particular re disabling bin packing. 1461 // https://google.github.io/styleguide/jsguide.html#features-arrays-trailing-comma 1462 // GoogleStyle.InsertTrailingCommas = FormatStyle::TCS_Wrapped; 1463 GoogleStyle.MaxEmptyLinesToKeep = 3; 1464 GoogleStyle.NamespaceIndentation = FormatStyle::NI_All; 1465 GoogleStyle.SpacesInContainerLiterals = false; 1466 GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single; 1467 GoogleStyle.JavaScriptWrapImports = false; 1468 } else if (Language == FormatStyle::LK_Proto) { 1469 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 1470 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 1471 GoogleStyle.SpacesInContainerLiterals = false; 1472 GoogleStyle.Cpp11BracedListStyle = false; 1473 // This affects protocol buffer options specifications and text protos. 1474 // Text protos are currently mostly formatted inside C++ raw string literals 1475 // and often the current breaking behavior of string literals is not 1476 // beneficial there. Investigate turning this on once proper string reflow 1477 // has been implemented. 1478 GoogleStyle.BreakStringLiterals = false; 1479 } else if (Language == FormatStyle::LK_ObjC) { 1480 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 1481 GoogleStyle.ColumnLimit = 100; 1482 // "Regroup" doesn't work well for ObjC yet (main header heuristic, 1483 // relationship between ObjC standard library headers and other heades, 1484 // #imports, etc.) 1485 GoogleStyle.IncludeStyle.IncludeBlocks = 1486 tooling::IncludeStyle::IBS_Preserve; 1487 } else if (Language == FormatStyle::LK_CSharp) { 1488 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 1489 GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 1490 GoogleStyle.BreakStringLiterals = false; 1491 GoogleStyle.ColumnLimit = 100; 1492 GoogleStyle.NamespaceIndentation = FormatStyle::NI_All; 1493 } 1494 1495 return GoogleStyle; 1496 } 1497 1498 FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) { 1499 FormatStyle ChromiumStyle = getGoogleStyle(Language); 1500 1501 // Disable include reordering across blocks in Chromium code. 1502 // - clang-format tries to detect that foo.h is the "main" header for 1503 // foo.cc and foo_unittest.cc via IncludeIsMainRegex. However, Chromium 1504 // uses many other suffices (_win.cc, _mac.mm, _posix.cc, _browsertest.cc, 1505 // _private.cc, _impl.cc etc) in different permutations 1506 // (_win_browsertest.cc) so disable this until IncludeIsMainRegex has a 1507 // better default for Chromium code. 1508 // - The default for .cc and .mm files is different (r357695) for Google style 1509 // for the same reason. The plan is to unify this again once the main 1510 // header detection works for Google's ObjC code, but this hasn't happened 1511 // yet. Since Chromium has some ObjC code, switching Chromium is blocked 1512 // on that. 1513 // - Finally, "If include reordering is harmful, put things in different 1514 // blocks to prevent it" has been a recommendation for a long time that 1515 // people are used to. We'll need a dev education push to change this to 1516 // "If include reordering is harmful, put things in a different block and 1517 // _prepend that with a comment_ to prevent it" before changing behavior. 1518 ChromiumStyle.IncludeStyle.IncludeBlocks = 1519 tooling::IncludeStyle::IBS_Preserve; 1520 1521 if (Language == FormatStyle::LK_Java) { 1522 ChromiumStyle.AllowShortIfStatementsOnASingleLine = 1523 FormatStyle::SIS_WithoutElse; 1524 ChromiumStyle.BreakAfterJavaFieldAnnotations = true; 1525 ChromiumStyle.ContinuationIndentWidth = 8; 1526 ChromiumStyle.IndentWidth = 4; 1527 // See styleguide for import groups: 1528 // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/styleguide/java/java.md#Import-Order 1529 ChromiumStyle.JavaImportGroups = { 1530 "android", 1531 "androidx", 1532 "com", 1533 "dalvik", 1534 "junit", 1535 "org", 1536 "com.google.android.apps.chrome", 1537 "org.chromium", 1538 "java", 1539 "javax", 1540 }; 1541 ChromiumStyle.SortIncludes = FormatStyle::SI_CaseSensitive; 1542 } else if (Language == FormatStyle::LK_JavaScript) { 1543 ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 1544 ChromiumStyle.AllowShortLoopsOnASingleLine = false; 1545 } else { 1546 ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false; 1547 ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 1548 ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 1549 ChromiumStyle.AllowShortLoopsOnASingleLine = false; 1550 ChromiumStyle.BinPackParameters = false; 1551 ChromiumStyle.DerivePointerAlignment = false; 1552 if (Language == FormatStyle::LK_ObjC) 1553 ChromiumStyle.ColumnLimit = 80; 1554 } 1555 return ChromiumStyle; 1556 } 1557 1558 FormatStyle getMozillaStyle() { 1559 FormatStyle MozillaStyle = getLLVMStyle(); 1560 MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false; 1561 MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 1562 MozillaStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel; 1563 MozillaStyle.AlwaysBreakAfterDefinitionReturnType = 1564 FormatStyle::DRTBS_TopLevel; 1565 MozillaStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; 1566 MozillaStyle.BinPackParameters = false; 1567 MozillaStyle.BinPackArguments = false; 1568 MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla; 1569 MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 1570 MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma; 1571 MozillaStyle.ConstructorInitializerIndentWidth = 2; 1572 MozillaStyle.ContinuationIndentWidth = 2; 1573 MozillaStyle.Cpp11BracedListStyle = false; 1574 MozillaStyle.FixNamespaceComments = false; 1575 MozillaStyle.IndentCaseLabels = true; 1576 MozillaStyle.ObjCSpaceAfterProperty = true; 1577 MozillaStyle.ObjCSpaceBeforeProtocolList = false; 1578 MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200; 1579 MozillaStyle.PointerAlignment = FormatStyle::PAS_Left; 1580 MozillaStyle.SpaceAfterTemplateKeyword = false; 1581 return MozillaStyle; 1582 } 1583 1584 FormatStyle getWebKitStyle() { 1585 FormatStyle Style = getLLVMStyle(); 1586 Style.AccessModifierOffset = -4; 1587 Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; 1588 Style.AlignOperands = FormatStyle::OAS_DontAlign; 1589 Style.AlignTrailingComments = false; 1590 Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; 1591 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; 1592 Style.BreakBeforeBraces = FormatStyle::BS_WebKit; 1593 Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 1594 Style.Cpp11BracedListStyle = false; 1595 Style.ColumnLimit = 0; 1596 Style.FixNamespaceComments = false; 1597 Style.IndentWidth = 4; 1598 Style.NamespaceIndentation = FormatStyle::NI_Inner; 1599 Style.ObjCBlockIndentWidth = 4; 1600 Style.ObjCSpaceAfterProperty = true; 1601 Style.PointerAlignment = FormatStyle::PAS_Left; 1602 Style.SpaceBeforeCpp11BracedList = true; 1603 Style.SpaceInEmptyBlock = true; 1604 return Style; 1605 } 1606 1607 FormatStyle getGNUStyle() { 1608 FormatStyle Style = getLLVMStyle(); 1609 Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; 1610 Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions; 1611 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; 1612 Style.BreakBeforeBraces = FormatStyle::BS_GNU; 1613 Style.BreakBeforeTernaryOperators = true; 1614 Style.Cpp11BracedListStyle = false; 1615 Style.ColumnLimit = 79; 1616 Style.FixNamespaceComments = false; 1617 Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 1618 Style.Standard = FormatStyle::LS_Cpp03; 1619 return Style; 1620 } 1621 1622 FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) { 1623 FormatStyle Style = getLLVMStyle(Language); 1624 Style.ColumnLimit = 120; 1625 Style.TabWidth = 4; 1626 Style.IndentWidth = 4; 1627 Style.UseTab = FormatStyle::UT_Never; 1628 Style.BreakBeforeBraces = FormatStyle::BS_Custom; 1629 Style.BraceWrapping.AfterClass = true; 1630 Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; 1631 Style.BraceWrapping.AfterEnum = true; 1632 Style.BraceWrapping.AfterFunction = true; 1633 Style.BraceWrapping.AfterNamespace = true; 1634 Style.BraceWrapping.AfterObjCDeclaration = true; 1635 Style.BraceWrapping.AfterStruct = true; 1636 Style.BraceWrapping.AfterExternBlock = true; 1637 Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; 1638 Style.BraceWrapping.BeforeCatch = true; 1639 Style.BraceWrapping.BeforeElse = true; 1640 Style.BraceWrapping.BeforeWhile = false; 1641 Style.PenaltyReturnTypeOnItsOwnLine = 1000; 1642 Style.AllowShortEnumsOnASingleLine = false; 1643 Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; 1644 Style.AllowShortCaseLabelsOnASingleLine = false; 1645 Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 1646 Style.AllowShortLoopsOnASingleLine = false; 1647 Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None; 1648 Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None; 1649 return Style; 1650 } 1651 1652 FormatStyle getNoStyle() { 1653 FormatStyle NoStyle = getLLVMStyle(); 1654 NoStyle.DisableFormat = true; 1655 NoStyle.SortIncludes = FormatStyle::SI_Never; 1656 NoStyle.SortUsingDeclarations = false; 1657 return NoStyle; 1658 } 1659 1660 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, 1661 FormatStyle *Style) { 1662 if (Name.equals_insensitive("llvm")) 1663 *Style = getLLVMStyle(Language); 1664 else if (Name.equals_insensitive("chromium")) 1665 *Style = getChromiumStyle(Language); 1666 else if (Name.equals_insensitive("mozilla")) 1667 *Style = getMozillaStyle(); 1668 else if (Name.equals_insensitive("google")) 1669 *Style = getGoogleStyle(Language); 1670 else if (Name.equals_insensitive("webkit")) 1671 *Style = getWebKitStyle(); 1672 else if (Name.equals_insensitive("gnu")) 1673 *Style = getGNUStyle(); 1674 else if (Name.equals_insensitive("microsoft")) 1675 *Style = getMicrosoftStyle(Language); 1676 else if (Name.equals_insensitive("none")) 1677 *Style = getNoStyle(); 1678 else if (Name.equals_insensitive("inheritparentconfig")) 1679 Style->InheritsParentConfig = true; 1680 else 1681 return false; 1682 1683 Style->Language = Language; 1684 return true; 1685 } 1686 1687 ParseError validateQualifierOrder(FormatStyle *Style) { 1688 // If its empty then it means don't do anything. 1689 if (Style->QualifierOrder.empty()) 1690 return ParseError::MissingQualifierOrder; 1691 1692 // Ensure the list contains only currently valid qualifiers. 1693 for (const auto &Qualifier : Style->QualifierOrder) { 1694 if (Qualifier == "type") 1695 continue; 1696 auto token = 1697 LeftRightQualifierAlignmentFixer::getTokenFromQualifier(Qualifier); 1698 if (token == tok::identifier) 1699 return ParseError::InvalidQualifierSpecified; 1700 } 1701 1702 // Ensure the list is unique (no duplicates). 1703 std::set<std::string> UniqueQualifiers(Style->QualifierOrder.begin(), 1704 Style->QualifierOrder.end()); 1705 if (Style->QualifierOrder.size() != UniqueQualifiers.size()) { 1706 LLVM_DEBUG(llvm::dbgs() 1707 << "Duplicate Qualifiers " << Style->QualifierOrder.size() 1708 << " vs " << UniqueQualifiers.size() << "\n"); 1709 return ParseError::DuplicateQualifierSpecified; 1710 } 1711 1712 // Ensure the list has 'type' in it. 1713 auto type = std::find(Style->QualifierOrder.begin(), 1714 Style->QualifierOrder.end(), "type"); 1715 if (type == Style->QualifierOrder.end()) 1716 return ParseError::MissingQualifierType; 1717 1718 return ParseError::Success; 1719 } 1720 1721 std::error_code parseConfiguration(llvm::MemoryBufferRef Config, 1722 FormatStyle *Style, bool AllowUnknownOptions, 1723 llvm::SourceMgr::DiagHandlerTy DiagHandler, 1724 void *DiagHandlerCtxt) { 1725 assert(Style); 1726 FormatStyle::LanguageKind Language = Style->Language; 1727 assert(Language != FormatStyle::LK_None); 1728 if (Config.getBuffer().trim().empty()) 1729 return make_error_code(ParseError::Success); 1730 Style->StyleSet.Clear(); 1731 std::vector<FormatStyle> Styles; 1732 llvm::yaml::Input Input(Config, /*Ctxt=*/nullptr, DiagHandler, 1733 DiagHandlerCtxt); 1734 // DocumentListTraits<vector<FormatStyle>> uses the context to get default 1735 // values for the fields, keys for which are missing from the configuration. 1736 // Mapping also uses the context to get the language to find the correct 1737 // base style. 1738 Input.setContext(Style); 1739 Input.setAllowUnknownKeys(AllowUnknownOptions); 1740 Input >> Styles; 1741 if (Input.error()) 1742 return Input.error(); 1743 1744 for (unsigned i = 0; i < Styles.size(); ++i) { 1745 // Ensures that only the first configuration can skip the Language option. 1746 if (Styles[i].Language == FormatStyle::LK_None && i != 0) 1747 return make_error_code(ParseError::Error); 1748 // Ensure that each language is configured at most once. 1749 for (unsigned j = 0; j < i; ++j) { 1750 if (Styles[i].Language == Styles[j].Language) { 1751 LLVM_DEBUG(llvm::dbgs() 1752 << "Duplicate languages in the config file on positions " 1753 << j << " and " << i << "\n"); 1754 return make_error_code(ParseError::Error); 1755 } 1756 } 1757 } 1758 // Look for a suitable configuration starting from the end, so we can 1759 // find the configuration for the specific language first, and the default 1760 // configuration (which can only be at slot 0) after it. 1761 FormatStyle::FormatStyleSet StyleSet; 1762 bool LanguageFound = false; 1763 for (const FormatStyle &Style : llvm::reverse(Styles)) { 1764 if (Style.Language != FormatStyle::LK_None) 1765 StyleSet.Add(Style); 1766 if (Style.Language == Language) 1767 LanguageFound = true; 1768 } 1769 if (!LanguageFound) { 1770 if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None) 1771 return make_error_code(ParseError::Unsuitable); 1772 FormatStyle DefaultStyle = Styles[0]; 1773 DefaultStyle.Language = Language; 1774 StyleSet.Add(std::move(DefaultStyle)); 1775 } 1776 *Style = *StyleSet.Get(Language); 1777 if (Style->InsertTrailingCommas != FormatStyle::TCS_None && 1778 Style->BinPackArguments) { 1779 // See comment on FormatStyle::TSC_Wrapped. 1780 return make_error_code(ParseError::BinPackTrailingCommaConflict); 1781 } 1782 if (Style->QualifierAlignment != FormatStyle::QAS_Leave) 1783 return make_error_code(validateQualifierOrder(Style)); 1784 return make_error_code(ParseError::Success); 1785 } 1786 1787 std::string configurationAsText(const FormatStyle &Style) { 1788 std::string Text; 1789 llvm::raw_string_ostream Stream(Text); 1790 llvm::yaml::Output Output(Stream); 1791 // We use the same mapping method for input and output, so we need a non-const 1792 // reference here. 1793 FormatStyle NonConstStyle = Style; 1794 expandPresetsBraceWrapping(NonConstStyle); 1795 expandPresetsSpaceBeforeParens(NonConstStyle); 1796 Output << NonConstStyle; 1797 1798 return Stream.str(); 1799 } 1800 1801 llvm::Optional<FormatStyle> 1802 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const { 1803 if (!Styles) 1804 return None; 1805 auto It = Styles->find(Language); 1806 if (It == Styles->end()) 1807 return None; 1808 FormatStyle Style = It->second; 1809 Style.StyleSet = *this; 1810 return Style; 1811 } 1812 1813 void FormatStyle::FormatStyleSet::Add(FormatStyle Style) { 1814 assert(Style.Language != LK_None && 1815 "Cannot add a style for LK_None to a StyleSet"); 1816 assert( 1817 !Style.StyleSet.Styles && 1818 "Cannot add a style associated with an existing StyleSet to a StyleSet"); 1819 if (!Styles) 1820 Styles = std::make_shared<MapType>(); 1821 (*Styles)[Style.Language] = std::move(Style); 1822 } 1823 1824 void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); } 1825 1826 llvm::Optional<FormatStyle> 1827 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const { 1828 return StyleSet.Get(Language); 1829 } 1830 1831 namespace { 1832 1833 class BracesInserter : public TokenAnalyzer { 1834 public: 1835 BracesInserter(const Environment &Env, const FormatStyle &Style) 1836 : TokenAnalyzer(Env, Style) {} 1837 1838 std::pair<tooling::Replacements, unsigned> 1839 analyze(TokenAnnotator &Annotator, 1840 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1841 FormatTokenLexer &Tokens) override { 1842 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 1843 tooling::Replacements Result; 1844 insertBraces(AnnotatedLines, Result); 1845 return {Result, 0}; 1846 } 1847 1848 private: 1849 void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines, 1850 tooling::Replacements &Result) { 1851 const auto &SourceMgr = Env.getSourceManager(); 1852 for (AnnotatedLine *Line : Lines) { 1853 insertBraces(Line->Children, Result); 1854 if (!Line->Affected) 1855 continue; 1856 for (FormatToken *Token = Line->First; Token && !Token->Finalized; 1857 Token = Token->Next) { 1858 if (Token->BraceCount == 0) 1859 continue; 1860 std::string Brace; 1861 if (Token->BraceCount < 0) { 1862 assert(Token->BraceCount == -1); 1863 Brace = '{'; 1864 } else { 1865 Brace = '\n' + std::string(Token->BraceCount, '}'); 1866 } 1867 Token->BraceCount = 0; 1868 const auto Start = Token->Tok.getEndLoc(); 1869 cantFail(Result.add(tooling::Replacement(SourceMgr, Start, 0, Brace))); 1870 } 1871 } 1872 } 1873 }; 1874 1875 class BracesRemover : public TokenAnalyzer { 1876 public: 1877 BracesRemover(const Environment &Env, const FormatStyle &Style) 1878 : TokenAnalyzer(Env, Style) {} 1879 1880 std::pair<tooling::Replacements, unsigned> 1881 analyze(TokenAnnotator &Annotator, 1882 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1883 FormatTokenLexer &Tokens) override { 1884 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 1885 tooling::Replacements Result; 1886 removeBraces(AnnotatedLines, Result); 1887 return {Result, 0}; 1888 } 1889 1890 private: 1891 void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines, 1892 tooling::Replacements &Result) { 1893 const auto &SourceMgr = Env.getSourceManager(); 1894 for (AnnotatedLine *Line : Lines) { 1895 removeBraces(Line->Children, Result); 1896 if (!Line->Affected) 1897 continue; 1898 for (FormatToken *Token = Line->First; Token && !Token->Finalized; 1899 Token = Token->Next) { 1900 if (!Token->Optional) 1901 continue; 1902 assert(Token->isOneOf(tok::l_brace, tok::r_brace)); 1903 assert(Token->Next || Token == Line->Last); 1904 const auto Start = 1905 Token == Line->Last || 1906 (Token->Next->isOneOf(tok::kw_else, tok::comment) && 1907 Token->Next->NewlinesBefore > 0) 1908 ? Token->WhitespaceRange.getBegin() 1909 : Token->Tok.getLocation(); 1910 const auto Range = 1911 CharSourceRange::getCharRange(Start, Token->Tok.getEndLoc()); 1912 cantFail(Result.add(tooling::Replacement(SourceMgr, Range, ""))); 1913 } 1914 } 1915 } 1916 }; 1917 1918 class JavaScriptRequoter : public TokenAnalyzer { 1919 public: 1920 JavaScriptRequoter(const Environment &Env, const FormatStyle &Style) 1921 : TokenAnalyzer(Env, Style) {} 1922 1923 std::pair<tooling::Replacements, unsigned> 1924 analyze(TokenAnnotator &Annotator, 1925 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1926 FormatTokenLexer &Tokens) override { 1927 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 1928 tooling::Replacements Result; 1929 requoteJSStringLiteral(AnnotatedLines, Result); 1930 return {Result, 0}; 1931 } 1932 1933 private: 1934 // Replaces double/single-quoted string literal as appropriate, re-escaping 1935 // the contents in the process. 1936 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines, 1937 tooling::Replacements &Result) { 1938 for (AnnotatedLine *Line : Lines) { 1939 requoteJSStringLiteral(Line->Children, Result); 1940 if (!Line->Affected) 1941 continue; 1942 for (FormatToken *FormatTok = Line->First; FormatTok; 1943 FormatTok = FormatTok->Next) { 1944 StringRef Input = FormatTok->TokenText; 1945 if (FormatTok->Finalized || !FormatTok->isStringLiteral() || 1946 // NB: testing for not starting with a double quote to avoid 1947 // breaking `template strings`. 1948 (Style.JavaScriptQuotes == FormatStyle::JSQS_Single && 1949 !Input.startswith("\"")) || 1950 (Style.JavaScriptQuotes == FormatStyle::JSQS_Double && 1951 !Input.startswith("\'"))) { 1952 continue; 1953 } 1954 1955 // Change start and end quote. 1956 bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single; 1957 SourceLocation Start = FormatTok->Tok.getLocation(); 1958 auto Replace = [&](SourceLocation Start, unsigned Length, 1959 StringRef ReplacementText) { 1960 auto Err = Result.add(tooling::Replacement( 1961 Env.getSourceManager(), Start, Length, ReplacementText)); 1962 // FIXME: handle error. For now, print error message and skip the 1963 // replacement for release version. 1964 if (Err) { 1965 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1966 assert(false); 1967 } 1968 }; 1969 Replace(Start, 1, IsSingle ? "'" : "\""); 1970 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1, 1971 IsSingle ? "'" : "\""); 1972 1973 // Escape internal quotes. 1974 bool Escaped = false; 1975 for (size_t i = 1; i < Input.size() - 1; i++) { 1976 switch (Input[i]) { 1977 case '\\': 1978 if (!Escaped && i + 1 < Input.size() && 1979 ((IsSingle && Input[i + 1] == '"') || 1980 (!IsSingle && Input[i + 1] == '\''))) { 1981 // Remove this \, it's escaping a " or ' that no longer needs 1982 // escaping 1983 Replace(Start.getLocWithOffset(i), 1, ""); 1984 continue; 1985 } 1986 Escaped = !Escaped; 1987 break; 1988 case '\"': 1989 case '\'': 1990 if (!Escaped && IsSingle == (Input[i] == '\'')) { 1991 // Escape the quote. 1992 Replace(Start.getLocWithOffset(i), 0, "\\"); 1993 } 1994 Escaped = false; 1995 break; 1996 default: 1997 Escaped = false; 1998 break; 1999 } 2000 } 2001 } 2002 } 2003 } 2004 }; 2005 2006 class Formatter : public TokenAnalyzer { 2007 public: 2008 Formatter(const Environment &Env, const FormatStyle &Style, 2009 FormattingAttemptStatus *Status) 2010 : TokenAnalyzer(Env, Style), Status(Status) {} 2011 2012 std::pair<tooling::Replacements, unsigned> 2013 analyze(TokenAnnotator &Annotator, 2014 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 2015 FormatTokenLexer &Tokens) override { 2016 tooling::Replacements Result; 2017 deriveLocalStyle(AnnotatedLines); 2018 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 2019 for (AnnotatedLine *Line : AnnotatedLines) 2020 Annotator.calculateFormattingInformation(*Line); 2021 Annotator.setCommentLineLevels(AnnotatedLines); 2022 2023 WhitespaceManager Whitespaces( 2024 Env.getSourceManager(), Style, 2025 Style.DeriveLineEnding 2026 ? WhitespaceManager::inputUsesCRLF( 2027 Env.getSourceManager().getBufferData(Env.getFileID()), 2028 Style.UseCRLF) 2029 : Style.UseCRLF); 2030 ContinuationIndenter Indenter(Style, Tokens.getKeywords(), 2031 Env.getSourceManager(), Whitespaces, Encoding, 2032 BinPackInconclusiveFunctions); 2033 unsigned Penalty = 2034 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style, 2035 Tokens.getKeywords(), Env.getSourceManager(), 2036 Status) 2037 .format(AnnotatedLines, /*DryRun=*/false, 2038 /*AdditionalIndent=*/0, 2039 /*FixBadIndentation=*/false, 2040 /*FirstStartColumn=*/Env.getFirstStartColumn(), 2041 /*NextStartColumn=*/Env.getNextStartColumn(), 2042 /*LastStartColumn=*/Env.getLastStartColumn()); 2043 for (const auto &R : Whitespaces.generateReplacements()) 2044 if (Result.add(R)) 2045 return std::make_pair(Result, 0); 2046 return std::make_pair(Result, Penalty); 2047 } 2048 2049 private: 2050 bool 2051 hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) { 2052 for (const AnnotatedLine *Line : Lines) { 2053 if (hasCpp03IncompatibleFormat(Line->Children)) 2054 return true; 2055 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) { 2056 if (!Tok->hasWhitespaceBefore()) { 2057 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener)) 2058 return true; 2059 if (Tok->is(TT_TemplateCloser) && 2060 Tok->Previous->is(TT_TemplateCloser)) { 2061 return true; 2062 } 2063 } 2064 } 2065 } 2066 return false; 2067 } 2068 2069 int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) { 2070 int AlignmentDiff = 0; 2071 for (const AnnotatedLine *Line : Lines) { 2072 AlignmentDiff += countVariableAlignments(Line->Children); 2073 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) { 2074 if (!Tok->is(TT_PointerOrReference)) 2075 continue; 2076 // Don't treat space in `void foo() &&` as evidence. 2077 if (const auto *Prev = Tok->getPreviousNonComment()) { 2078 if (Prev->is(tok::r_paren) && Prev->MatchingParen) { 2079 if (const auto *Func = 2080 Prev->MatchingParen->getPreviousNonComment()) { 2081 if (Func->isOneOf(TT_FunctionDeclarationName, TT_StartOfName, 2082 TT_OverloadedOperator)) { 2083 continue; 2084 } 2085 } 2086 } 2087 } 2088 bool SpaceBefore = Tok->hasWhitespaceBefore(); 2089 bool SpaceAfter = Tok->Next->hasWhitespaceBefore(); 2090 if (SpaceBefore && !SpaceAfter) 2091 ++AlignmentDiff; 2092 if (!SpaceBefore && SpaceAfter) 2093 --AlignmentDiff; 2094 } 2095 } 2096 return AlignmentDiff; 2097 } 2098 2099 void 2100 deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 2101 bool HasBinPackedFunction = false; 2102 bool HasOnePerLineFunction = false; 2103 for (AnnotatedLine *Line : AnnotatedLines) { 2104 if (!Line->First->Next) 2105 continue; 2106 FormatToken *Tok = Line->First->Next; 2107 while (Tok->Next) { 2108 if (Tok->is(PPK_BinPacked)) 2109 HasBinPackedFunction = true; 2110 if (Tok->is(PPK_OnePerLine)) 2111 HasOnePerLineFunction = true; 2112 2113 Tok = Tok->Next; 2114 } 2115 } 2116 if (Style.DerivePointerAlignment) { 2117 Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0 2118 ? FormatStyle::PAS_Left 2119 : FormatStyle::PAS_Right; 2120 Style.ReferenceAlignment = FormatStyle::RAS_Pointer; 2121 } 2122 if (Style.Standard == FormatStyle::LS_Auto) { 2123 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines) 2124 ? FormatStyle::LS_Latest 2125 : FormatStyle::LS_Cpp03; 2126 } 2127 BinPackInconclusiveFunctions = 2128 HasBinPackedFunction || !HasOnePerLineFunction; 2129 } 2130 2131 bool BinPackInconclusiveFunctions; 2132 FormattingAttemptStatus *Status; 2133 }; 2134 2135 /// TrailingCommaInserter inserts trailing commas into container literals. 2136 /// E.g.: 2137 /// const x = [ 2138 /// 1, 2139 /// ]; 2140 /// TrailingCommaInserter runs after formatting. To avoid causing a required 2141 /// reformatting (and thus reflow), it never inserts a comma that'd exceed the 2142 /// ColumnLimit. 2143 /// 2144 /// Because trailing commas disable binpacking of arrays, TrailingCommaInserter 2145 /// is conceptually incompatible with bin packing. 2146 class TrailingCommaInserter : public TokenAnalyzer { 2147 public: 2148 TrailingCommaInserter(const Environment &Env, const FormatStyle &Style) 2149 : TokenAnalyzer(Env, Style) {} 2150 2151 std::pair<tooling::Replacements, unsigned> 2152 analyze(TokenAnnotator &Annotator, 2153 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 2154 FormatTokenLexer &Tokens) override { 2155 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 2156 tooling::Replacements Result; 2157 insertTrailingCommas(AnnotatedLines, Result); 2158 return {Result, 0}; 2159 } 2160 2161 private: 2162 /// Inserts trailing commas in [] and {} initializers if they wrap over 2163 /// multiple lines. 2164 void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines, 2165 tooling::Replacements &Result) { 2166 for (AnnotatedLine *Line : Lines) { 2167 insertTrailingCommas(Line->Children, Result); 2168 if (!Line->Affected) 2169 continue; 2170 for (FormatToken *FormatTok = Line->First; FormatTok; 2171 FormatTok = FormatTok->Next) { 2172 if (FormatTok->NewlinesBefore == 0) 2173 continue; 2174 FormatToken *Matching = FormatTok->MatchingParen; 2175 if (!Matching || !FormatTok->getPreviousNonComment()) 2176 continue; 2177 if (!(FormatTok->is(tok::r_square) && 2178 Matching->is(TT_ArrayInitializerLSquare)) && 2179 !(FormatTok->is(tok::r_brace) && Matching->is(TT_DictLiteral))) { 2180 continue; 2181 } 2182 FormatToken *Prev = FormatTok->getPreviousNonComment(); 2183 if (Prev->is(tok::comma) || Prev->is(tok::semi)) 2184 continue; 2185 // getEndLoc is not reliably set during re-lexing, use text length 2186 // instead. 2187 SourceLocation Start = 2188 Prev->Tok.getLocation().getLocWithOffset(Prev->TokenText.size()); 2189 // If inserting a comma would push the code over the column limit, skip 2190 // this location - it'd introduce an unstable formatting due to the 2191 // required reflow. 2192 unsigned ColumnNumber = 2193 Env.getSourceManager().getSpellingColumnNumber(Start); 2194 if (ColumnNumber > Style.ColumnLimit) 2195 continue; 2196 // Comma insertions cannot conflict with each other, and this pass has a 2197 // clean set of Replacements, so the operation below cannot fail. 2198 cantFail(Result.add( 2199 tooling::Replacement(Env.getSourceManager(), Start, 0, ","))); 2200 } 2201 } 2202 } 2203 }; 2204 2205 // This class clean up the erroneous/redundant code around the given ranges in 2206 // file. 2207 class Cleaner : public TokenAnalyzer { 2208 public: 2209 Cleaner(const Environment &Env, const FormatStyle &Style) 2210 : TokenAnalyzer(Env, Style), 2211 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {} 2212 2213 // FIXME: eliminate unused parameters. 2214 std::pair<tooling::Replacements, unsigned> 2215 analyze(TokenAnnotator &Annotator, 2216 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 2217 FormatTokenLexer &Tokens) override { 2218 // FIXME: in the current implementation the granularity of affected range 2219 // is an annotated line. However, this is not sufficient. Furthermore, 2220 // redundant code introduced by replacements does not necessarily 2221 // intercept with ranges of replacements that result in the redundancy. 2222 // To determine if some redundant code is actually introduced by 2223 // replacements(e.g. deletions), we need to come up with a more 2224 // sophisticated way of computing affected ranges. 2225 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 2226 2227 checkEmptyNamespace(AnnotatedLines); 2228 2229 for (auto *Line : AnnotatedLines) 2230 cleanupLine(Line); 2231 2232 return {generateFixes(), 0}; 2233 } 2234 2235 private: 2236 void cleanupLine(AnnotatedLine *Line) { 2237 for (auto *Child : Line->Children) 2238 cleanupLine(Child); 2239 2240 if (Line->Affected) { 2241 cleanupRight(Line->First, tok::comma, tok::comma); 2242 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma); 2243 cleanupRight(Line->First, tok::l_paren, tok::comma); 2244 cleanupLeft(Line->First, tok::comma, tok::r_paren); 2245 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace); 2246 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace); 2247 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal); 2248 } 2249 } 2250 2251 bool containsOnlyComments(const AnnotatedLine &Line) { 2252 for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next) 2253 if (Tok->isNot(tok::comment)) 2254 return false; 2255 return true; 2256 } 2257 2258 // Iterate through all lines and remove any empty (nested) namespaces. 2259 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 2260 std::set<unsigned> DeletedLines; 2261 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 2262 auto &Line = *AnnotatedLines[i]; 2263 if (Line.startsWithNamespace()) 2264 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines); 2265 } 2266 2267 for (auto Line : DeletedLines) { 2268 FormatToken *Tok = AnnotatedLines[Line]->First; 2269 while (Tok) { 2270 deleteToken(Tok); 2271 Tok = Tok->Next; 2272 } 2273 } 2274 } 2275 2276 // The function checks if the namespace, which starts from \p CurrentLine, and 2277 // its nested namespaces are empty and delete them if they are empty. It also 2278 // sets \p NewLine to the last line checked. 2279 // Returns true if the current namespace is empty. 2280 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 2281 unsigned CurrentLine, unsigned &NewLine, 2282 std::set<unsigned> &DeletedLines) { 2283 unsigned InitLine = CurrentLine, End = AnnotatedLines.size(); 2284 if (Style.BraceWrapping.AfterNamespace) { 2285 // If the left brace is in a new line, we should consume it first so that 2286 // it does not make the namespace non-empty. 2287 // FIXME: error handling if there is no left brace. 2288 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) { 2289 NewLine = CurrentLine; 2290 return false; 2291 } 2292 } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) { 2293 return false; 2294 } 2295 while (++CurrentLine < End) { 2296 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace)) 2297 break; 2298 2299 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) { 2300 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine, 2301 DeletedLines)) { 2302 return false; 2303 } 2304 CurrentLine = NewLine; 2305 continue; 2306 } 2307 2308 if (containsOnlyComments(*AnnotatedLines[CurrentLine])) 2309 continue; 2310 2311 // If there is anything other than comments or nested namespaces in the 2312 // current namespace, the namespace cannot be empty. 2313 NewLine = CurrentLine; 2314 return false; 2315 } 2316 2317 NewLine = CurrentLine; 2318 if (CurrentLine >= End) 2319 return false; 2320 2321 // Check if the empty namespace is actually affected by changed ranges. 2322 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange( 2323 AnnotatedLines[InitLine]->First->Tok.getLocation(), 2324 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) { 2325 return false; 2326 } 2327 2328 for (unsigned i = InitLine; i <= CurrentLine; ++i) 2329 DeletedLines.insert(i); 2330 2331 return true; 2332 } 2333 2334 // Checks pairs {start, start->next},..., {end->previous, end} and deletes one 2335 // of the token in the pair if the left token has \p LK token kind and the 2336 // right token has \p RK token kind. If \p DeleteLeft is true, the left token 2337 // is deleted on match; otherwise, the right token is deleted. 2338 template <typename LeftKind, typename RightKind> 2339 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK, 2340 bool DeleteLeft) { 2341 auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * { 2342 for (auto *Res = Tok.Next; Res; Res = Res->Next) { 2343 if (!Res->is(tok::comment) && 2344 DeletedTokens.find(Res) == DeletedTokens.end()) { 2345 return Res; 2346 } 2347 } 2348 return nullptr; 2349 }; 2350 for (auto *Left = Start; Left;) { 2351 auto *Right = NextNotDeleted(*Left); 2352 if (!Right) 2353 break; 2354 if (Left->is(LK) && Right->is(RK)) { 2355 deleteToken(DeleteLeft ? Left : Right); 2356 for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next) 2357 deleteToken(Tok); 2358 // If the right token is deleted, we should keep the left token 2359 // unchanged and pair it with the new right token. 2360 if (!DeleteLeft) 2361 continue; 2362 } 2363 Left = Right; 2364 } 2365 } 2366 2367 template <typename LeftKind, typename RightKind> 2368 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) { 2369 cleanupPair(Start, LK, RK, /*DeleteLeft=*/true); 2370 } 2371 2372 template <typename LeftKind, typename RightKind> 2373 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) { 2374 cleanupPair(Start, LK, RK, /*DeleteLeft=*/false); 2375 } 2376 2377 // Delete the given token. 2378 inline void deleteToken(FormatToken *Tok) { 2379 if (Tok) 2380 DeletedTokens.insert(Tok); 2381 } 2382 2383 tooling::Replacements generateFixes() { 2384 tooling::Replacements Fixes; 2385 std::vector<FormatToken *> Tokens; 2386 std::copy(DeletedTokens.begin(), DeletedTokens.end(), 2387 std::back_inserter(Tokens)); 2388 2389 // Merge multiple continuous token deletions into one big deletion so that 2390 // the number of replacements can be reduced. This makes computing affected 2391 // ranges more efficient when we run reformat on the changed code. 2392 unsigned Idx = 0; 2393 while (Idx < Tokens.size()) { 2394 unsigned St = Idx, End = Idx; 2395 while ((End + 1) < Tokens.size() && Tokens[End]->Next == Tokens[End + 1]) 2396 ++End; 2397 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(), 2398 Tokens[End]->Tok.getEndLoc()); 2399 auto Err = 2400 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, "")); 2401 // FIXME: better error handling. for now just print error message and skip 2402 // for the release version. 2403 if (Err) { 2404 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 2405 assert(false && "Fixes must not conflict!"); 2406 } 2407 Idx = End + 1; 2408 } 2409 2410 return Fixes; 2411 } 2412 2413 // Class for less-than inequality comparason for the set `RedundantTokens`. 2414 // We store tokens in the order they appear in the translation unit so that 2415 // we do not need to sort them in `generateFixes()`. 2416 struct FormatTokenLess { 2417 FormatTokenLess(const SourceManager &SM) : SM(SM) {} 2418 2419 bool operator()(const FormatToken *LHS, const FormatToken *RHS) const { 2420 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(), 2421 RHS->Tok.getLocation()); 2422 } 2423 const SourceManager &SM; 2424 }; 2425 2426 // Tokens to be deleted. 2427 std::set<FormatToken *, FormatTokenLess> DeletedTokens; 2428 }; 2429 2430 class ObjCHeaderStyleGuesser : public TokenAnalyzer { 2431 public: 2432 ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style) 2433 : TokenAnalyzer(Env, Style), IsObjC(false) {} 2434 2435 std::pair<tooling::Replacements, unsigned> 2436 analyze(TokenAnnotator &Annotator, 2437 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 2438 FormatTokenLexer &Tokens) override { 2439 assert(Style.Language == FormatStyle::LK_Cpp); 2440 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines, 2441 Tokens.getKeywords()); 2442 tooling::Replacements Result; 2443 return {Result, 0}; 2444 } 2445 2446 bool isObjC() { return IsObjC; } 2447 2448 private: 2449 static bool 2450 guessIsObjC(const SourceManager &SourceManager, 2451 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 2452 const AdditionalKeywords &Keywords) { 2453 // Keep this array sorted, since we are binary searching over it. 2454 static constexpr llvm::StringLiteral FoundationIdentifiers[] = { 2455 "CGFloat", 2456 "CGPoint", 2457 "CGPointMake", 2458 "CGPointZero", 2459 "CGRect", 2460 "CGRectEdge", 2461 "CGRectInfinite", 2462 "CGRectMake", 2463 "CGRectNull", 2464 "CGRectZero", 2465 "CGSize", 2466 "CGSizeMake", 2467 "CGVector", 2468 "CGVectorMake", 2469 "NSAffineTransform", 2470 "NSArray", 2471 "NSAttributedString", 2472 "NSBlockOperation", 2473 "NSBundle", 2474 "NSCache", 2475 "NSCalendar", 2476 "NSCharacterSet", 2477 "NSCountedSet", 2478 "NSData", 2479 "NSDataDetector", 2480 "NSDecimal", 2481 "NSDecimalNumber", 2482 "NSDictionary", 2483 "NSEdgeInsets", 2484 "NSHashTable", 2485 "NSIndexPath", 2486 "NSIndexSet", 2487 "NSInteger", 2488 "NSInvocationOperation", 2489 "NSLocale", 2490 "NSMapTable", 2491 "NSMutableArray", 2492 "NSMutableAttributedString", 2493 "NSMutableCharacterSet", 2494 "NSMutableData", 2495 "NSMutableDictionary", 2496 "NSMutableIndexSet", 2497 "NSMutableOrderedSet", 2498 "NSMutableSet", 2499 "NSMutableString", 2500 "NSNumber", 2501 "NSNumberFormatter", 2502 "NSObject", 2503 "NSOperation", 2504 "NSOperationQueue", 2505 "NSOperationQueuePriority", 2506 "NSOrderedSet", 2507 "NSPoint", 2508 "NSPointerArray", 2509 "NSQualityOfService", 2510 "NSRange", 2511 "NSRect", 2512 "NSRegularExpression", 2513 "NSSet", 2514 "NSSize", 2515 "NSString", 2516 "NSTimeZone", 2517 "NSUInteger", 2518 "NSURL", 2519 "NSURLComponents", 2520 "NSURLQueryItem", 2521 "NSUUID", 2522 "NSValue", 2523 "UIImage", 2524 "UIView", 2525 }; 2526 2527 for (auto Line : AnnotatedLines) { 2528 if (Line->First && (Line->First->TokenText.startswith("#") || 2529 Line->First->TokenText == "__pragma" || 2530 Line->First->TokenText == "_Pragma")) { 2531 continue; 2532 } 2533 for (const FormatToken *FormatTok = Line->First; FormatTok; 2534 FormatTok = FormatTok->Next) { 2535 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) && 2536 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword || 2537 FormatTok->isOneOf(tok::numeric_constant, tok::l_square, 2538 tok::l_brace))) || 2539 (FormatTok->Tok.isAnyIdentifier() && 2540 std::binary_search(std::begin(FoundationIdentifiers), 2541 std::end(FoundationIdentifiers), 2542 FormatTok->TokenText)) || 2543 FormatTok->is(TT_ObjCStringLiteral) || 2544 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM, 2545 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace, 2546 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn, 2547 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier, 2548 TT_ObjCProperty)) { 2549 LLVM_DEBUG(llvm::dbgs() 2550 << "Detected ObjC at location " 2551 << FormatTok->Tok.getLocation().printToString( 2552 SourceManager) 2553 << " token: " << FormatTok->TokenText << " token type: " 2554 << getTokenTypeName(FormatTok->getType()) << "\n"); 2555 return true; 2556 } 2557 if (guessIsObjC(SourceManager, Line->Children, Keywords)) 2558 return true; 2559 } 2560 } 2561 return false; 2562 } 2563 2564 bool IsObjC; 2565 }; 2566 2567 struct IncludeDirective { 2568 StringRef Filename; 2569 StringRef Text; 2570 unsigned Offset; 2571 int Category; 2572 int Priority; 2573 }; 2574 2575 struct JavaImportDirective { 2576 StringRef Identifier; 2577 StringRef Text; 2578 unsigned Offset; 2579 std::vector<StringRef> AssociatedCommentLines; 2580 bool IsStatic; 2581 }; 2582 2583 } // end anonymous namespace 2584 2585 // Determines whether 'Ranges' intersects with ('Start', 'End'). 2586 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start, 2587 unsigned End) { 2588 for (auto Range : Ranges) { 2589 if (Range.getOffset() < End && 2590 Range.getOffset() + Range.getLength() > Start) { 2591 return true; 2592 } 2593 } 2594 return false; 2595 } 2596 2597 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor 2598 // before sorting/deduplicating. Index is the index of the include under the 2599 // cursor in the original set of includes. If this include has duplicates, it is 2600 // the index of the first of the duplicates as the others are going to be 2601 // removed. OffsetToEOL describes the cursor's position relative to the end of 2602 // its current line. 2603 // If `Cursor` is not on any #include, `Index` will be UINT_MAX. 2604 static std::pair<unsigned, unsigned> 2605 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes, 2606 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) { 2607 unsigned CursorIndex = UINT_MAX; 2608 unsigned OffsetToEOL = 0; 2609 for (int i = 0, e = Includes.size(); i != e; ++i) { 2610 unsigned Start = Includes[Indices[i]].Offset; 2611 unsigned End = Start + Includes[Indices[i]].Text.size(); 2612 if (!(Cursor >= Start && Cursor < End)) 2613 continue; 2614 CursorIndex = Indices[i]; 2615 OffsetToEOL = End - Cursor; 2616 // Put the cursor on the only remaining #include among the duplicate 2617 // #includes. 2618 while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text) 2619 CursorIndex = i; 2620 break; 2621 } 2622 return std::make_pair(CursorIndex, OffsetToEOL); 2623 } 2624 2625 // Replace all "\r\n" with "\n". 2626 std::string replaceCRLF(const std::string &Code) { 2627 std::string NewCode; 2628 size_t Pos = 0, LastPos = 0; 2629 2630 do { 2631 Pos = Code.find("\r\n", LastPos); 2632 if (Pos == LastPos) { 2633 ++LastPos; 2634 continue; 2635 } 2636 if (Pos == std::string::npos) { 2637 NewCode += Code.substr(LastPos); 2638 break; 2639 } 2640 NewCode += Code.substr(LastPos, Pos - LastPos) + "\n"; 2641 LastPos = Pos + 2; 2642 } while (Pos != std::string::npos); 2643 2644 return NewCode; 2645 } 2646 2647 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically 2648 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict 2649 // source order. 2650 // #include directives with the same text will be deduplicated, and only the 2651 // first #include in the duplicate #includes remains. If the `Cursor` is 2652 // provided and put on a deleted #include, it will be moved to the remaining 2653 // #include in the duplicate #includes. 2654 static void sortCppIncludes(const FormatStyle &Style, 2655 const SmallVectorImpl<IncludeDirective> &Includes, 2656 ArrayRef<tooling::Range> Ranges, StringRef FileName, 2657 StringRef Code, tooling::Replacements &Replaces, 2658 unsigned *Cursor) { 2659 tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName); 2660 const unsigned IncludesBeginOffset = Includes.front().Offset; 2661 const unsigned IncludesEndOffset = 2662 Includes.back().Offset + Includes.back().Text.size(); 2663 const unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset; 2664 if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset)) 2665 return; 2666 SmallVector<unsigned, 16> Indices = 2667 llvm::to_vector<16>(llvm::seq<unsigned>(0, Includes.size())); 2668 2669 if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive) { 2670 llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) { 2671 const auto LHSFilenameLower = Includes[LHSI].Filename.lower(); 2672 const auto RHSFilenameLower = Includes[RHSI].Filename.lower(); 2673 return std::tie(Includes[LHSI].Priority, LHSFilenameLower, 2674 Includes[LHSI].Filename) < 2675 std::tie(Includes[RHSI].Priority, RHSFilenameLower, 2676 Includes[RHSI].Filename); 2677 }); 2678 } else { 2679 llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) { 2680 return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) < 2681 std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename); 2682 }); 2683 } 2684 2685 // The index of the include on which the cursor will be put after 2686 // sorting/deduplicating. 2687 unsigned CursorIndex; 2688 // The offset from cursor to the end of line. 2689 unsigned CursorToEOLOffset; 2690 if (Cursor) { 2691 std::tie(CursorIndex, CursorToEOLOffset) = 2692 FindCursorIndex(Includes, Indices, *Cursor); 2693 } 2694 2695 // Deduplicate #includes. 2696 Indices.erase(std::unique(Indices.begin(), Indices.end(), 2697 [&](unsigned LHSI, unsigned RHSI) { 2698 return Includes[LHSI].Text.trim() == 2699 Includes[RHSI].Text.trim(); 2700 }), 2701 Indices.end()); 2702 2703 int CurrentCategory = Includes.front().Category; 2704 2705 // If the #includes are out of order, we generate a single replacement fixing 2706 // the entire block. Otherwise, no replacement is generated. 2707 // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not 2708 // enough as additional newlines might be added or removed across #include 2709 // blocks. This we handle below by generating the updated #include blocks and 2710 // comparing it to the original. 2711 if (Indices.size() == Includes.size() && llvm::is_sorted(Indices) && 2712 Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve) { 2713 return; 2714 } 2715 2716 std::string result; 2717 for (unsigned Index : Indices) { 2718 if (!result.empty()) { 2719 result += "\n"; 2720 if (Style.IncludeStyle.IncludeBlocks == 2721 tooling::IncludeStyle::IBS_Regroup && 2722 CurrentCategory != Includes[Index].Category) { 2723 result += "\n"; 2724 } 2725 } 2726 result += Includes[Index].Text; 2727 if (Cursor && CursorIndex == Index) 2728 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset; 2729 CurrentCategory = Includes[Index].Category; 2730 } 2731 2732 if (Cursor && *Cursor >= IncludesEndOffset) 2733 *Cursor += result.size() - IncludesBlockSize; 2734 2735 // If the #includes are out of order, we generate a single replacement fixing 2736 // the entire range of blocks. Otherwise, no replacement is generated. 2737 if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr( 2738 IncludesBeginOffset, IncludesBlockSize)))) { 2739 return; 2740 } 2741 2742 auto Err = Replaces.add(tooling::Replacement( 2743 FileName, Includes.front().Offset, IncludesBlockSize, result)); 2744 // FIXME: better error handling. For now, just skip the replacement for the 2745 // release version. 2746 if (Err) { 2747 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 2748 assert(false); 2749 } 2750 } 2751 2752 namespace { 2753 2754 const char CppIncludeRegexPattern[] = 2755 R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))"; 2756 2757 } // anonymous namespace 2758 2759 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code, 2760 ArrayRef<tooling::Range> Ranges, 2761 StringRef FileName, 2762 tooling::Replacements &Replaces, 2763 unsigned *Cursor) { 2764 unsigned Prev = llvm::StringSwitch<size_t>(Code) 2765 .StartsWith("\xEF\xBB\xBF", 3) // UTF-8 BOM 2766 .Default(0); 2767 unsigned SearchFrom = 0; 2768 llvm::Regex IncludeRegex(CppIncludeRegexPattern); 2769 SmallVector<StringRef, 4> Matches; 2770 SmallVector<IncludeDirective, 16> IncludesInBlock; 2771 2772 // In compiled files, consider the first #include to be the main #include of 2773 // the file if it is not a system #include. This ensures that the header 2774 // doesn't have hidden dependencies 2775 // (http://llvm.org/docs/CodingStandards.html#include-style). 2776 // 2777 // FIXME: Do some validation, e.g. edit distance of the base name, to fix 2778 // cases where the first #include is unlikely to be the main header. 2779 tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName); 2780 bool FirstIncludeBlock = true; 2781 bool MainIncludeFound = false; 2782 bool FormattingOff = false; 2783 2784 // '[' must be the first and '-' the last character inside [...]. 2785 llvm::Regex RawStringRegex( 2786 "R\"([][A-Za-z0-9_{}#<>%:;.?*+/^&\\$|~!=,'-]*)\\("); 2787 SmallVector<StringRef, 2> RawStringMatches; 2788 std::string RawStringTermination = ")\""; 2789 2790 for (;;) { 2791 auto Pos = Code.find('\n', SearchFrom); 2792 StringRef Line = 2793 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); 2794 2795 StringRef Trimmed = Line.trim(); 2796 2797 // #includes inside raw string literals need to be ignored. 2798 // or we will sort the contents of the string. 2799 // Skip past until we think we are at the rawstring literal close. 2800 if (RawStringRegex.match(Trimmed, &RawStringMatches)) { 2801 std::string CharSequence = RawStringMatches[1].str(); 2802 RawStringTermination = ")" + CharSequence + "\""; 2803 FormattingOff = true; 2804 } 2805 2806 if (Trimmed.contains(RawStringTermination)) 2807 FormattingOff = false; 2808 2809 if (Trimmed == "// clang-format off" || 2810 Trimmed == "/* clang-format off */") { 2811 FormattingOff = true; 2812 } else if (Trimmed == "// clang-format on" || 2813 Trimmed == "/* clang-format on */") { 2814 FormattingOff = false; 2815 } 2816 2817 const bool EmptyLineSkipped = 2818 Trimmed.empty() && 2819 (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge || 2820 Style.IncludeStyle.IncludeBlocks == 2821 tooling::IncludeStyle::IBS_Regroup); 2822 2823 bool MergeWithNextLine = Trimmed.endswith("\\"); 2824 if (!FormattingOff && !MergeWithNextLine) { 2825 if (IncludeRegex.match(Line, &Matches)) { 2826 StringRef IncludeName = Matches[2]; 2827 if (Line.contains("/*") && !Line.contains("*/")) { 2828 // #include with a start of a block comment, but without the end. 2829 // Need to keep all the lines until the end of the comment together. 2830 // FIXME: This is somehow simplified check that probably does not work 2831 // correctly if there are multiple comments on a line. 2832 Pos = Code.find("*/", SearchFrom); 2833 Line = Code.substr( 2834 Prev, (Pos != StringRef::npos ? Pos + 2 : Code.size()) - Prev); 2835 } 2836 int Category = Categories.getIncludePriority( 2837 IncludeName, 2838 /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock); 2839 int Priority = Categories.getSortIncludePriority( 2840 IncludeName, !MainIncludeFound && FirstIncludeBlock); 2841 if (Category == 0) 2842 MainIncludeFound = true; 2843 IncludesInBlock.push_back( 2844 {IncludeName, Line, Prev, Category, Priority}); 2845 } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) { 2846 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, 2847 Replaces, Cursor); 2848 IncludesInBlock.clear(); 2849 if (Trimmed.startswith("#pragma hdrstop")) // Precompiled headers. 2850 FirstIncludeBlock = true; 2851 else 2852 FirstIncludeBlock = false; 2853 } 2854 } 2855 if (Pos == StringRef::npos || Pos + 1 == Code.size()) 2856 break; 2857 2858 if (!MergeWithNextLine) 2859 Prev = Pos + 1; 2860 SearchFrom = Pos + 1; 2861 } 2862 if (!IncludesInBlock.empty()) { 2863 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces, 2864 Cursor); 2865 } 2866 return Replaces; 2867 } 2868 2869 // Returns group number to use as a first order sort on imports. Gives UINT_MAX 2870 // if the import does not match any given groups. 2871 static unsigned findJavaImportGroup(const FormatStyle &Style, 2872 StringRef ImportIdentifier) { 2873 unsigned LongestMatchIndex = UINT_MAX; 2874 unsigned LongestMatchLength = 0; 2875 for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) { 2876 const std::string &GroupPrefix = Style.JavaImportGroups[I]; 2877 if (ImportIdentifier.startswith(GroupPrefix) && 2878 GroupPrefix.length() > LongestMatchLength) { 2879 LongestMatchIndex = I; 2880 LongestMatchLength = GroupPrefix.length(); 2881 } 2882 } 2883 return LongestMatchIndex; 2884 } 2885 2886 // Sorts and deduplicates a block of includes given by 'Imports' based on 2887 // JavaImportGroups, then adding the necessary replacement to 'Replaces'. 2888 // Import declarations with the same text will be deduplicated. Between each 2889 // import group, a newline is inserted, and within each import group, a 2890 // lexicographic sort based on ASCII value is performed. 2891 static void sortJavaImports(const FormatStyle &Style, 2892 const SmallVectorImpl<JavaImportDirective> &Imports, 2893 ArrayRef<tooling::Range> Ranges, StringRef FileName, 2894 StringRef Code, tooling::Replacements &Replaces) { 2895 unsigned ImportsBeginOffset = Imports.front().Offset; 2896 unsigned ImportsEndOffset = 2897 Imports.back().Offset + Imports.back().Text.size(); 2898 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset; 2899 if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset)) 2900 return; 2901 2902 SmallVector<unsigned, 16> Indices = 2903 llvm::to_vector<16>(llvm::seq<unsigned>(0, Imports.size())); 2904 SmallVector<unsigned, 16> JavaImportGroups; 2905 JavaImportGroups.reserve(Imports.size()); 2906 for (const JavaImportDirective &Import : Imports) 2907 JavaImportGroups.push_back(findJavaImportGroup(Style, Import.Identifier)); 2908 2909 bool StaticImportAfterNormalImport = 2910 Style.SortJavaStaticImport == FormatStyle::SJSIO_After; 2911 llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) { 2912 // Negating IsStatic to push static imports above non-static imports. 2913 return std::make_tuple(!Imports[LHSI].IsStatic ^ 2914 StaticImportAfterNormalImport, 2915 JavaImportGroups[LHSI], Imports[LHSI].Identifier) < 2916 std::make_tuple(!Imports[RHSI].IsStatic ^ 2917 StaticImportAfterNormalImport, 2918 JavaImportGroups[RHSI], Imports[RHSI].Identifier); 2919 }); 2920 2921 // Deduplicate imports. 2922 Indices.erase(std::unique(Indices.begin(), Indices.end(), 2923 [&](unsigned LHSI, unsigned RHSI) { 2924 return Imports[LHSI].Text == Imports[RHSI].Text; 2925 }), 2926 Indices.end()); 2927 2928 bool CurrentIsStatic = Imports[Indices.front()].IsStatic; 2929 unsigned CurrentImportGroup = JavaImportGroups[Indices.front()]; 2930 2931 std::string result; 2932 for (unsigned Index : Indices) { 2933 if (!result.empty()) { 2934 result += "\n"; 2935 if (CurrentIsStatic != Imports[Index].IsStatic || 2936 CurrentImportGroup != JavaImportGroups[Index]) { 2937 result += "\n"; 2938 } 2939 } 2940 for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) { 2941 result += CommentLine; 2942 result += "\n"; 2943 } 2944 result += Imports[Index].Text; 2945 CurrentIsStatic = Imports[Index].IsStatic; 2946 CurrentImportGroup = JavaImportGroups[Index]; 2947 } 2948 2949 // If the imports are out of order, we generate a single replacement fixing 2950 // the entire block. Otherwise, no replacement is generated. 2951 if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr( 2952 Imports.front().Offset, ImportsBlockSize)))) { 2953 return; 2954 } 2955 2956 auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset, 2957 ImportsBlockSize, result)); 2958 // FIXME: better error handling. For now, just skip the replacement for the 2959 // release version. 2960 if (Err) { 2961 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 2962 assert(false); 2963 } 2964 } 2965 2966 namespace { 2967 2968 const char JavaImportRegexPattern[] = 2969 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"; 2970 2971 } // anonymous namespace 2972 2973 tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, 2974 ArrayRef<tooling::Range> Ranges, 2975 StringRef FileName, 2976 tooling::Replacements &Replaces) { 2977 unsigned Prev = 0; 2978 unsigned SearchFrom = 0; 2979 llvm::Regex ImportRegex(JavaImportRegexPattern); 2980 SmallVector<StringRef, 4> Matches; 2981 SmallVector<JavaImportDirective, 16> ImportsInBlock; 2982 std::vector<StringRef> AssociatedCommentLines; 2983 2984 bool FormattingOff = false; 2985 2986 for (;;) { 2987 auto Pos = Code.find('\n', SearchFrom); 2988 StringRef Line = 2989 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); 2990 2991 StringRef Trimmed = Line.trim(); 2992 if (Trimmed == "// clang-format off") 2993 FormattingOff = true; 2994 else if (Trimmed == "// clang-format on") 2995 FormattingOff = false; 2996 2997 if (ImportRegex.match(Line, &Matches)) { 2998 if (FormattingOff) { 2999 // If at least one import line has formatting turned off, turn off 3000 // formatting entirely. 3001 return Replaces; 3002 } 3003 StringRef Static = Matches[1]; 3004 StringRef Identifier = Matches[2]; 3005 bool IsStatic = false; 3006 if (Static.contains("static")) 3007 IsStatic = true; 3008 ImportsInBlock.push_back( 3009 {Identifier, Line, Prev, AssociatedCommentLines, IsStatic}); 3010 AssociatedCommentLines.clear(); 3011 } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) { 3012 // Associating comments within the imports with the nearest import below 3013 AssociatedCommentLines.push_back(Line); 3014 } 3015 Prev = Pos + 1; 3016 if (Pos == StringRef::npos || Pos + 1 == Code.size()) 3017 break; 3018 SearchFrom = Pos + 1; 3019 } 3020 if (!ImportsInBlock.empty()) 3021 sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces); 3022 return Replaces; 3023 } 3024 3025 bool isMpegTS(StringRef Code) { 3026 // MPEG transport streams use the ".ts" file extension. clang-format should 3027 // not attempt to format those. MPEG TS' frame format starts with 0x47 every 3028 // 189 bytes - detect that and return. 3029 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47; 3030 } 3031 3032 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); } 3033 3034 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, 3035 ArrayRef<tooling::Range> Ranges, 3036 StringRef FileName, unsigned *Cursor) { 3037 tooling::Replacements Replaces; 3038 if (!Style.SortIncludes || Style.DisableFormat) 3039 return Replaces; 3040 if (isLikelyXml(Code)) 3041 return Replaces; 3042 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript && 3043 isMpegTS(Code)) { 3044 return Replaces; 3045 } 3046 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript) 3047 return sortJavaScriptImports(Style, Code, Ranges, FileName); 3048 if (Style.Language == FormatStyle::LanguageKind::LK_Java) 3049 return sortJavaImports(Style, Code, Ranges, FileName, Replaces); 3050 sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor); 3051 return Replaces; 3052 } 3053 3054 template <typename T> 3055 static llvm::Expected<tooling::Replacements> 3056 processReplacements(T ProcessFunc, StringRef Code, 3057 const tooling::Replacements &Replaces, 3058 const FormatStyle &Style) { 3059 if (Replaces.empty()) 3060 return tooling::Replacements(); 3061 3062 auto NewCode = applyAllReplacements(Code, Replaces); 3063 if (!NewCode) 3064 return NewCode.takeError(); 3065 std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges(); 3066 StringRef FileName = Replaces.begin()->getFilePath(); 3067 3068 tooling::Replacements FormatReplaces = 3069 ProcessFunc(Style, *NewCode, ChangedRanges, FileName); 3070 3071 return Replaces.merge(FormatReplaces); 3072 } 3073 3074 llvm::Expected<tooling::Replacements> 3075 formatReplacements(StringRef Code, const tooling::Replacements &Replaces, 3076 const FormatStyle &Style) { 3077 // We need to use lambda function here since there are two versions of 3078 // `sortIncludes`. 3079 auto SortIncludes = [](const FormatStyle &Style, StringRef Code, 3080 std::vector<tooling::Range> Ranges, 3081 StringRef FileName) -> tooling::Replacements { 3082 return sortIncludes(Style, Code, Ranges, FileName); 3083 }; 3084 auto SortedReplaces = 3085 processReplacements(SortIncludes, Code, Replaces, Style); 3086 if (!SortedReplaces) 3087 return SortedReplaces.takeError(); 3088 3089 // We need to use lambda function here since there are two versions of 3090 // `reformat`. 3091 auto Reformat = [](const FormatStyle &Style, StringRef Code, 3092 std::vector<tooling::Range> Ranges, 3093 StringRef FileName) -> tooling::Replacements { 3094 return reformat(Style, Code, Ranges, FileName); 3095 }; 3096 return processReplacements(Reformat, Code, *SortedReplaces, Style); 3097 } 3098 3099 namespace { 3100 3101 inline bool isHeaderInsertion(const tooling::Replacement &Replace) { 3102 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 && 3103 llvm::Regex(CppIncludeRegexPattern) 3104 .match(Replace.getReplacementText()); 3105 } 3106 3107 inline bool isHeaderDeletion(const tooling::Replacement &Replace) { 3108 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1; 3109 } 3110 3111 // FIXME: insert empty lines between newly created blocks. 3112 tooling::Replacements 3113 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, 3114 const FormatStyle &Style) { 3115 if (!Style.isCpp()) 3116 return Replaces; 3117 3118 tooling::Replacements HeaderInsertions; 3119 std::set<llvm::StringRef> HeadersToDelete; 3120 tooling::Replacements Result; 3121 for (const auto &R : Replaces) { 3122 if (isHeaderInsertion(R)) { 3123 // Replacements from \p Replaces must be conflict-free already, so we can 3124 // simply consume the error. 3125 llvm::consumeError(HeaderInsertions.add(R)); 3126 } else if (isHeaderDeletion(R)) { 3127 HeadersToDelete.insert(R.getReplacementText()); 3128 } else if (R.getOffset() == UINT_MAX) { 3129 llvm::errs() << "Insertions other than header #include insertion are " 3130 "not supported! " 3131 << R.getReplacementText() << "\n"; 3132 } else { 3133 llvm::consumeError(Result.add(R)); 3134 } 3135 } 3136 if (HeaderInsertions.empty() && HeadersToDelete.empty()) 3137 return Replaces; 3138 3139 StringRef FileName = Replaces.begin()->getFilePath(); 3140 tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle); 3141 3142 for (const auto &Header : HeadersToDelete) { 3143 tooling::Replacements Replaces = 3144 Includes.remove(Header.trim("\"<>"), Header.startswith("<")); 3145 for (const auto &R : Replaces) { 3146 auto Err = Result.add(R); 3147 if (Err) { 3148 // Ignore the deletion on conflict. 3149 llvm::errs() << "Failed to add header deletion replacement for " 3150 << Header << ": " << llvm::toString(std::move(Err)) 3151 << "\n"; 3152 } 3153 } 3154 } 3155 3156 llvm::Regex IncludeRegex = llvm::Regex(CppIncludeRegexPattern); 3157 llvm::SmallVector<StringRef, 4> Matches; 3158 for (const auto &R : HeaderInsertions) { 3159 auto IncludeDirective = R.getReplacementText(); 3160 bool Matched = IncludeRegex.match(IncludeDirective, &Matches); 3161 assert(Matched && "Header insertion replacement must have replacement text " 3162 "'#include ...'"); 3163 (void)Matched; 3164 auto IncludeName = Matches[2]; 3165 auto Replace = 3166 Includes.insert(IncludeName.trim("\"<>"), IncludeName.startswith("<")); 3167 if (Replace) { 3168 auto Err = Result.add(*Replace); 3169 if (Err) { 3170 llvm::consumeError(std::move(Err)); 3171 unsigned NewOffset = 3172 Result.getShiftedCodePosition(Replace->getOffset()); 3173 auto Shifted = tooling::Replacement(FileName, NewOffset, 0, 3174 Replace->getReplacementText()); 3175 Result = Result.merge(tooling::Replacements(Shifted)); 3176 } 3177 } 3178 } 3179 return Result; 3180 } 3181 3182 } // anonymous namespace 3183 3184 llvm::Expected<tooling::Replacements> 3185 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces, 3186 const FormatStyle &Style) { 3187 // We need to use lambda function here since there are two versions of 3188 // `cleanup`. 3189 auto Cleanup = [](const FormatStyle &Style, StringRef Code, 3190 std::vector<tooling::Range> Ranges, 3191 StringRef FileName) -> tooling::Replacements { 3192 return cleanup(Style, Code, Ranges, FileName); 3193 }; 3194 // Make header insertion replacements insert new headers into correct blocks. 3195 tooling::Replacements NewReplaces = 3196 fixCppIncludeInsertions(Code, Replaces, Style); 3197 return processReplacements(Cleanup, Code, NewReplaces, Style); 3198 } 3199 3200 namespace internal { 3201 std::pair<tooling::Replacements, unsigned> 3202 reformat(const FormatStyle &Style, StringRef Code, 3203 ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn, 3204 unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, 3205 FormattingAttemptStatus *Status) { 3206 FormatStyle Expanded = Style; 3207 expandPresetsBraceWrapping(Expanded); 3208 expandPresetsSpaceBeforeParens(Expanded); 3209 switch (Expanded.RequiresClausePosition) { 3210 case FormatStyle::RCPS_SingleLine: 3211 case FormatStyle::RCPS_WithPreceding: 3212 Expanded.IndentRequiresClause = false; 3213 break; 3214 default: 3215 break; 3216 } 3217 3218 if (Expanded.DisableFormat) 3219 return {tooling::Replacements(), 0}; 3220 if (isLikelyXml(Code)) 3221 return {tooling::Replacements(), 0}; 3222 if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code)) 3223 return {tooling::Replacements(), 0}; 3224 3225 // JSON only needs the formatting passing. 3226 if (Style.isJson()) { 3227 std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); 3228 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn, 3229 NextStartColumn, LastStartColumn); 3230 if (!Env) 3231 return {}; 3232 // Perform the actual formatting pass. 3233 tooling::Replacements Replaces = 3234 Formatter(*Env, Style, Status).process().first; 3235 // add a replacement to remove the "x = " from the result. 3236 if (!Replaces.add(tooling::Replacement(FileName, 0, 4, ""))) { 3237 // apply the reformatting changes and the removal of "x = ". 3238 if (applyAllReplacements(Code, Replaces)) 3239 return {Replaces, 0}; 3240 } 3241 return {tooling::Replacements(), 0}; 3242 } 3243 3244 typedef std::function<std::pair<tooling::Replacements, unsigned>( 3245 const Environment &)> 3246 AnalyzerPass; 3247 SmallVector<AnalyzerPass, 8> Passes; 3248 3249 if (Style.isCpp()) { 3250 if (Style.QualifierAlignment != FormatStyle::QAS_Leave) { 3251 Passes.emplace_back([&](const Environment &Env) { 3252 return QualifierAlignmentFixer(Env, Expanded, Code, Ranges, 3253 FirstStartColumn, NextStartColumn, 3254 LastStartColumn, FileName) 3255 .process(); 3256 }); 3257 } 3258 3259 if (Style.InsertBraces) { 3260 Passes.emplace_back([&](const Environment &Env) { 3261 return BracesInserter(Env, Expanded).process(); 3262 }); 3263 } 3264 3265 if (Style.RemoveBracesLLVM) { 3266 Passes.emplace_back([&](const Environment &Env) { 3267 return BracesRemover(Env, Expanded).process(); 3268 }); 3269 } 3270 3271 if (Style.FixNamespaceComments) { 3272 Passes.emplace_back([&](const Environment &Env) { 3273 return NamespaceEndCommentsFixer(Env, Expanded).process(); 3274 }); 3275 } 3276 3277 if (Style.SortUsingDeclarations) { 3278 Passes.emplace_back([&](const Environment &Env) { 3279 return UsingDeclarationsSorter(Env, Expanded).process(); 3280 }); 3281 } 3282 } 3283 3284 if (Style.SeparateDefinitionBlocks != FormatStyle::SDS_Leave) { 3285 Passes.emplace_back([&](const Environment &Env) { 3286 return DefinitionBlockSeparator(Env, Expanded).process(); 3287 }); 3288 } 3289 3290 if (Style.isJavaScript() && 3291 Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) { 3292 Passes.emplace_back([&](const Environment &Env) { 3293 return JavaScriptRequoter(Env, Expanded).process(); 3294 }); 3295 } 3296 3297 Passes.emplace_back([&](const Environment &Env) { 3298 return Formatter(Env, Expanded, Status).process(); 3299 }); 3300 3301 if (Style.isJavaScript() && 3302 Style.InsertTrailingCommas == FormatStyle::TCS_Wrapped) { 3303 Passes.emplace_back([&](const Environment &Env) { 3304 return TrailingCommaInserter(Env, Expanded).process(); 3305 }); 3306 } 3307 3308 auto Env = Environment::make(Code, FileName, Ranges, FirstStartColumn, 3309 NextStartColumn, LastStartColumn); 3310 if (!Env) 3311 return {}; 3312 llvm::Optional<std::string> CurrentCode = None; 3313 tooling::Replacements Fixes; 3314 unsigned Penalty = 0; 3315 for (size_t I = 0, E = Passes.size(); I < E; ++I) { 3316 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env); 3317 auto NewCode = applyAllReplacements( 3318 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first); 3319 if (NewCode) { 3320 Fixes = Fixes.merge(PassFixes.first); 3321 Penalty += PassFixes.second; 3322 if (I + 1 < E) { 3323 CurrentCode = std::move(*NewCode); 3324 Env = Environment::make( 3325 *CurrentCode, FileName, 3326 tooling::calculateRangesAfterReplacements(Fixes, Ranges), 3327 FirstStartColumn, NextStartColumn, LastStartColumn); 3328 if (!Env) 3329 return {}; 3330 } 3331 } 3332 } 3333 3334 return {Fixes, Penalty}; 3335 } 3336 } // namespace internal 3337 3338 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 3339 ArrayRef<tooling::Range> Ranges, 3340 StringRef FileName, 3341 FormattingAttemptStatus *Status) { 3342 return internal::reformat(Style, Code, Ranges, 3343 /*FirstStartColumn=*/0, 3344 /*NextStartColumn=*/0, 3345 /*LastStartColumn=*/0, FileName, Status) 3346 .first; 3347 } 3348 3349 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, 3350 ArrayRef<tooling::Range> Ranges, 3351 StringRef FileName) { 3352 // cleanups only apply to C++ (they mostly concern ctor commas etc.) 3353 if (Style.Language != FormatStyle::LK_Cpp) 3354 return tooling::Replacements(); 3355 auto Env = Environment::make(Code, FileName, Ranges); 3356 if (!Env) 3357 return {}; 3358 return Cleaner(*Env, Style).process().first; 3359 } 3360 3361 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 3362 ArrayRef<tooling::Range> Ranges, 3363 StringRef FileName, bool *IncompleteFormat) { 3364 FormattingAttemptStatus Status; 3365 auto Result = reformat(Style, Code, Ranges, FileName, &Status); 3366 if (!Status.FormatComplete) 3367 *IncompleteFormat = true; 3368 return Result; 3369 } 3370 3371 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, 3372 StringRef Code, 3373 ArrayRef<tooling::Range> Ranges, 3374 StringRef FileName) { 3375 auto Env = Environment::make(Code, FileName, Ranges); 3376 if (!Env) 3377 return {}; 3378 return NamespaceEndCommentsFixer(*Env, Style).process().first; 3379 } 3380 3381 tooling::Replacements separateDefinitionBlocks(const FormatStyle &Style, 3382 StringRef Code, 3383 ArrayRef<tooling::Range> Ranges, 3384 StringRef FileName) { 3385 auto Env = Environment::make(Code, FileName, Ranges); 3386 if (!Env) 3387 return {}; 3388 return DefinitionBlockSeparator(*Env, Style).process().first; 3389 } 3390 3391 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, 3392 StringRef Code, 3393 ArrayRef<tooling::Range> Ranges, 3394 StringRef FileName) { 3395 auto Env = Environment::make(Code, FileName, Ranges); 3396 if (!Env) 3397 return {}; 3398 return UsingDeclarationsSorter(*Env, Style).process().first; 3399 } 3400 3401 LangOptions getFormattingLangOpts(const FormatStyle &Style) { 3402 LangOptions LangOpts; 3403 3404 FormatStyle::LanguageStandard LexingStd = Style.Standard; 3405 if (LexingStd == FormatStyle::LS_Auto) 3406 LexingStd = FormatStyle::LS_Latest; 3407 if (LexingStd == FormatStyle::LS_Latest) 3408 LexingStd = FormatStyle::LS_Cpp20; 3409 LangOpts.CPlusPlus = 1; 3410 LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11; 3411 LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14; 3412 LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp17; 3413 LangOpts.CPlusPlus20 = LexingStd >= FormatStyle::LS_Cpp20; 3414 LangOpts.Char8 = LexingStd >= FormatStyle::LS_Cpp20; 3415 // Turning on digraphs in standards before C++0x is error-prone, because e.g. 3416 // the sequence "<::" will be unconditionally treated as "[:". 3417 // Cf. Lexer::LexTokenInternal. 3418 LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11; 3419 3420 LangOpts.LineComment = 1; 3421 bool AlternativeOperators = Style.isCpp(); 3422 LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0; 3423 LangOpts.Bool = 1; 3424 LangOpts.ObjC = 1; 3425 LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally. 3426 LangOpts.DeclSpecKeyword = 1; // To get __declspec. 3427 LangOpts.C99 = 1; // To get kw_restrict for non-underscore-prefixed restrict. 3428 return LangOpts; 3429 } 3430 3431 const char *StyleOptionHelpDescription = 3432 "Coding style, currently supports:\n" 3433 " LLVM, GNU, Google, Chromium, Microsoft, Mozilla, WebKit.\n" 3434 "Use -style=file to load style configuration from\n" 3435 ".clang-format file located in one of the parent\n" 3436 "directories of the source file (or current\n" 3437 "directory for stdin).\n" 3438 "Use -style=file:<format_file_path> to explicitly specify\n" 3439 "the configuration file.\n" 3440 "Use -style=\"{key: value, ...}\" to set specific\n" 3441 "parameters, e.g.:\n" 3442 " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\""; 3443 3444 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) { 3445 if (FileName.endswith(".java")) 3446 return FormatStyle::LK_Java; 3447 if (FileName.endswith_insensitive(".js") || 3448 FileName.endswith_insensitive(".mjs") || 3449 FileName.endswith_insensitive(".ts")) { 3450 return FormatStyle::LK_JavaScript; // (module) JavaScript or TypeScript. 3451 } 3452 if (FileName.endswith(".m") || FileName.endswith(".mm")) 3453 return FormatStyle::LK_ObjC; 3454 if (FileName.endswith_insensitive(".proto") || 3455 FileName.endswith_insensitive(".protodevel")) { 3456 return FormatStyle::LK_Proto; 3457 } 3458 if (FileName.endswith_insensitive(".textpb") || 3459 FileName.endswith_insensitive(".pb.txt") || 3460 FileName.endswith_insensitive(".textproto") || 3461 FileName.endswith_insensitive(".asciipb")) { 3462 return FormatStyle::LK_TextProto; 3463 } 3464 if (FileName.endswith_insensitive(".td")) 3465 return FormatStyle::LK_TableGen; 3466 if (FileName.endswith_insensitive(".cs")) 3467 return FormatStyle::LK_CSharp; 3468 if (FileName.endswith_insensitive(".json")) 3469 return FormatStyle::LK_Json; 3470 return FormatStyle::LK_Cpp; 3471 } 3472 3473 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) { 3474 const auto GuessedLanguage = getLanguageByFileName(FileName); 3475 if (GuessedLanguage == FormatStyle::LK_Cpp) { 3476 auto Extension = llvm::sys::path::extension(FileName); 3477 // If there's no file extension (or it's .h), we need to check the contents 3478 // of the code to see if it contains Objective-C. 3479 if (Extension.empty() || Extension == ".h") { 3480 auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName; 3481 Environment Env(Code, NonEmptyFileName, /*Ranges=*/{}); 3482 ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle()); 3483 Guesser.process(); 3484 if (Guesser.isObjC()) 3485 return FormatStyle::LK_ObjC; 3486 } 3487 } 3488 return GuessedLanguage; 3489 } 3490 3491 const char *DefaultFormatStyle = "file"; 3492 3493 const char *DefaultFallbackStyle = "LLVM"; 3494 3495 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> 3496 loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS, 3497 FormatStyle *Style, bool AllowUnknownOptions) { 3498 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 3499 FS->getBufferForFile(ConfigFile.str()); 3500 if (auto EC = Text.getError()) 3501 return EC; 3502 if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions)) 3503 return EC; 3504 return Text; 3505 } 3506 3507 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, 3508 StringRef FallbackStyleName, 3509 StringRef Code, llvm::vfs::FileSystem *FS, 3510 bool AllowUnknownOptions) { 3511 if (!FS) 3512 FS = llvm::vfs::getRealFileSystem().get(); 3513 FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code)); 3514 3515 FormatStyle FallbackStyle = getNoStyle(); 3516 if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle)) 3517 return make_string_error("Invalid fallback style \"" + FallbackStyleName); 3518 3519 llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 1> 3520 ChildFormatTextToApply; 3521 3522 if (StyleName.startswith("{")) { 3523 // Parse YAML/JSON style from the command line. 3524 StringRef Source = "<command-line>"; 3525 if (std::error_code ec = 3526 parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style, 3527 AllowUnknownOptions)) { 3528 return make_string_error("Error parsing -style: " + ec.message()); 3529 } 3530 if (Style.InheritsParentConfig) { 3531 ChildFormatTextToApply.emplace_back( 3532 llvm::MemoryBuffer::getMemBuffer(StyleName, Source, false)); 3533 } else { 3534 return Style; 3535 } 3536 } 3537 3538 // User provided clang-format file using -style=file:path/to/format/file. 3539 if (!Style.InheritsParentConfig && 3540 StyleName.startswith_insensitive("file:")) { 3541 auto ConfigFile = StyleName.substr(5); 3542 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 3543 loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions); 3544 if (auto EC = Text.getError()) { 3545 return make_string_error("Error reading " + ConfigFile + ": " + 3546 EC.message()); 3547 } 3548 3549 LLVM_DEBUG(llvm::dbgs() 3550 << "Using configuration file " << ConfigFile << "\n"); 3551 3552 if (!Style.InheritsParentConfig) 3553 return Style; 3554 3555 // Search for parent configs starting from the parent directory of 3556 // ConfigFile. 3557 FileName = ConfigFile; 3558 ChildFormatTextToApply.emplace_back(std::move(*Text)); 3559 } 3560 3561 // If the style inherits the parent configuration it is a command line 3562 // configuration, which wants to inherit, so we have to skip the check of the 3563 // StyleName. 3564 if (!Style.InheritsParentConfig && !StyleName.equals_insensitive("file")) { 3565 if (!getPredefinedStyle(StyleName, Style.Language, &Style)) 3566 return make_string_error("Invalid value for -style"); 3567 if (!Style.InheritsParentConfig) 3568 return Style; 3569 } 3570 3571 // Reset possible inheritance 3572 Style.InheritsParentConfig = false; 3573 3574 // Look for .clang-format/_clang-format file in the file's parent directories. 3575 SmallString<128> UnsuitableConfigFiles; 3576 SmallString<128> Path(FileName); 3577 if (std::error_code EC = FS->makeAbsolute(Path)) 3578 return make_string_error(EC.message()); 3579 3580 llvm::SmallVector<std::string, 2> FilesToLookFor; 3581 FilesToLookFor.push_back(".clang-format"); 3582 FilesToLookFor.push_back("_clang-format"); 3583 3584 auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {}; 3585 3586 auto applyChildFormatTexts = [&](FormatStyle *Style) { 3587 for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) { 3588 auto EC = parseConfiguration(*MemBuf, Style, AllowUnknownOptions, 3589 dropDiagnosticHandler); 3590 // It was already correctly parsed. 3591 assert(!EC); 3592 static_cast<void>(EC); 3593 } 3594 }; 3595 3596 for (StringRef Directory = Path; !Directory.empty(); 3597 Directory = llvm::sys::path::parent_path(Directory)) { 3598 3599 auto Status = FS->status(Directory); 3600 if (!Status || 3601 Status->getType() != llvm::sys::fs::file_type::directory_file) { 3602 continue; 3603 } 3604 3605 for (const auto &F : FilesToLookFor) { 3606 SmallString<128> ConfigFile(Directory); 3607 3608 llvm::sys::path::append(ConfigFile, F); 3609 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 3610 3611 Status = FS->status(ConfigFile.str()); 3612 3613 if (Status && 3614 (Status->getType() == llvm::sys::fs::file_type::regular_file)) { 3615 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 3616 loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions); 3617 if (auto EC = Text.getError()) { 3618 if (EC == ParseError::Unsuitable) { 3619 if (!UnsuitableConfigFiles.empty()) 3620 UnsuitableConfigFiles.append(", "); 3621 UnsuitableConfigFiles.append(ConfigFile); 3622 continue; 3623 } 3624 return make_string_error("Error reading " + ConfigFile + ": " + 3625 EC.message()); 3626 } 3627 LLVM_DEBUG(llvm::dbgs() 3628 << "Using configuration file " << ConfigFile << "\n"); 3629 3630 if (!Style.InheritsParentConfig) { 3631 if (ChildFormatTextToApply.empty()) 3632 return Style; 3633 3634 LLVM_DEBUG(llvm::dbgs() << "Applying child configurations\n"); 3635 applyChildFormatTexts(&Style); 3636 3637 return Style; 3638 } 3639 3640 LLVM_DEBUG(llvm::dbgs() << "Inherits parent configuration\n"); 3641 3642 // Reset inheritance of style 3643 Style.InheritsParentConfig = false; 3644 3645 ChildFormatTextToApply.emplace_back(std::move(*Text)); 3646 3647 // Breaking out of the inner loop, since we don't want to parse 3648 // .clang-format AND _clang-format, if both exist. Then we continue the 3649 // inner loop (parent directories) in search for the parent 3650 // configuration. 3651 break; 3652 } 3653 } 3654 } 3655 if (!UnsuitableConfigFiles.empty()) { 3656 return make_string_error("Configuration file(s) do(es) not support " + 3657 getLanguageName(Style.Language) + ": " + 3658 UnsuitableConfigFiles); 3659 } 3660 3661 if (!ChildFormatTextToApply.empty()) { 3662 LLVM_DEBUG(llvm::dbgs() 3663 << "Applying child configurations on fallback style\n"); 3664 applyChildFormatTexts(&FallbackStyle); 3665 } 3666 3667 return FallbackStyle; 3668 } 3669 3670 } // namespace format 3671 } // namespace clang 3672