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