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 "ContinuationIndenter.h" 18 #include "FormatInternal.h" 19 #include "FormatTokenLexer.h" 20 #include "NamespaceEndCommentsFixer.h" 21 #include "SortJavaScriptImports.h" 22 #include "TokenAnalyzer.h" 23 #include "TokenAnnotator.h" 24 #include "UnwrappedLineFormatter.h" 25 #include "UnwrappedLineParser.h" 26 #include "UsingDeclarationsSorter.h" 27 #include "WhitespaceManager.h" 28 #include "clang/Basic/Diagnostic.h" 29 #include "clang/Basic/DiagnosticOptions.h" 30 #include "clang/Basic/SourceManager.h" 31 #include "clang/Lex/Lexer.h" 32 #include "clang/Tooling/Inclusions/HeaderIncludes.h" 33 #include "llvm/ADT/STLExtras.h" 34 #include "llvm/ADT/StringRef.h" 35 #include "llvm/Support/Allocator.h" 36 #include "llvm/Support/Debug.h" 37 #include "llvm/Support/Path.h" 38 #include "llvm/Support/Regex.h" 39 #include "llvm/Support/VirtualFileSystem.h" 40 #include "llvm/Support/YAMLTraits.h" 41 #include <algorithm> 42 #include <memory> 43 #include <mutex> 44 #include <string> 45 #include <unordered_map> 46 47 #define DEBUG_TYPE "format-formatter" 48 49 using clang::format::FormatStyle; 50 51 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::format::FormatStyle::RawStringFormat) 52 53 namespace llvm { 54 namespace yaml { 55 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> { 56 static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) { 57 IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp); 58 IO.enumCase(Value, "Java", FormatStyle::LK_Java); 59 IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript); 60 IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC); 61 IO.enumCase(Value, "Proto", FormatStyle::LK_Proto); 62 IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen); 63 IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto); 64 IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp); 65 } 66 }; 67 68 template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> { 69 static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) { 70 IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03); 71 IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03); 72 IO.enumCase(Value, "Cpp11", FormatStyle::LS_Cpp11); 73 IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11); 74 IO.enumCase(Value, "Auto", FormatStyle::LS_Auto); 75 } 76 }; 77 78 template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> { 79 static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) { 80 IO.enumCase(Value, "Never", FormatStyle::UT_Never); 81 IO.enumCase(Value, "false", FormatStyle::UT_Never); 82 IO.enumCase(Value, "Always", FormatStyle::UT_Always); 83 IO.enumCase(Value, "true", FormatStyle::UT_Always); 84 IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation); 85 IO.enumCase(Value, "ForContinuationAndIndentation", 86 FormatStyle::UT_ForContinuationAndIndentation); 87 } 88 }; 89 90 template <> struct ScalarEnumerationTraits<FormatStyle::JavaScriptQuoteStyle> { 91 static void enumeration(IO &IO, FormatStyle::JavaScriptQuoteStyle &Value) { 92 IO.enumCase(Value, "Leave", FormatStyle::JSQS_Leave); 93 IO.enumCase(Value, "Single", FormatStyle::JSQS_Single); 94 IO.enumCase(Value, "Double", FormatStyle::JSQS_Double); 95 } 96 }; 97 98 template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> { 99 static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) { 100 IO.enumCase(Value, "None", FormatStyle::SFS_None); 101 IO.enumCase(Value, "false", FormatStyle::SFS_None); 102 IO.enumCase(Value, "All", FormatStyle::SFS_All); 103 IO.enumCase(Value, "true", FormatStyle::SFS_All); 104 IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline); 105 IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly); 106 IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty); 107 } 108 }; 109 110 template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> { 111 static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) { 112 IO.enumCase(Value, "Never", FormatStyle::SIS_Never); 113 IO.enumCase(Value, "Always", FormatStyle::SIS_Always); 114 IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse); 115 116 // For backward compatibility. 117 IO.enumCase(Value, "false", FormatStyle::SIS_Never); 118 IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse); 119 } 120 }; 121 122 template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> { 123 static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value) { 124 IO.enumCase(Value, "None", FormatStyle::SLS_None); 125 IO.enumCase(Value, "false", FormatStyle::SLS_None); 126 IO.enumCase(Value, "Empty", FormatStyle::SLS_Empty); 127 IO.enumCase(Value, "Inline", FormatStyle::SLS_Inline); 128 IO.enumCase(Value, "All", FormatStyle::SLS_All); 129 IO.enumCase(Value, "true", FormatStyle::SLS_All); 130 } 131 }; 132 133 template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> { 134 static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value) { 135 IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto); 136 IO.enumCase(Value, "Always", FormatStyle::BPS_Always); 137 IO.enumCase(Value, "Never", FormatStyle::BPS_Never); 138 } 139 }; 140 141 template <> struct ScalarEnumerationTraits<FormatStyle::BinaryOperatorStyle> { 142 static void enumeration(IO &IO, FormatStyle::BinaryOperatorStyle &Value) { 143 IO.enumCase(Value, "All", FormatStyle::BOS_All); 144 IO.enumCase(Value, "true", FormatStyle::BOS_All); 145 IO.enumCase(Value, "None", FormatStyle::BOS_None); 146 IO.enumCase(Value, "false", FormatStyle::BOS_None); 147 IO.enumCase(Value, "NonAssignment", FormatStyle::BOS_NonAssignment); 148 } 149 }; 150 151 template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> { 152 static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) { 153 IO.enumCase(Value, "Attach", FormatStyle::BS_Attach); 154 IO.enumCase(Value, "Linux", FormatStyle::BS_Linux); 155 IO.enumCase(Value, "Mozilla", FormatStyle::BS_Mozilla); 156 IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup); 157 IO.enumCase(Value, "Allman", FormatStyle::BS_Allman); 158 IO.enumCase(Value, "GNU", FormatStyle::BS_GNU); 159 IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit); 160 IO.enumCase(Value, "Custom", FormatStyle::BS_Custom); 161 } 162 }; 163 164 template <> 165 struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> { 166 static void 167 enumeration(IO &IO, FormatStyle::BreakConstructorInitializersStyle &Value) { 168 IO.enumCase(Value, "BeforeColon", FormatStyle::BCIS_BeforeColon); 169 IO.enumCase(Value, "BeforeComma", FormatStyle::BCIS_BeforeComma); 170 IO.enumCase(Value, "AfterColon", FormatStyle::BCIS_AfterColon); 171 } 172 }; 173 174 template <> 175 struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> { 176 static void enumeration(IO &IO, 177 FormatStyle::BreakInheritanceListStyle &Value) { 178 IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon); 179 IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma); 180 IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon); 181 } 182 }; 183 184 template <> 185 struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> { 186 static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) { 187 IO.enumCase(Value, "None", FormatStyle::PPDIS_None); 188 IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash); 189 IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash); 190 } 191 }; 192 193 template <> 194 struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> { 195 static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) { 196 IO.enumCase(Value, "None", FormatStyle::RTBS_None); 197 IO.enumCase(Value, "All", FormatStyle::RTBS_All); 198 IO.enumCase(Value, "TopLevel", FormatStyle::RTBS_TopLevel); 199 IO.enumCase(Value, "TopLevelDefinitions", 200 FormatStyle::RTBS_TopLevelDefinitions); 201 IO.enumCase(Value, "AllDefinitions", FormatStyle::RTBS_AllDefinitions); 202 } 203 }; 204 205 template <> 206 struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> { 207 static void enumeration(IO &IO, 208 FormatStyle::BreakTemplateDeclarationsStyle &Value) { 209 IO.enumCase(Value, "No", FormatStyle::BTDS_No); 210 IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine); 211 IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes); 212 213 // For backward compatibility. 214 IO.enumCase(Value, "false", FormatStyle::BTDS_MultiLine); 215 IO.enumCase(Value, "true", FormatStyle::BTDS_Yes); 216 } 217 }; 218 219 template <> 220 struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> { 221 static void 222 enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) { 223 IO.enumCase(Value, "None", FormatStyle::DRTBS_None); 224 IO.enumCase(Value, "All", FormatStyle::DRTBS_All); 225 IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel); 226 227 // For backward compatibility. 228 IO.enumCase(Value, "false", FormatStyle::DRTBS_None); 229 IO.enumCase(Value, "true", FormatStyle::DRTBS_All); 230 } 231 }; 232 233 template <> 234 struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> { 235 static void enumeration(IO &IO, 236 FormatStyle::NamespaceIndentationKind &Value) { 237 IO.enumCase(Value, "None", FormatStyle::NI_None); 238 IO.enumCase(Value, "Inner", FormatStyle::NI_Inner); 239 IO.enumCase(Value, "All", FormatStyle::NI_All); 240 } 241 }; 242 243 template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> { 244 static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) { 245 IO.enumCase(Value, "Align", FormatStyle::BAS_Align); 246 IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign); 247 IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak); 248 249 // For backward compatibility. 250 IO.enumCase(Value, "true", FormatStyle::BAS_Align); 251 IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign); 252 } 253 }; 254 255 template <> 256 struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> { 257 static void enumeration(IO &IO, 258 FormatStyle::EscapedNewlineAlignmentStyle &Value) { 259 IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign); 260 IO.enumCase(Value, "Left", FormatStyle::ENAS_Left); 261 IO.enumCase(Value, "Right", FormatStyle::ENAS_Right); 262 263 // For backward compatibility. 264 IO.enumCase(Value, "true", FormatStyle::ENAS_Left); 265 IO.enumCase(Value, "false", FormatStyle::ENAS_Right); 266 } 267 }; 268 269 template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> { 270 static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) { 271 IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle); 272 IO.enumCase(Value, "Left", FormatStyle::PAS_Left); 273 IO.enumCase(Value, "Right", FormatStyle::PAS_Right); 274 275 // For backward compatibility. 276 IO.enumCase(Value, "true", FormatStyle::PAS_Left); 277 IO.enumCase(Value, "false", FormatStyle::PAS_Right); 278 } 279 }; 280 281 template <> 282 struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> { 283 static void enumeration(IO &IO, 284 FormatStyle::SpaceBeforeParensOptions &Value) { 285 IO.enumCase(Value, "Never", FormatStyle::SBPO_Never); 286 IO.enumCase(Value, "ControlStatements", 287 FormatStyle::SBPO_ControlStatements); 288 IO.enumCase(Value, "NonEmptyParentheses", 289 FormatStyle::SBPO_NonEmptyParentheses); 290 IO.enumCase(Value, "Always", FormatStyle::SBPO_Always); 291 292 // For backward compatibility. 293 IO.enumCase(Value, "false", FormatStyle::SBPO_Never); 294 IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements); 295 } 296 }; 297 298 template <> struct MappingTraits<FormatStyle> { 299 static void mapping(IO &IO, FormatStyle &Style) { 300 // When reading, read the language first, we need it for getPredefinedStyle. 301 IO.mapOptional("Language", Style.Language); 302 303 if (IO.outputting()) { 304 StringRef StylesArray[] = {"LLVM", "Google", "Chromium", "Mozilla", 305 "WebKit", "GNU", "Microsoft"}; 306 ArrayRef<StringRef> Styles(StylesArray); 307 for (size_t i = 0, e = Styles.size(); i < e; ++i) { 308 StringRef StyleName(Styles[i]); 309 FormatStyle PredefinedStyle; 310 if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) && 311 Style == PredefinedStyle) { 312 IO.mapOptional("# BasedOnStyle", StyleName); 313 break; 314 } 315 } 316 } else { 317 StringRef BasedOnStyle; 318 IO.mapOptional("BasedOnStyle", BasedOnStyle); 319 if (!BasedOnStyle.empty()) { 320 FormatStyle::LanguageKind OldLanguage = Style.Language; 321 FormatStyle::LanguageKind Language = 322 ((FormatStyle *)IO.getContext())->Language; 323 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) { 324 IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle)); 325 return; 326 } 327 Style.Language = OldLanguage; 328 } 329 } 330 331 // For backward compatibility. 332 if (!IO.outputting()) { 333 IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines); 334 IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment); 335 IO.mapOptional("IndentFunctionDeclarationAfterType", 336 Style.IndentWrappedFunctionNames); 337 IO.mapOptional("PointerBindsToType", Style.PointerAlignment); 338 IO.mapOptional("SpaceAfterControlStatementKeyword", 339 Style.SpaceBeforeParens); 340 } 341 342 IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); 343 IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket); 344 IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros); 345 IO.mapOptional("AlignConsecutiveAssignments", 346 Style.AlignConsecutiveAssignments); 347 IO.mapOptional("AlignConsecutiveDeclarations", 348 Style.AlignConsecutiveDeclarations); 349 IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines); 350 IO.mapOptional("AlignOperands", Style.AlignOperands); 351 IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); 352 IO.mapOptional("AllowAllArgumentsOnNextLine", 353 Style.AllowAllArgumentsOnNextLine); 354 IO.mapOptional("AllowAllConstructorInitializersOnNextLine", 355 Style.AllowAllConstructorInitializersOnNextLine); 356 IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine", 357 Style.AllowAllParametersOfDeclarationOnNextLine); 358 IO.mapOptional("AllowShortBlocksOnASingleLine", 359 Style.AllowShortBlocksOnASingleLine); 360 IO.mapOptional("AllowShortCaseLabelsOnASingleLine", 361 Style.AllowShortCaseLabelsOnASingleLine); 362 IO.mapOptional("AllowShortFunctionsOnASingleLine", 363 Style.AllowShortFunctionsOnASingleLine); 364 IO.mapOptional("AllowShortLambdasOnASingleLine", 365 Style.AllowShortLambdasOnASingleLine); 366 IO.mapOptional("AllowShortIfStatementsOnASingleLine", 367 Style.AllowShortIfStatementsOnASingleLine); 368 IO.mapOptional("AllowShortLoopsOnASingleLine", 369 Style.AllowShortLoopsOnASingleLine); 370 IO.mapOptional("AlwaysBreakAfterDefinitionReturnType", 371 Style.AlwaysBreakAfterDefinitionReturnType); 372 IO.mapOptional("AlwaysBreakAfterReturnType", 373 Style.AlwaysBreakAfterReturnType); 374 375 // If AlwaysBreakAfterDefinitionReturnType was specified but 376 // AlwaysBreakAfterReturnType was not, initialize the latter from the 377 // former for backwards compatibility. 378 if (Style.AlwaysBreakAfterDefinitionReturnType != FormatStyle::DRTBS_None && 379 Style.AlwaysBreakAfterReturnType == FormatStyle::RTBS_None) { 380 if (Style.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_All) 381 Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions; 382 else if (Style.AlwaysBreakAfterDefinitionReturnType == 383 FormatStyle::DRTBS_TopLevel) 384 Style.AlwaysBreakAfterReturnType = 385 FormatStyle::RTBS_TopLevelDefinitions; 386 } 387 388 IO.mapOptional("AlwaysBreakBeforeMultilineStrings", 389 Style.AlwaysBreakBeforeMultilineStrings); 390 IO.mapOptional("AlwaysBreakTemplateDeclarations", 391 Style.AlwaysBreakTemplateDeclarations); 392 IO.mapOptional("BinPackArguments", Style.BinPackArguments); 393 IO.mapOptional("BinPackParameters", Style.BinPackParameters); 394 IO.mapOptional("BraceWrapping", Style.BraceWrapping); 395 IO.mapOptional("BreakBeforeBinaryOperators", 396 Style.BreakBeforeBinaryOperators); 397 IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); 398 399 bool BreakBeforeInheritanceComma = false; 400 IO.mapOptional("BreakBeforeInheritanceComma", BreakBeforeInheritanceComma); 401 IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList); 402 // If BreakBeforeInheritanceComma was specified but 403 // BreakInheritance was not, initialize the latter from the 404 // former for backwards compatibility. 405 if (BreakBeforeInheritanceComma && 406 Style.BreakInheritanceList == FormatStyle::BILS_BeforeColon) 407 Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma; 408 409 IO.mapOptional("BreakBeforeTernaryOperators", 410 Style.BreakBeforeTernaryOperators); 411 412 bool BreakConstructorInitializersBeforeComma = false; 413 IO.mapOptional("BreakConstructorInitializersBeforeComma", 414 BreakConstructorInitializersBeforeComma); 415 IO.mapOptional("BreakConstructorInitializers", 416 Style.BreakConstructorInitializers); 417 // If BreakConstructorInitializersBeforeComma was specified but 418 // BreakConstructorInitializers was not, initialize the latter from the 419 // former for backwards compatibility. 420 if (BreakConstructorInitializersBeforeComma && 421 Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeColon) 422 Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 423 424 IO.mapOptional("BreakAfterJavaFieldAnnotations", 425 Style.BreakAfterJavaFieldAnnotations); 426 IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals); 427 IO.mapOptional("ColumnLimit", Style.ColumnLimit); 428 IO.mapOptional("CommentPragmas", Style.CommentPragmas); 429 IO.mapOptional("CompactNamespaces", Style.CompactNamespaces); 430 IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine", 431 Style.ConstructorInitializerAllOnOneLineOrOnePerLine); 432 IO.mapOptional("ConstructorInitializerIndentWidth", 433 Style.ConstructorInitializerIndentWidth); 434 IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth); 435 IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle); 436 IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment); 437 IO.mapOptional("DisableFormat", Style.DisableFormat); 438 IO.mapOptional("ExperimentalAutoDetectBinPacking", 439 Style.ExperimentalAutoDetectBinPacking); 440 IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments); 441 IO.mapOptional("ForEachMacros", Style.ForEachMacros); 442 IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks); 443 IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories); 444 IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex); 445 IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels); 446 IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives); 447 IO.mapOptional("IndentWidth", Style.IndentWidth); 448 IO.mapOptional("IndentWrappedFunctionNames", 449 Style.IndentWrappedFunctionNames); 450 IO.mapOptional("JavaImportGroups", Style.JavaImportGroups); 451 IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes); 452 IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports); 453 IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks", 454 Style.KeepEmptyLinesAtTheStartOfBlocks); 455 IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin); 456 IO.mapOptional("MacroBlockEnd", Style.MacroBlockEnd); 457 IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); 458 IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); 459 IO.mapOptional("NamespaceMacros", Style.NamespaceMacros); 460 IO.mapOptional("ObjCBinPackProtocolList", Style.ObjCBinPackProtocolList); 461 IO.mapOptional("ObjCBlockIndentWidth", Style.ObjCBlockIndentWidth); 462 IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); 463 IO.mapOptional("ObjCSpaceBeforeProtocolList", 464 Style.ObjCSpaceBeforeProtocolList); 465 IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment); 466 IO.mapOptional("PenaltyBreakBeforeFirstCallParameter", 467 Style.PenaltyBreakBeforeFirstCallParameter); 468 IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment); 469 IO.mapOptional("PenaltyBreakFirstLessLess", 470 Style.PenaltyBreakFirstLessLess); 471 IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString); 472 IO.mapOptional("PenaltyBreakTemplateDeclaration", 473 Style.PenaltyBreakTemplateDeclaration); 474 IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter); 475 IO.mapOptional("PenaltyReturnTypeOnItsOwnLine", 476 Style.PenaltyReturnTypeOnItsOwnLine); 477 IO.mapOptional("PointerAlignment", Style.PointerAlignment); 478 IO.mapOptional("RawStringFormats", Style.RawStringFormats); 479 IO.mapOptional("ReflowComments", Style.ReflowComments); 480 IO.mapOptional("SortIncludes", Style.SortIncludes); 481 IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations); 482 IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast); 483 IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot); 484 IO.mapOptional("SpaceAfterTemplateKeyword", 485 Style.SpaceAfterTemplateKeyword); 486 IO.mapOptional("SpaceBeforeAssignmentOperators", 487 Style.SpaceBeforeAssignmentOperators); 488 IO.mapOptional("SpaceBeforeCpp11BracedList", 489 Style.SpaceBeforeCpp11BracedList); 490 IO.mapOptional("SpaceBeforeCtorInitializerColon", 491 Style.SpaceBeforeCtorInitializerColon); 492 IO.mapOptional("SpaceBeforeInheritanceColon", 493 Style.SpaceBeforeInheritanceColon); 494 IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens); 495 IO.mapOptional("SpaceBeforeRangeBasedForLoopColon", 496 Style.SpaceBeforeRangeBasedForLoopColon); 497 IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses); 498 IO.mapOptional("SpacesBeforeTrailingComments", 499 Style.SpacesBeforeTrailingComments); 500 IO.mapOptional("SpacesInAngles", Style.SpacesInAngles); 501 IO.mapOptional("SpacesInContainerLiterals", 502 Style.SpacesInContainerLiterals); 503 IO.mapOptional("SpacesInCStyleCastParentheses", 504 Style.SpacesInCStyleCastParentheses); 505 IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses); 506 IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets); 507 IO.mapOptional("Standard", Style.Standard); 508 IO.mapOptional("StatementMacros", Style.StatementMacros); 509 IO.mapOptional("TabWidth", Style.TabWidth); 510 IO.mapOptional("TypenameMacros", Style.TypenameMacros); 511 IO.mapOptional("UseTab", Style.UseTab); 512 } 513 }; 514 515 template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> { 516 static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) { 517 IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel); 518 IO.mapOptional("AfterClass", Wrapping.AfterClass); 519 IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement); 520 IO.mapOptional("AfterEnum", Wrapping.AfterEnum); 521 IO.mapOptional("AfterFunction", Wrapping.AfterFunction); 522 IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace); 523 IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration); 524 IO.mapOptional("AfterStruct", Wrapping.AfterStruct); 525 IO.mapOptional("AfterUnion", Wrapping.AfterUnion); 526 IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock); 527 IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch); 528 IO.mapOptional("BeforeElse", Wrapping.BeforeElse); 529 IO.mapOptional("IndentBraces", Wrapping.IndentBraces); 530 IO.mapOptional("SplitEmptyFunction", Wrapping.SplitEmptyFunction); 531 IO.mapOptional("SplitEmptyRecord", Wrapping.SplitEmptyRecord); 532 IO.mapOptional("SplitEmptyNamespace", Wrapping.SplitEmptyNamespace); 533 } 534 }; 535 536 template <> struct MappingTraits<FormatStyle::RawStringFormat> { 537 static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) { 538 IO.mapOptional("Language", Format.Language); 539 IO.mapOptional("Delimiters", Format.Delimiters); 540 IO.mapOptional("EnclosingFunctions", Format.EnclosingFunctions); 541 IO.mapOptional("CanonicalDelimiter", Format.CanonicalDelimiter); 542 IO.mapOptional("BasedOnStyle", Format.BasedOnStyle); 543 } 544 }; 545 546 // Allows to read vector<FormatStyle> while keeping default values. 547 // IO.getContext() should contain a pointer to the FormatStyle structure, that 548 // will be used to get default values for missing keys. 549 // If the first element has no Language specified, it will be treated as the 550 // default one for the following elements. 551 template <> struct DocumentListTraits<std::vector<FormatStyle>> { 552 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) { 553 return Seq.size(); 554 } 555 static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq, 556 size_t Index) { 557 if (Index >= Seq.size()) { 558 assert(Index == Seq.size()); 559 FormatStyle Template; 560 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) { 561 Template = Seq[0]; 562 } else { 563 Template = *((const FormatStyle *)IO.getContext()); 564 Template.Language = FormatStyle::LK_None; 565 } 566 Seq.resize(Index + 1, Template); 567 } 568 return Seq[Index]; 569 } 570 }; 571 } // namespace yaml 572 } // namespace llvm 573 574 namespace clang { 575 namespace format { 576 577 const std::error_category &getParseCategory() { 578 static const ParseErrorCategory C{}; 579 return C; 580 } 581 std::error_code make_error_code(ParseError e) { 582 return std::error_code(static_cast<int>(e), getParseCategory()); 583 } 584 585 inline llvm::Error make_string_error(const llvm::Twine &Message) { 586 return llvm::make_error<llvm::StringError>(Message, 587 llvm::inconvertibleErrorCode()); 588 } 589 590 const char *ParseErrorCategory::name() const noexcept { 591 return "clang-format.parse_error"; 592 } 593 594 std::string ParseErrorCategory::message(int EV) const { 595 switch (static_cast<ParseError>(EV)) { 596 case ParseError::Success: 597 return "Success"; 598 case ParseError::Error: 599 return "Invalid argument"; 600 case ParseError::Unsuitable: 601 return "Unsuitable"; 602 } 603 llvm_unreachable("unexpected parse error"); 604 } 605 606 static FormatStyle expandPresets(const FormatStyle &Style) { 607 if (Style.BreakBeforeBraces == FormatStyle::BS_Custom) 608 return Style; 609 FormatStyle Expanded = Style; 610 Expanded.BraceWrapping = {false, false, false, false, false, false, 611 false, false, false, false, false, false, 612 false, true, true, true}; 613 switch (Style.BreakBeforeBraces) { 614 case FormatStyle::BS_Linux: 615 Expanded.BraceWrapping.AfterClass = true; 616 Expanded.BraceWrapping.AfterFunction = true; 617 Expanded.BraceWrapping.AfterNamespace = true; 618 break; 619 case FormatStyle::BS_Mozilla: 620 Expanded.BraceWrapping.AfterClass = true; 621 Expanded.BraceWrapping.AfterEnum = true; 622 Expanded.BraceWrapping.AfterFunction = true; 623 Expanded.BraceWrapping.AfterStruct = true; 624 Expanded.BraceWrapping.AfterUnion = true; 625 Expanded.BraceWrapping.AfterExternBlock = true; 626 Expanded.BraceWrapping.SplitEmptyFunction = true; 627 Expanded.BraceWrapping.SplitEmptyRecord = false; 628 break; 629 case FormatStyle::BS_Stroustrup: 630 Expanded.BraceWrapping.AfterFunction = true; 631 Expanded.BraceWrapping.BeforeCatch = true; 632 Expanded.BraceWrapping.BeforeElse = true; 633 break; 634 case FormatStyle::BS_Allman: 635 Expanded.BraceWrapping.AfterCaseLabel = true; 636 Expanded.BraceWrapping.AfterClass = true; 637 Expanded.BraceWrapping.AfterControlStatement = true; 638 Expanded.BraceWrapping.AfterEnum = true; 639 Expanded.BraceWrapping.AfterFunction = true; 640 Expanded.BraceWrapping.AfterNamespace = true; 641 Expanded.BraceWrapping.AfterObjCDeclaration = true; 642 Expanded.BraceWrapping.AfterStruct = true; 643 Expanded.BraceWrapping.AfterExternBlock = true; 644 Expanded.BraceWrapping.BeforeCatch = true; 645 Expanded.BraceWrapping.BeforeElse = true; 646 break; 647 case FormatStyle::BS_GNU: 648 Expanded.BraceWrapping = {true, true, true, true, true, true, true, true, 649 true, true, true, true, true, true, true, true}; 650 break; 651 case FormatStyle::BS_WebKit: 652 Expanded.BraceWrapping.AfterFunction = true; 653 break; 654 default: 655 break; 656 } 657 return Expanded; 658 } 659 660 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { 661 FormatStyle LLVMStyle; 662 LLVMStyle.Language = Language; 663 LLVMStyle.AccessModifierOffset = -2; 664 LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right; 665 LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align; 666 LLVMStyle.AlignOperands = true; 667 LLVMStyle.AlignTrailingComments = true; 668 LLVMStyle.AlignConsecutiveAssignments = false; 669 LLVMStyle.AlignConsecutiveDeclarations = false; 670 LLVMStyle.AlignConsecutiveMacros = false; 671 LLVMStyle.AllowAllArgumentsOnNextLine = true; 672 LLVMStyle.AllowAllConstructorInitializersOnNextLine = true; 673 LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; 674 LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; 675 LLVMStyle.AllowShortBlocksOnASingleLine = false; 676 LLVMStyle.AllowShortCaseLabelsOnASingleLine = false; 677 LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 678 LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All; 679 LLVMStyle.AllowShortLoopsOnASingleLine = false; 680 LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None; 681 LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None; 682 LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; 683 LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine; 684 LLVMStyle.BinPackArguments = true; 685 LLVMStyle.BinPackParameters = true; 686 LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; 687 LLVMStyle.BreakBeforeTernaryOperators = true; 688 LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; 689 LLVMStyle.BraceWrapping = {false, false, false, false, false, false, 690 false, false, false, false, false, false, 691 false, true, true, true}; 692 LLVMStyle.BreakAfterJavaFieldAnnotations = false; 693 LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; 694 LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; 695 LLVMStyle.BreakStringLiterals = true; 696 LLVMStyle.ColumnLimit = 80; 697 LLVMStyle.CommentPragmas = "^ IWYU pragma:"; 698 LLVMStyle.CompactNamespaces = false; 699 LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false; 700 LLVMStyle.ConstructorInitializerIndentWidth = 4; 701 LLVMStyle.ContinuationIndentWidth = 4; 702 LLVMStyle.Cpp11BracedListStyle = true; 703 LLVMStyle.DerivePointerAlignment = false; 704 LLVMStyle.ExperimentalAutoDetectBinPacking = false; 705 LLVMStyle.FixNamespaceComments = true; 706 LLVMStyle.ForEachMacros.push_back("foreach"); 707 LLVMStyle.ForEachMacros.push_back("Q_FOREACH"); 708 LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH"); 709 LLVMStyle.IncludeStyle.IncludeCategories = { 710 {"^\"(llvm|llvm-c|clang|clang-c)/", 2}, 711 {"^(<|\"(gtest|gmock|isl|json)/)", 3}, 712 {".*", 1}}; 713 LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$"; 714 LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve; 715 LLVMStyle.IndentCaseLabels = false; 716 LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None; 717 LLVMStyle.IndentWrappedFunctionNames = false; 718 LLVMStyle.IndentWidth = 2; 719 LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave; 720 LLVMStyle.JavaScriptWrapImports = true; 721 LLVMStyle.TabWidth = 8; 722 LLVMStyle.MaxEmptyLinesToKeep = 1; 723 LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true; 724 LLVMStyle.NamespaceIndentation = FormatStyle::NI_None; 725 LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto; 726 LLVMStyle.ObjCBlockIndentWidth = 2; 727 LLVMStyle.ObjCSpaceAfterProperty = false; 728 LLVMStyle.ObjCSpaceBeforeProtocolList = true; 729 LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; 730 LLVMStyle.SpacesBeforeTrailingComments = 1; 731 LLVMStyle.Standard = FormatStyle::LS_Cpp11; 732 LLVMStyle.UseTab = FormatStyle::UT_Never; 733 LLVMStyle.ReflowComments = true; 734 LLVMStyle.SpacesInParentheses = false; 735 LLVMStyle.SpacesInSquareBrackets = false; 736 LLVMStyle.SpaceInEmptyParentheses = false; 737 LLVMStyle.SpacesInContainerLiterals = true; 738 LLVMStyle.SpacesInCStyleCastParentheses = false; 739 LLVMStyle.SpaceAfterCStyleCast = false; 740 LLVMStyle.SpaceAfterLogicalNot = false; 741 LLVMStyle.SpaceAfterTemplateKeyword = true; 742 LLVMStyle.SpaceBeforeCtorInitializerColon = true; 743 LLVMStyle.SpaceBeforeInheritanceColon = true; 744 LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements; 745 LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true; 746 LLVMStyle.SpaceBeforeAssignmentOperators = true; 747 LLVMStyle.SpaceBeforeCpp11BracedList = false; 748 LLVMStyle.SpacesInAngles = false; 749 750 LLVMStyle.PenaltyBreakAssignment = prec::Assignment; 751 LLVMStyle.PenaltyBreakComment = 300; 752 LLVMStyle.PenaltyBreakFirstLessLess = 120; 753 LLVMStyle.PenaltyBreakString = 1000; 754 LLVMStyle.PenaltyExcessCharacter = 1000000; 755 LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60; 756 LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19; 757 LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational; 758 759 LLVMStyle.DisableFormat = false; 760 LLVMStyle.SortIncludes = true; 761 LLVMStyle.SortUsingDeclarations = true; 762 LLVMStyle.StatementMacros.push_back("Q_UNUSED"); 763 LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION"); 764 765 // Defaults that differ when not C++. 766 if (Language == FormatStyle::LK_TableGen) { 767 LLVMStyle.SpacesInContainerLiterals = false; 768 } 769 770 return LLVMStyle; 771 } 772 773 FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { 774 if (Language == FormatStyle::LK_TextProto) { 775 FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto); 776 GoogleStyle.Language = FormatStyle::LK_TextProto; 777 778 return GoogleStyle; 779 } 780 781 FormatStyle GoogleStyle = getLLVMStyle(Language); 782 783 GoogleStyle.AccessModifierOffset = -1; 784 GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left; 785 GoogleStyle.AllowShortIfStatementsOnASingleLine = 786 FormatStyle::SIS_WithoutElse; 787 GoogleStyle.AllowShortLoopsOnASingleLine = true; 788 GoogleStyle.AlwaysBreakBeforeMultilineStrings = true; 789 GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; 790 GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; 791 GoogleStyle.DerivePointerAlignment = true; 792 GoogleStyle.IncludeStyle.IncludeCategories = { 793 {"^<ext/.*\\.h>", 2}, {"^<.*\\.h>", 1}, {"^<.*", 2}, {".*", 3}}; 794 GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$"; 795 GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 796 GoogleStyle.IndentCaseLabels = true; 797 GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false; 798 GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never; 799 GoogleStyle.ObjCSpaceAfterProperty = false; 800 GoogleStyle.ObjCSpaceBeforeProtocolList = true; 801 GoogleStyle.PointerAlignment = FormatStyle::PAS_Left; 802 GoogleStyle.RawStringFormats = { 803 { 804 FormatStyle::LK_Cpp, 805 /*Delimiters=*/ 806 { 807 "cc", 808 "CC", 809 "cpp", 810 "Cpp", 811 "CPP", 812 "c++", 813 "C++", 814 }, 815 /*EnclosingFunctionNames=*/ 816 {}, 817 /*CanonicalDelimiter=*/"", 818 /*BasedOnStyle=*/"google", 819 }, 820 { 821 FormatStyle::LK_TextProto, 822 /*Delimiters=*/ 823 { 824 "pb", 825 "PB", 826 "proto", 827 "PROTO", 828 }, 829 /*EnclosingFunctionNames=*/ 830 { 831 "EqualsProto", 832 "EquivToProto", 833 "PARSE_PARTIAL_TEXT_PROTO", 834 "PARSE_TEST_PROTO", 835 "PARSE_TEXT_PROTO", 836 "ParseTextOrDie", 837 "ParseTextProtoOrDie", 838 }, 839 /*CanonicalDelimiter=*/"", 840 /*BasedOnStyle=*/"google", 841 }, 842 }; 843 GoogleStyle.SpacesBeforeTrailingComments = 2; 844 GoogleStyle.Standard = FormatStyle::LS_Auto; 845 846 GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200; 847 GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1; 848 849 if (Language == FormatStyle::LK_Java) { 850 GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; 851 GoogleStyle.AlignOperands = false; 852 GoogleStyle.AlignTrailingComments = false; 853 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 854 GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 855 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 856 GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; 857 GoogleStyle.ColumnLimit = 100; 858 GoogleStyle.SpaceAfterCStyleCast = true; 859 GoogleStyle.SpacesBeforeTrailingComments = 1; 860 } else if (Language == FormatStyle::LK_JavaScript) { 861 GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; 862 GoogleStyle.AlignOperands = false; 863 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 864 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 865 GoogleStyle.BreakBeforeTernaryOperators = false; 866 // taze:, triple slash directives (`/// <...`), @see, which is commonly 867 // followed by overlong URLs. 868 GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|@see)"; 869 GoogleStyle.MaxEmptyLinesToKeep = 3; 870 GoogleStyle.NamespaceIndentation = FormatStyle::NI_All; 871 GoogleStyle.SpacesInContainerLiterals = false; 872 GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single; 873 GoogleStyle.JavaScriptWrapImports = false; 874 } else if (Language == FormatStyle::LK_Proto) { 875 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 876 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 877 GoogleStyle.SpacesInContainerLiterals = false; 878 GoogleStyle.Cpp11BracedListStyle = false; 879 // This affects protocol buffer options specifications and text protos. 880 // Text protos are currently mostly formatted inside C++ raw string literals 881 // and often the current breaking behavior of string literals is not 882 // beneficial there. Investigate turning this on once proper string reflow 883 // has been implemented. 884 GoogleStyle.BreakStringLiterals = false; 885 } else if (Language == FormatStyle::LK_ObjC) { 886 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 887 GoogleStyle.ColumnLimit = 100; 888 // "Regroup" doesn't work well for ObjC yet (main header heuristic, 889 // relationship between ObjC standard library headers and other heades, 890 // #imports, etc.) 891 GoogleStyle.IncludeStyle.IncludeBlocks = 892 tooling::IncludeStyle::IBS_Preserve; 893 } 894 895 return GoogleStyle; 896 } 897 898 FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) { 899 FormatStyle ChromiumStyle = getGoogleStyle(Language); 900 if (Language == FormatStyle::LK_Java) { 901 ChromiumStyle.AllowShortIfStatementsOnASingleLine = 902 FormatStyle::SIS_WithoutElse; 903 ChromiumStyle.BreakAfterJavaFieldAnnotations = true; 904 ChromiumStyle.ContinuationIndentWidth = 8; 905 ChromiumStyle.IndentWidth = 4; 906 // See styleguide for import groups: 907 // https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/java.md#Import-Order 908 ChromiumStyle.JavaImportGroups = { 909 "android", 910 "androidx", 911 "com", 912 "dalvik", 913 "junit", 914 "org", 915 "com.google.android.apps.chrome", 916 "org.chromium", 917 "java", 918 "javax", 919 }; 920 ChromiumStyle.SortIncludes = true; 921 } else if (Language == FormatStyle::LK_JavaScript) { 922 ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 923 ChromiumStyle.AllowShortLoopsOnASingleLine = false; 924 } else { 925 ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false; 926 ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 927 ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 928 ChromiumStyle.AllowShortLoopsOnASingleLine = false; 929 ChromiumStyle.BinPackParameters = false; 930 ChromiumStyle.DerivePointerAlignment = false; 931 if (Language == FormatStyle::LK_ObjC) 932 ChromiumStyle.ColumnLimit = 80; 933 } 934 return ChromiumStyle; 935 } 936 937 FormatStyle getMozillaStyle() { 938 FormatStyle MozillaStyle = getLLVMStyle(); 939 MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false; 940 MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 941 MozillaStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel; 942 MozillaStyle.AlwaysBreakAfterDefinitionReturnType = 943 FormatStyle::DRTBS_TopLevel; 944 MozillaStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; 945 MozillaStyle.BinPackParameters = false; 946 MozillaStyle.BinPackArguments = false; 947 MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla; 948 MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 949 MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma; 950 MozillaStyle.ConstructorInitializerIndentWidth = 2; 951 MozillaStyle.ContinuationIndentWidth = 2; 952 MozillaStyle.Cpp11BracedListStyle = false; 953 MozillaStyle.FixNamespaceComments = false; 954 MozillaStyle.IndentCaseLabels = true; 955 MozillaStyle.ObjCSpaceAfterProperty = true; 956 MozillaStyle.ObjCSpaceBeforeProtocolList = false; 957 MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200; 958 MozillaStyle.PointerAlignment = FormatStyle::PAS_Left; 959 MozillaStyle.SpaceAfterTemplateKeyword = false; 960 return MozillaStyle; 961 } 962 963 FormatStyle getWebKitStyle() { 964 FormatStyle Style = getLLVMStyle(); 965 Style.AccessModifierOffset = -4; 966 Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; 967 Style.AlignOperands = false; 968 Style.AlignTrailingComments = false; 969 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; 970 Style.BreakBeforeBraces = FormatStyle::BS_WebKit; 971 Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 972 Style.Cpp11BracedListStyle = false; 973 Style.ColumnLimit = 0; 974 Style.FixNamespaceComments = false; 975 Style.IndentWidth = 4; 976 Style.NamespaceIndentation = FormatStyle::NI_Inner; 977 Style.ObjCBlockIndentWidth = 4; 978 Style.ObjCSpaceAfterProperty = true; 979 Style.PointerAlignment = FormatStyle::PAS_Left; 980 Style.SpaceBeforeCpp11BracedList = true; 981 return Style; 982 } 983 984 FormatStyle getGNUStyle() { 985 FormatStyle Style = getLLVMStyle(); 986 Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; 987 Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions; 988 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; 989 Style.BreakBeforeBraces = FormatStyle::BS_GNU; 990 Style.BreakBeforeTernaryOperators = true; 991 Style.Cpp11BracedListStyle = false; 992 Style.ColumnLimit = 79; 993 Style.FixNamespaceComments = false; 994 Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 995 Style.Standard = FormatStyle::LS_Cpp03; 996 return Style; 997 } 998 999 FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) { 1000 FormatStyle Style = getLLVMStyle(); 1001 Style.ColumnLimit = 120; 1002 Style.TabWidth = 4; 1003 Style.IndentWidth = 4; 1004 Style.UseTab = FormatStyle::UT_Never; 1005 Style.BreakBeforeBraces = FormatStyle::BS_Custom; 1006 Style.BraceWrapping.AfterClass = true; 1007 Style.BraceWrapping.AfterControlStatement = true; 1008 Style.BraceWrapping.AfterEnum = true; 1009 Style.BraceWrapping.AfterFunction = true; 1010 Style.BraceWrapping.AfterNamespace = true; 1011 Style.BraceWrapping.AfterObjCDeclaration = true; 1012 Style.BraceWrapping.AfterStruct = true; 1013 Style.BraceWrapping.AfterExternBlock = true; 1014 Style.BraceWrapping.BeforeCatch = true; 1015 Style.BraceWrapping.BeforeElse = true; 1016 Style.PenaltyReturnTypeOnItsOwnLine = 1000; 1017 Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; 1018 Style.AllowShortBlocksOnASingleLine = false; 1019 Style.AllowShortCaseLabelsOnASingleLine = false; 1020 Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 1021 Style.AllowShortLoopsOnASingleLine = false; 1022 return Style; 1023 } 1024 1025 FormatStyle getNoStyle() { 1026 FormatStyle NoStyle = getLLVMStyle(); 1027 NoStyle.DisableFormat = true; 1028 NoStyle.SortIncludes = false; 1029 NoStyle.SortUsingDeclarations = false; 1030 return NoStyle; 1031 } 1032 1033 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, 1034 FormatStyle *Style) { 1035 if (Name.equals_lower("llvm")) { 1036 *Style = getLLVMStyle(Language); 1037 } else if (Name.equals_lower("chromium")) { 1038 *Style = getChromiumStyle(Language); 1039 } else if (Name.equals_lower("mozilla")) { 1040 *Style = getMozillaStyle(); 1041 } else if (Name.equals_lower("google")) { 1042 *Style = getGoogleStyle(Language); 1043 } else if (Name.equals_lower("webkit")) { 1044 *Style = getWebKitStyle(); 1045 } else if (Name.equals_lower("gnu")) { 1046 *Style = getGNUStyle(); 1047 } else if (Name.equals_lower("microsoft")) { 1048 *Style = getMicrosoftStyle(Language); 1049 } else if (Name.equals_lower("none")) { 1050 *Style = getNoStyle(); 1051 } else { 1052 return false; 1053 } 1054 1055 Style->Language = Language; 1056 return true; 1057 } 1058 1059 std::error_code parseConfiguration(StringRef Text, FormatStyle *Style) { 1060 assert(Style); 1061 FormatStyle::LanguageKind Language = Style->Language; 1062 assert(Language != FormatStyle::LK_None); 1063 if (Text.trim().empty()) 1064 return make_error_code(ParseError::Error); 1065 Style->StyleSet.Clear(); 1066 std::vector<FormatStyle> Styles; 1067 llvm::yaml::Input Input(Text); 1068 // DocumentListTraits<vector<FormatStyle>> uses the context to get default 1069 // values for the fields, keys for which are missing from the configuration. 1070 // Mapping also uses the context to get the language to find the correct 1071 // base style. 1072 Input.setContext(Style); 1073 Input >> Styles; 1074 if (Input.error()) 1075 return Input.error(); 1076 1077 for (unsigned i = 0; i < Styles.size(); ++i) { 1078 // Ensures that only the first configuration can skip the Language option. 1079 if (Styles[i].Language == FormatStyle::LK_None && i != 0) 1080 return make_error_code(ParseError::Error); 1081 // Ensure that each language is configured at most once. 1082 for (unsigned j = 0; j < i; ++j) { 1083 if (Styles[i].Language == Styles[j].Language) { 1084 LLVM_DEBUG(llvm::dbgs() 1085 << "Duplicate languages in the config file on positions " 1086 << j << " and " << i << "\n"); 1087 return make_error_code(ParseError::Error); 1088 } 1089 } 1090 } 1091 // Look for a suitable configuration starting from the end, so we can 1092 // find the configuration for the specific language first, and the default 1093 // configuration (which can only be at slot 0) after it. 1094 FormatStyle::FormatStyleSet StyleSet; 1095 bool LanguageFound = false; 1096 for (int i = Styles.size() - 1; i >= 0; --i) { 1097 if (Styles[i].Language != FormatStyle::LK_None) 1098 StyleSet.Add(Styles[i]); 1099 if (Styles[i].Language == Language) 1100 LanguageFound = true; 1101 } 1102 if (!LanguageFound) { 1103 if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None) 1104 return make_error_code(ParseError::Unsuitable); 1105 FormatStyle DefaultStyle = Styles[0]; 1106 DefaultStyle.Language = Language; 1107 StyleSet.Add(std::move(DefaultStyle)); 1108 } 1109 *Style = *StyleSet.Get(Language); 1110 return make_error_code(ParseError::Success); 1111 } 1112 1113 std::string configurationAsText(const FormatStyle &Style) { 1114 std::string Text; 1115 llvm::raw_string_ostream Stream(Text); 1116 llvm::yaml::Output Output(Stream); 1117 // We use the same mapping method for input and output, so we need a non-const 1118 // reference here. 1119 FormatStyle NonConstStyle = expandPresets(Style); 1120 Output << NonConstStyle; 1121 return Stream.str(); 1122 } 1123 1124 llvm::Optional<FormatStyle> 1125 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const { 1126 if (!Styles) 1127 return None; 1128 auto It = Styles->find(Language); 1129 if (It == Styles->end()) 1130 return None; 1131 FormatStyle Style = It->second; 1132 Style.StyleSet = *this; 1133 return Style; 1134 } 1135 1136 void FormatStyle::FormatStyleSet::Add(FormatStyle Style) { 1137 assert(Style.Language != LK_None && 1138 "Cannot add a style for LK_None to a StyleSet"); 1139 assert( 1140 !Style.StyleSet.Styles && 1141 "Cannot add a style associated with an existing StyleSet to a StyleSet"); 1142 if (!Styles) 1143 Styles = std::make_shared<MapType>(); 1144 (*Styles)[Style.Language] = std::move(Style); 1145 } 1146 1147 void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); } 1148 1149 llvm::Optional<FormatStyle> 1150 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const { 1151 return StyleSet.Get(Language); 1152 } 1153 1154 namespace { 1155 1156 class JavaScriptRequoter : public TokenAnalyzer { 1157 public: 1158 JavaScriptRequoter(const Environment &Env, const FormatStyle &Style) 1159 : TokenAnalyzer(Env, Style) {} 1160 1161 std::pair<tooling::Replacements, unsigned> 1162 analyze(TokenAnnotator &Annotator, 1163 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1164 FormatTokenLexer &Tokens) override { 1165 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 1166 tooling::Replacements Result; 1167 requoteJSStringLiteral(AnnotatedLines, Result); 1168 return {Result, 0}; 1169 } 1170 1171 private: 1172 // Replaces double/single-quoted string literal as appropriate, re-escaping 1173 // the contents in the process. 1174 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines, 1175 tooling::Replacements &Result) { 1176 for (AnnotatedLine *Line : Lines) { 1177 requoteJSStringLiteral(Line->Children, Result); 1178 if (!Line->Affected) 1179 continue; 1180 for (FormatToken *FormatTok = Line->First; FormatTok; 1181 FormatTok = FormatTok->Next) { 1182 StringRef Input = FormatTok->TokenText; 1183 if (FormatTok->Finalized || !FormatTok->isStringLiteral() || 1184 // NB: testing for not starting with a double quote to avoid 1185 // breaking `template strings`. 1186 (Style.JavaScriptQuotes == FormatStyle::JSQS_Single && 1187 !Input.startswith("\"")) || 1188 (Style.JavaScriptQuotes == FormatStyle::JSQS_Double && 1189 !Input.startswith("\'"))) 1190 continue; 1191 1192 // Change start and end quote. 1193 bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single; 1194 SourceLocation Start = FormatTok->Tok.getLocation(); 1195 auto Replace = [&](SourceLocation Start, unsigned Length, 1196 StringRef ReplacementText) { 1197 auto Err = Result.add(tooling::Replacement( 1198 Env.getSourceManager(), Start, Length, ReplacementText)); 1199 // FIXME: handle error. For now, print error message and skip the 1200 // replacement for release version. 1201 if (Err) { 1202 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1203 assert(false); 1204 } 1205 }; 1206 Replace(Start, 1, IsSingle ? "'" : "\""); 1207 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1, 1208 IsSingle ? "'" : "\""); 1209 1210 // Escape internal quotes. 1211 bool Escaped = false; 1212 for (size_t i = 1; i < Input.size() - 1; i++) { 1213 switch (Input[i]) { 1214 case '\\': 1215 if (!Escaped && i + 1 < Input.size() && 1216 ((IsSingle && Input[i + 1] == '"') || 1217 (!IsSingle && Input[i + 1] == '\''))) { 1218 // Remove this \, it's escaping a " or ' that no longer needs 1219 // escaping 1220 Replace(Start.getLocWithOffset(i), 1, ""); 1221 continue; 1222 } 1223 Escaped = !Escaped; 1224 break; 1225 case '\"': 1226 case '\'': 1227 if (!Escaped && IsSingle == (Input[i] == '\'')) { 1228 // Escape the quote. 1229 Replace(Start.getLocWithOffset(i), 0, "\\"); 1230 } 1231 Escaped = false; 1232 break; 1233 default: 1234 Escaped = false; 1235 break; 1236 } 1237 } 1238 } 1239 } 1240 } 1241 }; 1242 1243 class Formatter : public TokenAnalyzer { 1244 public: 1245 Formatter(const Environment &Env, const FormatStyle &Style, 1246 FormattingAttemptStatus *Status) 1247 : TokenAnalyzer(Env, Style), Status(Status) {} 1248 1249 std::pair<tooling::Replacements, unsigned> 1250 analyze(TokenAnnotator &Annotator, 1251 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1252 FormatTokenLexer &Tokens) override { 1253 tooling::Replacements Result; 1254 deriveLocalStyle(AnnotatedLines); 1255 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 1256 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1257 Annotator.calculateFormattingInformation(*AnnotatedLines[i]); 1258 } 1259 Annotator.setCommentLineLevels(AnnotatedLines); 1260 1261 WhitespaceManager Whitespaces( 1262 Env.getSourceManager(), Style, 1263 inputUsesCRLF(Env.getSourceManager().getBufferData(Env.getFileID()))); 1264 ContinuationIndenter Indenter(Style, Tokens.getKeywords(), 1265 Env.getSourceManager(), Whitespaces, Encoding, 1266 BinPackInconclusiveFunctions); 1267 unsigned Penalty = 1268 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style, 1269 Tokens.getKeywords(), Env.getSourceManager(), 1270 Status) 1271 .format(AnnotatedLines, /*DryRun=*/false, 1272 /*AdditionalIndent=*/0, 1273 /*FixBadIndentation=*/false, 1274 /*FirstStartColumn=*/Env.getFirstStartColumn(), 1275 /*NextStartColumn=*/Env.getNextStartColumn(), 1276 /*LastStartColumn=*/Env.getLastStartColumn()); 1277 for (const auto &R : Whitespaces.generateReplacements()) 1278 if (Result.add(R)) 1279 return std::make_pair(Result, 0); 1280 return std::make_pair(Result, Penalty); 1281 } 1282 1283 private: 1284 static bool inputUsesCRLF(StringRef Text) { 1285 return Text.count('\r') * 2 > Text.count('\n'); 1286 } 1287 1288 bool 1289 hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) { 1290 for (const AnnotatedLine *Line : Lines) { 1291 if (hasCpp03IncompatibleFormat(Line->Children)) 1292 return true; 1293 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) { 1294 if (Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) { 1295 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener)) 1296 return true; 1297 if (Tok->is(TT_TemplateCloser) && 1298 Tok->Previous->is(TT_TemplateCloser)) 1299 return true; 1300 } 1301 } 1302 } 1303 return false; 1304 } 1305 1306 int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) { 1307 int AlignmentDiff = 0; 1308 for (const AnnotatedLine *Line : Lines) { 1309 AlignmentDiff += countVariableAlignments(Line->Children); 1310 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) { 1311 if (!Tok->is(TT_PointerOrReference)) 1312 continue; 1313 bool SpaceBefore = 1314 Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd(); 1315 bool SpaceAfter = Tok->Next->WhitespaceRange.getBegin() != 1316 Tok->Next->WhitespaceRange.getEnd(); 1317 if (SpaceBefore && !SpaceAfter) 1318 ++AlignmentDiff; 1319 if (!SpaceBefore && SpaceAfter) 1320 --AlignmentDiff; 1321 } 1322 } 1323 return AlignmentDiff; 1324 } 1325 1326 void 1327 deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 1328 bool HasBinPackedFunction = false; 1329 bool HasOnePerLineFunction = false; 1330 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1331 if (!AnnotatedLines[i]->First->Next) 1332 continue; 1333 FormatToken *Tok = AnnotatedLines[i]->First->Next; 1334 while (Tok->Next) { 1335 if (Tok->PackingKind == PPK_BinPacked) 1336 HasBinPackedFunction = true; 1337 if (Tok->PackingKind == PPK_OnePerLine) 1338 HasOnePerLineFunction = true; 1339 1340 Tok = Tok->Next; 1341 } 1342 } 1343 if (Style.DerivePointerAlignment) 1344 Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0 1345 ? FormatStyle::PAS_Left 1346 : FormatStyle::PAS_Right; 1347 if (Style.Standard == FormatStyle::LS_Auto) 1348 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines) 1349 ? FormatStyle::LS_Cpp11 1350 : FormatStyle::LS_Cpp03; 1351 BinPackInconclusiveFunctions = 1352 HasBinPackedFunction || !HasOnePerLineFunction; 1353 } 1354 1355 bool BinPackInconclusiveFunctions; 1356 FormattingAttemptStatus *Status; 1357 }; 1358 1359 // This class clean up the erroneous/redundant code around the given ranges in 1360 // file. 1361 class Cleaner : public TokenAnalyzer { 1362 public: 1363 Cleaner(const Environment &Env, const FormatStyle &Style) 1364 : TokenAnalyzer(Env, Style), 1365 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {} 1366 1367 // FIXME: eliminate unused parameters. 1368 std::pair<tooling::Replacements, unsigned> 1369 analyze(TokenAnnotator &Annotator, 1370 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1371 FormatTokenLexer &Tokens) override { 1372 // FIXME: in the current implementation the granularity of affected range 1373 // is an annotated line. However, this is not sufficient. Furthermore, 1374 // redundant code introduced by replacements does not necessarily 1375 // intercept with ranges of replacements that result in the redundancy. 1376 // To determine if some redundant code is actually introduced by 1377 // replacements(e.g. deletions), we need to come up with a more 1378 // sophisticated way of computing affected ranges. 1379 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 1380 1381 checkEmptyNamespace(AnnotatedLines); 1382 1383 for (auto &Line : AnnotatedLines) { 1384 if (Line->Affected) { 1385 cleanupRight(Line->First, tok::comma, tok::comma); 1386 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma); 1387 cleanupRight(Line->First, tok::l_paren, tok::comma); 1388 cleanupLeft(Line->First, tok::comma, tok::r_paren); 1389 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace); 1390 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace); 1391 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal); 1392 } 1393 } 1394 1395 return {generateFixes(), 0}; 1396 } 1397 1398 private: 1399 bool containsOnlyComments(const AnnotatedLine &Line) { 1400 for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next) { 1401 if (Tok->isNot(tok::comment)) 1402 return false; 1403 } 1404 return true; 1405 } 1406 1407 // Iterate through all lines and remove any empty (nested) namespaces. 1408 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 1409 std::set<unsigned> DeletedLines; 1410 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1411 auto &Line = *AnnotatedLines[i]; 1412 if (Line.startsWithNamespace()) { 1413 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines); 1414 } 1415 } 1416 1417 for (auto Line : DeletedLines) { 1418 FormatToken *Tok = AnnotatedLines[Line]->First; 1419 while (Tok) { 1420 deleteToken(Tok); 1421 Tok = Tok->Next; 1422 } 1423 } 1424 } 1425 1426 // The function checks if the namespace, which starts from \p CurrentLine, and 1427 // its nested namespaces are empty and delete them if they are empty. It also 1428 // sets \p NewLine to the last line checked. 1429 // Returns true if the current namespace is empty. 1430 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1431 unsigned CurrentLine, unsigned &NewLine, 1432 std::set<unsigned> &DeletedLines) { 1433 unsigned InitLine = CurrentLine, End = AnnotatedLines.size(); 1434 if (Style.BraceWrapping.AfterNamespace) { 1435 // If the left brace is in a new line, we should consume it first so that 1436 // it does not make the namespace non-empty. 1437 // FIXME: error handling if there is no left brace. 1438 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) { 1439 NewLine = CurrentLine; 1440 return false; 1441 } 1442 } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) { 1443 return false; 1444 } 1445 while (++CurrentLine < End) { 1446 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace)) 1447 break; 1448 1449 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) { 1450 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine, 1451 DeletedLines)) 1452 return false; 1453 CurrentLine = NewLine; 1454 continue; 1455 } 1456 1457 if (containsOnlyComments(*AnnotatedLines[CurrentLine])) 1458 continue; 1459 1460 // If there is anything other than comments or nested namespaces in the 1461 // current namespace, the namespace cannot be empty. 1462 NewLine = CurrentLine; 1463 return false; 1464 } 1465 1466 NewLine = CurrentLine; 1467 if (CurrentLine >= End) 1468 return false; 1469 1470 // Check if the empty namespace is actually affected by changed ranges. 1471 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange( 1472 AnnotatedLines[InitLine]->First->Tok.getLocation(), 1473 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) 1474 return false; 1475 1476 for (unsigned i = InitLine; i <= CurrentLine; ++i) { 1477 DeletedLines.insert(i); 1478 } 1479 1480 return true; 1481 } 1482 1483 // Checks pairs {start, start->next},..., {end->previous, end} and deletes one 1484 // of the token in the pair if the left token has \p LK token kind and the 1485 // right token has \p RK token kind. If \p DeleteLeft is true, the left token 1486 // is deleted on match; otherwise, the right token is deleted. 1487 template <typename LeftKind, typename RightKind> 1488 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK, 1489 bool DeleteLeft) { 1490 auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * { 1491 for (auto *Res = Tok.Next; Res; Res = Res->Next) 1492 if (!Res->is(tok::comment) && 1493 DeletedTokens.find(Res) == DeletedTokens.end()) 1494 return Res; 1495 return nullptr; 1496 }; 1497 for (auto *Left = Start; Left;) { 1498 auto *Right = NextNotDeleted(*Left); 1499 if (!Right) 1500 break; 1501 if (Left->is(LK) && Right->is(RK)) { 1502 deleteToken(DeleteLeft ? Left : Right); 1503 for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next) 1504 deleteToken(Tok); 1505 // If the right token is deleted, we should keep the left token 1506 // unchanged and pair it with the new right token. 1507 if (!DeleteLeft) 1508 continue; 1509 } 1510 Left = Right; 1511 } 1512 } 1513 1514 template <typename LeftKind, typename RightKind> 1515 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) { 1516 cleanupPair(Start, LK, RK, /*DeleteLeft=*/true); 1517 } 1518 1519 template <typename LeftKind, typename RightKind> 1520 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) { 1521 cleanupPair(Start, LK, RK, /*DeleteLeft=*/false); 1522 } 1523 1524 // Delete the given token. 1525 inline void deleteToken(FormatToken *Tok) { 1526 if (Tok) 1527 DeletedTokens.insert(Tok); 1528 } 1529 1530 tooling::Replacements generateFixes() { 1531 tooling::Replacements Fixes; 1532 std::vector<FormatToken *> Tokens; 1533 std::copy(DeletedTokens.begin(), DeletedTokens.end(), 1534 std::back_inserter(Tokens)); 1535 1536 // Merge multiple continuous token deletions into one big deletion so that 1537 // the number of replacements can be reduced. This makes computing affected 1538 // ranges more efficient when we run reformat on the changed code. 1539 unsigned Idx = 0; 1540 while (Idx < Tokens.size()) { 1541 unsigned St = Idx, End = Idx; 1542 while ((End + 1) < Tokens.size() && 1543 Tokens[End]->Next == Tokens[End + 1]) { 1544 End++; 1545 } 1546 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(), 1547 Tokens[End]->Tok.getEndLoc()); 1548 auto Err = 1549 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, "")); 1550 // FIXME: better error handling. for now just print error message and skip 1551 // for the release version. 1552 if (Err) { 1553 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1554 assert(false && "Fixes must not conflict!"); 1555 } 1556 Idx = End + 1; 1557 } 1558 1559 return Fixes; 1560 } 1561 1562 // Class for less-than inequality comparason for the set `RedundantTokens`. 1563 // We store tokens in the order they appear in the translation unit so that 1564 // we do not need to sort them in `generateFixes()`. 1565 struct FormatTokenLess { 1566 FormatTokenLess(const SourceManager &SM) : SM(SM) {} 1567 1568 bool operator()(const FormatToken *LHS, const FormatToken *RHS) const { 1569 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(), 1570 RHS->Tok.getLocation()); 1571 } 1572 const SourceManager &SM; 1573 }; 1574 1575 // Tokens to be deleted. 1576 std::set<FormatToken *, FormatTokenLess> DeletedTokens; 1577 }; 1578 1579 class ObjCHeaderStyleGuesser : public TokenAnalyzer { 1580 public: 1581 ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style) 1582 : TokenAnalyzer(Env, Style), IsObjC(false) {} 1583 1584 std::pair<tooling::Replacements, unsigned> 1585 analyze(TokenAnnotator &Annotator, 1586 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1587 FormatTokenLexer &Tokens) override { 1588 assert(Style.Language == FormatStyle::LK_Cpp); 1589 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines, 1590 Tokens.getKeywords()); 1591 tooling::Replacements Result; 1592 return {Result, 0}; 1593 } 1594 1595 bool isObjC() { return IsObjC; } 1596 1597 private: 1598 static bool 1599 guessIsObjC(const SourceManager &SourceManager, 1600 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1601 const AdditionalKeywords &Keywords) { 1602 // Keep this array sorted, since we are binary searching over it. 1603 static constexpr llvm::StringLiteral FoundationIdentifiers[] = { 1604 "CGFloat", 1605 "CGPoint", 1606 "CGPointMake", 1607 "CGPointZero", 1608 "CGRect", 1609 "CGRectEdge", 1610 "CGRectInfinite", 1611 "CGRectMake", 1612 "CGRectNull", 1613 "CGRectZero", 1614 "CGSize", 1615 "CGSizeMake", 1616 "CGVector", 1617 "CGVectorMake", 1618 "NSAffineTransform", 1619 "NSArray", 1620 "NSAttributedString", 1621 "NSBlockOperation", 1622 "NSBundle", 1623 "NSCache", 1624 "NSCalendar", 1625 "NSCharacterSet", 1626 "NSCountedSet", 1627 "NSData", 1628 "NSDataDetector", 1629 "NSDecimal", 1630 "NSDecimalNumber", 1631 "NSDictionary", 1632 "NSEdgeInsets", 1633 "NSHashTable", 1634 "NSIndexPath", 1635 "NSIndexSet", 1636 "NSInteger", 1637 "NSInvocationOperation", 1638 "NSLocale", 1639 "NSMapTable", 1640 "NSMutableArray", 1641 "NSMutableAttributedString", 1642 "NSMutableCharacterSet", 1643 "NSMutableData", 1644 "NSMutableDictionary", 1645 "NSMutableIndexSet", 1646 "NSMutableOrderedSet", 1647 "NSMutableSet", 1648 "NSMutableString", 1649 "NSNumber", 1650 "NSNumberFormatter", 1651 "NSObject", 1652 "NSOperation", 1653 "NSOperationQueue", 1654 "NSOperationQueuePriority", 1655 "NSOrderedSet", 1656 "NSPoint", 1657 "NSPointerArray", 1658 "NSQualityOfService", 1659 "NSRange", 1660 "NSRect", 1661 "NSRegularExpression", 1662 "NSSet", 1663 "NSSize", 1664 "NSString", 1665 "NSTimeZone", 1666 "NSUInteger", 1667 "NSURL", 1668 "NSURLComponents", 1669 "NSURLQueryItem", 1670 "NSUUID", 1671 "NSValue", 1672 "UIImage", 1673 "UIView", 1674 }; 1675 1676 for (auto Line : AnnotatedLines) { 1677 for (const FormatToken *FormatTok = Line->First; FormatTok; 1678 FormatTok = FormatTok->Next) { 1679 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) && 1680 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword || 1681 FormatTok->isOneOf(tok::numeric_constant, tok::l_square, 1682 tok::l_brace))) || 1683 (FormatTok->Tok.isAnyIdentifier() && 1684 std::binary_search(std::begin(FoundationIdentifiers), 1685 std::end(FoundationIdentifiers), 1686 FormatTok->TokenText)) || 1687 FormatTok->is(TT_ObjCStringLiteral) || 1688 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM, 1689 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace, 1690 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn, 1691 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier, 1692 TT_ObjCProperty)) { 1693 LLVM_DEBUG(llvm::dbgs() 1694 << "Detected ObjC at location " 1695 << FormatTok->Tok.getLocation().printToString( 1696 SourceManager) 1697 << " token: " << FormatTok->TokenText << " token type: " 1698 << getTokenTypeName(FormatTok->Type) << "\n"); 1699 return true; 1700 } 1701 if (guessIsObjC(SourceManager, Line->Children, Keywords)) 1702 return true; 1703 } 1704 } 1705 return false; 1706 } 1707 1708 bool IsObjC; 1709 }; 1710 1711 struct IncludeDirective { 1712 StringRef Filename; 1713 StringRef Text; 1714 unsigned Offset; 1715 int Category; 1716 }; 1717 1718 struct JavaImportDirective { 1719 StringRef Identifier; 1720 StringRef Text; 1721 unsigned Offset; 1722 std::vector<StringRef> AssociatedCommentLines; 1723 bool IsStatic; 1724 }; 1725 1726 } // end anonymous namespace 1727 1728 // Determines whether 'Ranges' intersects with ('Start', 'End'). 1729 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start, 1730 unsigned End) { 1731 for (auto Range : Ranges) { 1732 if (Range.getOffset() < End && 1733 Range.getOffset() + Range.getLength() > Start) 1734 return true; 1735 } 1736 return false; 1737 } 1738 1739 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor 1740 // before sorting/deduplicating. Index is the index of the include under the 1741 // cursor in the original set of includes. If this include has duplicates, it is 1742 // the index of the first of the duplicates as the others are going to be 1743 // removed. OffsetToEOL describes the cursor's position relative to the end of 1744 // its current line. 1745 // If `Cursor` is not on any #include, `Index` will be UINT_MAX. 1746 static std::pair<unsigned, unsigned> 1747 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes, 1748 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) { 1749 unsigned CursorIndex = UINT_MAX; 1750 unsigned OffsetToEOL = 0; 1751 for (int i = 0, e = Includes.size(); i != e; ++i) { 1752 unsigned Start = Includes[Indices[i]].Offset; 1753 unsigned End = Start + Includes[Indices[i]].Text.size(); 1754 if (!(Cursor >= Start && Cursor < End)) 1755 continue; 1756 CursorIndex = Indices[i]; 1757 OffsetToEOL = End - Cursor; 1758 // Put the cursor on the only remaining #include among the duplicate 1759 // #includes. 1760 while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text) 1761 CursorIndex = i; 1762 break; 1763 } 1764 return std::make_pair(CursorIndex, OffsetToEOL); 1765 } 1766 1767 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically 1768 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict 1769 // source order. 1770 // #include directives with the same text will be deduplicated, and only the 1771 // first #include in the duplicate #includes remains. If the `Cursor` is 1772 // provided and put on a deleted #include, it will be moved to the remaining 1773 // #include in the duplicate #includes. 1774 static void sortCppIncludes(const FormatStyle &Style, 1775 const SmallVectorImpl<IncludeDirective> &Includes, 1776 ArrayRef<tooling::Range> Ranges, StringRef FileName, 1777 StringRef Code, tooling::Replacements &Replaces, 1778 unsigned *Cursor) { 1779 unsigned IncludesBeginOffset = Includes.front().Offset; 1780 unsigned IncludesEndOffset = 1781 Includes.back().Offset + Includes.back().Text.size(); 1782 unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset; 1783 if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset)) 1784 return; 1785 SmallVector<unsigned, 16> Indices; 1786 for (unsigned i = 0, e = Includes.size(); i != e; ++i) 1787 Indices.push_back(i); 1788 llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) { 1789 return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) < 1790 std::tie(Includes[RHSI].Category, Includes[RHSI].Filename); 1791 }); 1792 // The index of the include on which the cursor will be put after 1793 // sorting/deduplicating. 1794 unsigned CursorIndex; 1795 // The offset from cursor to the end of line. 1796 unsigned CursorToEOLOffset; 1797 if (Cursor) 1798 std::tie(CursorIndex, CursorToEOLOffset) = 1799 FindCursorIndex(Includes, Indices, *Cursor); 1800 1801 // Deduplicate #includes. 1802 Indices.erase(std::unique(Indices.begin(), Indices.end(), 1803 [&](unsigned LHSI, unsigned RHSI) { 1804 return Includes[LHSI].Text == Includes[RHSI].Text; 1805 }), 1806 Indices.end()); 1807 1808 int CurrentCategory = Includes.front().Category; 1809 1810 // If the #includes are out of order, we generate a single replacement fixing 1811 // the entire block. Otherwise, no replacement is generated. 1812 // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not 1813 // enough as additional newlines might be added or removed across #include 1814 // blocks. This we handle below by generating the updated #imclude blocks and 1815 // comparing it to the original. 1816 if (Indices.size() == Includes.size() && 1817 std::is_sorted(Indices.begin(), Indices.end()) && 1818 Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve) 1819 return; 1820 1821 std::string result; 1822 for (unsigned Index : Indices) { 1823 if (!result.empty()) { 1824 result += "\n"; 1825 if (Style.IncludeStyle.IncludeBlocks == 1826 tooling::IncludeStyle::IBS_Regroup && 1827 CurrentCategory != Includes[Index].Category) 1828 result += "\n"; 1829 } 1830 result += Includes[Index].Text; 1831 if (Cursor && CursorIndex == Index) 1832 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset; 1833 CurrentCategory = Includes[Index].Category; 1834 } 1835 1836 // If the #includes are out of order, we generate a single replacement fixing 1837 // the entire range of blocks. Otherwise, no replacement is generated. 1838 if (result == Code.substr(IncludesBeginOffset, IncludesBlockSize)) 1839 return; 1840 1841 auto Err = Replaces.add(tooling::Replacement( 1842 FileName, Includes.front().Offset, IncludesBlockSize, result)); 1843 // FIXME: better error handling. For now, just skip the replacement for the 1844 // release version. 1845 if (Err) { 1846 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1847 assert(false); 1848 } 1849 } 1850 1851 namespace { 1852 1853 const char CppIncludeRegexPattern[] = 1854 R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))"; 1855 1856 } // anonymous namespace 1857 1858 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code, 1859 ArrayRef<tooling::Range> Ranges, 1860 StringRef FileName, 1861 tooling::Replacements &Replaces, 1862 unsigned *Cursor) { 1863 unsigned Prev = 0; 1864 unsigned SearchFrom = 0; 1865 llvm::Regex IncludeRegex(CppIncludeRegexPattern); 1866 SmallVector<StringRef, 4> Matches; 1867 SmallVector<IncludeDirective, 16> IncludesInBlock; 1868 1869 // In compiled files, consider the first #include to be the main #include of 1870 // the file if it is not a system #include. This ensures that the header 1871 // doesn't have hidden dependencies 1872 // (http://llvm.org/docs/CodingStandards.html#include-style). 1873 // 1874 // FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix 1875 // cases where the first #include is unlikely to be the main header. 1876 tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName); 1877 bool FirstIncludeBlock = true; 1878 bool MainIncludeFound = false; 1879 bool FormattingOff = false; 1880 1881 for (;;) { 1882 auto Pos = Code.find('\n', SearchFrom); 1883 StringRef Line = 1884 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); 1885 1886 StringRef Trimmed = Line.trim(); 1887 if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */") 1888 FormattingOff = true; 1889 else if (Trimmed == "// clang-format on" || 1890 Trimmed == "/* clang-format on */") 1891 FormattingOff = false; 1892 1893 const bool EmptyLineSkipped = 1894 Trimmed.empty() && 1895 (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge || 1896 Style.IncludeStyle.IncludeBlocks == 1897 tooling::IncludeStyle::IBS_Regroup); 1898 1899 if (!FormattingOff && !Line.endswith("\\")) { 1900 if (IncludeRegex.match(Line, &Matches)) { 1901 StringRef IncludeName = Matches[2]; 1902 int Category = Categories.getIncludePriority( 1903 IncludeName, 1904 /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock); 1905 if (Category == 0) 1906 MainIncludeFound = true; 1907 IncludesInBlock.push_back({IncludeName, Line, Prev, Category}); 1908 } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) { 1909 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, 1910 Replaces, Cursor); 1911 IncludesInBlock.clear(); 1912 FirstIncludeBlock = false; 1913 } 1914 Prev = Pos + 1; 1915 } 1916 if (Pos == StringRef::npos || Pos + 1 == Code.size()) 1917 break; 1918 SearchFrom = Pos + 1; 1919 } 1920 if (!IncludesInBlock.empty()) { 1921 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces, 1922 Cursor); 1923 } 1924 return Replaces; 1925 } 1926 1927 // Returns group number to use as a first order sort on imports. Gives UINT_MAX 1928 // if the import does not match any given groups. 1929 static unsigned findJavaImportGroup(const FormatStyle &Style, 1930 StringRef ImportIdentifier) { 1931 unsigned LongestMatchIndex = UINT_MAX; 1932 unsigned LongestMatchLength = 0; 1933 for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) { 1934 std::string GroupPrefix = Style.JavaImportGroups[I]; 1935 if (ImportIdentifier.startswith(GroupPrefix) && 1936 GroupPrefix.length() > LongestMatchLength) { 1937 LongestMatchIndex = I; 1938 LongestMatchLength = GroupPrefix.length(); 1939 } 1940 } 1941 return LongestMatchIndex; 1942 } 1943 1944 // Sorts and deduplicates a block of includes given by 'Imports' based on 1945 // JavaImportGroups, then adding the necessary replacement to 'Replaces'. 1946 // Import declarations with the same text will be deduplicated. Between each 1947 // import group, a newline is inserted, and within each import group, a 1948 // lexicographic sort based on ASCII value is performed. 1949 static void sortJavaImports(const FormatStyle &Style, 1950 const SmallVectorImpl<JavaImportDirective> &Imports, 1951 ArrayRef<tooling::Range> Ranges, StringRef FileName, 1952 StringRef Code, tooling::Replacements &Replaces) { 1953 unsigned ImportsBeginOffset = Imports.front().Offset; 1954 unsigned ImportsEndOffset = 1955 Imports.back().Offset + Imports.back().Text.size(); 1956 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset; 1957 if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset)) 1958 return; 1959 SmallVector<unsigned, 16> Indices; 1960 SmallVector<unsigned, 16> JavaImportGroups; 1961 for (unsigned i = 0, e = Imports.size(); i != e; ++i) { 1962 Indices.push_back(i); 1963 JavaImportGroups.push_back( 1964 findJavaImportGroup(Style, Imports[i].Identifier)); 1965 } 1966 llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) { 1967 // Negating IsStatic to push static imports above non-static imports. 1968 return std::make_tuple(!Imports[LHSI].IsStatic, JavaImportGroups[LHSI], 1969 Imports[LHSI].Identifier) < 1970 std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI], 1971 Imports[RHSI].Identifier); 1972 }); 1973 1974 // Deduplicate imports. 1975 Indices.erase(std::unique(Indices.begin(), Indices.end(), 1976 [&](unsigned LHSI, unsigned RHSI) { 1977 return Imports[LHSI].Text == Imports[RHSI].Text; 1978 }), 1979 Indices.end()); 1980 1981 bool CurrentIsStatic = Imports[Indices.front()].IsStatic; 1982 unsigned CurrentImportGroup = JavaImportGroups[Indices.front()]; 1983 1984 std::string result; 1985 for (unsigned Index : Indices) { 1986 if (!result.empty()) { 1987 result += "\n"; 1988 if (CurrentIsStatic != Imports[Index].IsStatic || 1989 CurrentImportGroup != JavaImportGroups[Index]) 1990 result += "\n"; 1991 } 1992 for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) { 1993 result += CommentLine; 1994 result += "\n"; 1995 } 1996 result += Imports[Index].Text; 1997 CurrentIsStatic = Imports[Index].IsStatic; 1998 CurrentImportGroup = JavaImportGroups[Index]; 1999 } 2000 2001 // If the imports are out of order, we generate a single replacement fixing 2002 // the entire block. Otherwise, no replacement is generated. 2003 if (result == Code.substr(Imports.front().Offset, ImportsBlockSize)) 2004 return; 2005 2006 auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset, 2007 ImportsBlockSize, result)); 2008 // FIXME: better error handling. For now, just skip the replacement for the 2009 // release version. 2010 if (Err) { 2011 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 2012 assert(false); 2013 } 2014 } 2015 2016 namespace { 2017 2018 const char JavaImportRegexPattern[] = 2019 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"; 2020 2021 } // anonymous namespace 2022 2023 tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, 2024 ArrayRef<tooling::Range> Ranges, 2025 StringRef FileName, 2026 tooling::Replacements &Replaces) { 2027 unsigned Prev = 0; 2028 unsigned SearchFrom = 0; 2029 llvm::Regex ImportRegex(JavaImportRegexPattern); 2030 SmallVector<StringRef, 4> Matches; 2031 SmallVector<JavaImportDirective, 16> ImportsInBlock; 2032 std::vector<StringRef> AssociatedCommentLines; 2033 2034 bool FormattingOff = false; 2035 2036 for (;;) { 2037 auto Pos = Code.find('\n', SearchFrom); 2038 StringRef Line = 2039 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); 2040 2041 StringRef Trimmed = Line.trim(); 2042 if (Trimmed == "// clang-format off") 2043 FormattingOff = true; 2044 else if (Trimmed == "// clang-format on") 2045 FormattingOff = false; 2046 2047 if (ImportRegex.match(Line, &Matches)) { 2048 if (FormattingOff) { 2049 // If at least one import line has formatting turned off, turn off 2050 // formatting entirely. 2051 return Replaces; 2052 } 2053 StringRef Static = Matches[1]; 2054 StringRef Identifier = Matches[2]; 2055 bool IsStatic = false; 2056 if (Static.contains("static")) { 2057 IsStatic = true; 2058 } 2059 ImportsInBlock.push_back( 2060 {Identifier, Line, Prev, AssociatedCommentLines, IsStatic}); 2061 AssociatedCommentLines.clear(); 2062 } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) { 2063 // Associating comments within the imports with the nearest import below 2064 AssociatedCommentLines.push_back(Line); 2065 } 2066 Prev = Pos + 1; 2067 if (Pos == StringRef::npos || Pos + 1 == Code.size()) 2068 break; 2069 SearchFrom = Pos + 1; 2070 } 2071 if (!ImportsInBlock.empty()) 2072 sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces); 2073 return Replaces; 2074 } 2075 2076 bool isMpegTS(StringRef Code) { 2077 // MPEG transport streams use the ".ts" file extension. clang-format should 2078 // not attempt to format those. MPEG TS' frame format starts with 0x47 every 2079 // 189 bytes - detect that and return. 2080 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47; 2081 } 2082 2083 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); } 2084 2085 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, 2086 ArrayRef<tooling::Range> Ranges, 2087 StringRef FileName, unsigned *Cursor) { 2088 tooling::Replacements Replaces; 2089 if (!Style.SortIncludes) 2090 return Replaces; 2091 if (isLikelyXml(Code)) 2092 return Replaces; 2093 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript && 2094 isMpegTS(Code)) 2095 return Replaces; 2096 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript) 2097 return sortJavaScriptImports(Style, Code, Ranges, FileName); 2098 if (Style.Language == FormatStyle::LanguageKind::LK_Java) 2099 return sortJavaImports(Style, Code, Ranges, FileName, Replaces); 2100 sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor); 2101 return Replaces; 2102 } 2103 2104 template <typename T> 2105 static llvm::Expected<tooling::Replacements> 2106 processReplacements(T ProcessFunc, StringRef Code, 2107 const tooling::Replacements &Replaces, 2108 const FormatStyle &Style) { 2109 if (Replaces.empty()) 2110 return tooling::Replacements(); 2111 2112 auto NewCode = applyAllReplacements(Code, Replaces); 2113 if (!NewCode) 2114 return NewCode.takeError(); 2115 std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges(); 2116 StringRef FileName = Replaces.begin()->getFilePath(); 2117 2118 tooling::Replacements FormatReplaces = 2119 ProcessFunc(Style, *NewCode, ChangedRanges, FileName); 2120 2121 return Replaces.merge(FormatReplaces); 2122 } 2123 2124 llvm::Expected<tooling::Replacements> 2125 formatReplacements(StringRef Code, const tooling::Replacements &Replaces, 2126 const FormatStyle &Style) { 2127 // We need to use lambda function here since there are two versions of 2128 // `sortIncludes`. 2129 auto SortIncludes = [](const FormatStyle &Style, StringRef Code, 2130 std::vector<tooling::Range> Ranges, 2131 StringRef FileName) -> tooling::Replacements { 2132 return sortIncludes(Style, Code, Ranges, FileName); 2133 }; 2134 auto SortedReplaces = 2135 processReplacements(SortIncludes, Code, Replaces, Style); 2136 if (!SortedReplaces) 2137 return SortedReplaces.takeError(); 2138 2139 // We need to use lambda function here since there are two versions of 2140 // `reformat`. 2141 auto Reformat = [](const FormatStyle &Style, StringRef Code, 2142 std::vector<tooling::Range> Ranges, 2143 StringRef FileName) -> tooling::Replacements { 2144 return reformat(Style, Code, Ranges, FileName); 2145 }; 2146 return processReplacements(Reformat, Code, *SortedReplaces, Style); 2147 } 2148 2149 namespace { 2150 2151 inline bool isHeaderInsertion(const tooling::Replacement &Replace) { 2152 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 && 2153 llvm::Regex(CppIncludeRegexPattern) 2154 .match(Replace.getReplacementText()); 2155 } 2156 2157 inline bool isHeaderDeletion(const tooling::Replacement &Replace) { 2158 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1; 2159 } 2160 2161 // FIXME: insert empty lines between newly created blocks. 2162 tooling::Replacements 2163 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, 2164 const FormatStyle &Style) { 2165 if (!Style.isCpp()) 2166 return Replaces; 2167 2168 tooling::Replacements HeaderInsertions; 2169 std::set<llvm::StringRef> HeadersToDelete; 2170 tooling::Replacements Result; 2171 for (const auto &R : Replaces) { 2172 if (isHeaderInsertion(R)) { 2173 // Replacements from \p Replaces must be conflict-free already, so we can 2174 // simply consume the error. 2175 llvm::consumeError(HeaderInsertions.add(R)); 2176 } else if (isHeaderDeletion(R)) { 2177 HeadersToDelete.insert(R.getReplacementText()); 2178 } else if (R.getOffset() == UINT_MAX) { 2179 llvm::errs() << "Insertions other than header #include insertion are " 2180 "not supported! " 2181 << R.getReplacementText() << "\n"; 2182 } else { 2183 llvm::consumeError(Result.add(R)); 2184 } 2185 } 2186 if (HeaderInsertions.empty() && HeadersToDelete.empty()) 2187 return Replaces; 2188 2189 StringRef FileName = Replaces.begin()->getFilePath(); 2190 tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle); 2191 2192 for (const auto &Header : HeadersToDelete) { 2193 tooling::Replacements Replaces = 2194 Includes.remove(Header.trim("\"<>"), Header.startswith("<")); 2195 for (const auto &R : Replaces) { 2196 auto Err = Result.add(R); 2197 if (Err) { 2198 // Ignore the deletion on conflict. 2199 llvm::errs() << "Failed to add header deletion replacement for " 2200 << Header << ": " << llvm::toString(std::move(Err)) 2201 << "\n"; 2202 } 2203 } 2204 } 2205 2206 llvm::Regex IncludeRegex = llvm::Regex(CppIncludeRegexPattern); 2207 llvm::SmallVector<StringRef, 4> Matches; 2208 for (const auto &R : HeaderInsertions) { 2209 auto IncludeDirective = R.getReplacementText(); 2210 bool Matched = IncludeRegex.match(IncludeDirective, &Matches); 2211 assert(Matched && "Header insertion replacement must have replacement text " 2212 "'#include ...'"); 2213 (void)Matched; 2214 auto IncludeName = Matches[2]; 2215 auto Replace = 2216 Includes.insert(IncludeName.trim("\"<>"), IncludeName.startswith("<")); 2217 if (Replace) { 2218 auto Err = Result.add(*Replace); 2219 if (Err) { 2220 llvm::consumeError(std::move(Err)); 2221 unsigned NewOffset = 2222 Result.getShiftedCodePosition(Replace->getOffset()); 2223 auto Shifted = tooling::Replacement(FileName, NewOffset, 0, 2224 Replace->getReplacementText()); 2225 Result = Result.merge(tooling::Replacements(Shifted)); 2226 } 2227 } 2228 } 2229 return Result; 2230 } 2231 2232 } // anonymous namespace 2233 2234 llvm::Expected<tooling::Replacements> 2235 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces, 2236 const FormatStyle &Style) { 2237 // We need to use lambda function here since there are two versions of 2238 // `cleanup`. 2239 auto Cleanup = [](const FormatStyle &Style, StringRef Code, 2240 std::vector<tooling::Range> Ranges, 2241 StringRef FileName) -> tooling::Replacements { 2242 return cleanup(Style, Code, Ranges, FileName); 2243 }; 2244 // Make header insertion replacements insert new headers into correct blocks. 2245 tooling::Replacements NewReplaces = 2246 fixCppIncludeInsertions(Code, Replaces, Style); 2247 return processReplacements(Cleanup, Code, NewReplaces, Style); 2248 } 2249 2250 namespace internal { 2251 std::pair<tooling::Replacements, unsigned> 2252 reformat(const FormatStyle &Style, StringRef Code, 2253 ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn, 2254 unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, 2255 FormattingAttemptStatus *Status) { 2256 FormatStyle Expanded = expandPresets(Style); 2257 if (Expanded.DisableFormat) 2258 return {tooling::Replacements(), 0}; 2259 if (isLikelyXml(Code)) 2260 return {tooling::Replacements(), 0}; 2261 if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code)) 2262 return {tooling::Replacements(), 0}; 2263 2264 typedef std::function<std::pair<tooling::Replacements, unsigned>( 2265 const Environment &)> 2266 AnalyzerPass; 2267 SmallVector<AnalyzerPass, 4> Passes; 2268 2269 if (Style.Language == FormatStyle::LK_Cpp) { 2270 if (Style.FixNamespaceComments) 2271 Passes.emplace_back([&](const Environment &Env) { 2272 return NamespaceEndCommentsFixer(Env, Expanded).process(); 2273 }); 2274 2275 if (Style.SortUsingDeclarations) 2276 Passes.emplace_back([&](const Environment &Env) { 2277 return UsingDeclarationsSorter(Env, Expanded).process(); 2278 }); 2279 } 2280 2281 if (Style.Language == FormatStyle::LK_JavaScript && 2282 Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) 2283 Passes.emplace_back([&](const Environment &Env) { 2284 return JavaScriptRequoter(Env, Expanded).process(); 2285 }); 2286 2287 Passes.emplace_back([&](const Environment &Env) { 2288 return Formatter(Env, Expanded, Status).process(); 2289 }); 2290 2291 auto Env = 2292 llvm::make_unique<Environment>(Code, FileName, Ranges, FirstStartColumn, 2293 NextStartColumn, LastStartColumn); 2294 llvm::Optional<std::string> CurrentCode = None; 2295 tooling::Replacements Fixes; 2296 unsigned Penalty = 0; 2297 for (size_t I = 0, E = Passes.size(); I < E; ++I) { 2298 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env); 2299 auto NewCode = applyAllReplacements( 2300 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first); 2301 if (NewCode) { 2302 Fixes = Fixes.merge(PassFixes.first); 2303 Penalty += PassFixes.second; 2304 if (I + 1 < E) { 2305 CurrentCode = std::move(*NewCode); 2306 Env = llvm::make_unique<Environment>( 2307 *CurrentCode, FileName, 2308 tooling::calculateRangesAfterReplacements(Fixes, Ranges), 2309 FirstStartColumn, NextStartColumn, LastStartColumn); 2310 } 2311 } 2312 } 2313 2314 return {Fixes, Penalty}; 2315 } 2316 } // namespace internal 2317 2318 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 2319 ArrayRef<tooling::Range> Ranges, 2320 StringRef FileName, 2321 FormattingAttemptStatus *Status) { 2322 return internal::reformat(Style, Code, Ranges, 2323 /*FirstStartColumn=*/0, 2324 /*NextStartColumn=*/0, 2325 /*LastStartColumn=*/0, FileName, Status) 2326 .first; 2327 } 2328 2329 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, 2330 ArrayRef<tooling::Range> Ranges, 2331 StringRef FileName) { 2332 // cleanups only apply to C++ (they mostly concern ctor commas etc.) 2333 if (Style.Language != FormatStyle::LK_Cpp) 2334 return tooling::Replacements(); 2335 return Cleaner(Environment(Code, FileName, Ranges), Style).process().first; 2336 } 2337 2338 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 2339 ArrayRef<tooling::Range> Ranges, 2340 StringRef FileName, bool *IncompleteFormat) { 2341 FormattingAttemptStatus Status; 2342 auto Result = reformat(Style, Code, Ranges, FileName, &Status); 2343 if (!Status.FormatComplete) 2344 *IncompleteFormat = true; 2345 return Result; 2346 } 2347 2348 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, 2349 StringRef Code, 2350 ArrayRef<tooling::Range> Ranges, 2351 StringRef FileName) { 2352 return NamespaceEndCommentsFixer(Environment(Code, FileName, Ranges), Style) 2353 .process() 2354 .first; 2355 } 2356 2357 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, 2358 StringRef Code, 2359 ArrayRef<tooling::Range> Ranges, 2360 StringRef FileName) { 2361 return UsingDeclarationsSorter(Environment(Code, FileName, Ranges), Style) 2362 .process() 2363 .first; 2364 } 2365 2366 LangOptions getFormattingLangOpts(const FormatStyle &Style) { 2367 LangOptions LangOpts; 2368 FormatStyle::LanguageStandard LexingStd = 2369 Style.Standard == FormatStyle::LS_Auto ? FormatStyle::LS_Cpp11 2370 : Style.Standard; 2371 LangOpts.CPlusPlus = 1; 2372 LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11; 2373 LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp11; 2374 LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp11; 2375 LangOpts.CPlusPlus2a = LexingStd >= FormatStyle::LS_Cpp11; 2376 LangOpts.LineComment = 1; 2377 bool AlternativeOperators = Style.isCpp(); 2378 LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0; 2379 LangOpts.Bool = 1; 2380 LangOpts.ObjC = 1; 2381 LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally. 2382 LangOpts.DeclSpecKeyword = 1; // To get __declspec. 2383 return LangOpts; 2384 } 2385 2386 const char *StyleOptionHelpDescription = 2387 "Coding style, currently supports:\n" 2388 " LLVM, Google, Chromium, Mozilla, WebKit.\n" 2389 "Use -style=file to load style configuration from\n" 2390 ".clang-format file located in one of the parent\n" 2391 "directories of the source file (or current\n" 2392 "directory for stdin).\n" 2393 "Use -style=\"{key: value, ...}\" to set specific\n" 2394 "parameters, e.g.:\n" 2395 " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\""; 2396 2397 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) { 2398 if (FileName.endswith(".java")) 2399 return FormatStyle::LK_Java; 2400 if (FileName.endswith_lower(".js") || FileName.endswith_lower(".ts")) 2401 return FormatStyle::LK_JavaScript; // JavaScript or TypeScript. 2402 if (FileName.endswith(".m") || FileName.endswith(".mm")) 2403 return FormatStyle::LK_ObjC; 2404 if (FileName.endswith_lower(".proto") || 2405 FileName.endswith_lower(".protodevel")) 2406 return FormatStyle::LK_Proto; 2407 if (FileName.endswith_lower(".textpb") || 2408 FileName.endswith_lower(".pb.txt") || 2409 FileName.endswith_lower(".textproto") || 2410 FileName.endswith_lower(".asciipb")) 2411 return FormatStyle::LK_TextProto; 2412 if (FileName.endswith_lower(".td")) 2413 return FormatStyle::LK_TableGen; 2414 if (FileName.endswith_lower(".cs")) 2415 return FormatStyle::LK_CSharp; 2416 return FormatStyle::LK_Cpp; 2417 } 2418 2419 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) { 2420 const auto GuessedLanguage = getLanguageByFileName(FileName); 2421 if (GuessedLanguage == FormatStyle::LK_Cpp) { 2422 auto Extension = llvm::sys::path::extension(FileName); 2423 // If there's no file extension (or it's .h), we need to check the contents 2424 // of the code to see if it contains Objective-C. 2425 if (Extension.empty() || Extension == ".h") { 2426 auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName; 2427 Environment Env(Code, NonEmptyFileName, /*Ranges=*/{}); 2428 ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle()); 2429 Guesser.process(); 2430 if (Guesser.isObjC()) 2431 return FormatStyle::LK_ObjC; 2432 } 2433 } 2434 return GuessedLanguage; 2435 } 2436 2437 const char *DefaultFormatStyle = "file"; 2438 2439 const char *DefaultFallbackStyle = "LLVM"; 2440 2441 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, 2442 StringRef FallbackStyleName, 2443 StringRef Code, 2444 llvm::vfs::FileSystem *FS) { 2445 if (!FS) { 2446 FS = llvm::vfs::getRealFileSystem().get(); 2447 } 2448 FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code)); 2449 2450 FormatStyle FallbackStyle = getNoStyle(); 2451 if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle)) 2452 return make_string_error("Invalid fallback style \"" + FallbackStyleName); 2453 2454 if (StyleName.startswith("{")) { 2455 // Parse YAML/JSON style from the command line. 2456 if (std::error_code ec = parseConfiguration(StyleName, &Style)) 2457 return make_string_error("Error parsing -style: " + ec.message()); 2458 return Style; 2459 } 2460 2461 if (!StyleName.equals_lower("file")) { 2462 if (!getPredefinedStyle(StyleName, Style.Language, &Style)) 2463 return make_string_error("Invalid value for -style"); 2464 return Style; 2465 } 2466 2467 // Look for .clang-format/_clang-format file in the file's parent directories. 2468 SmallString<128> UnsuitableConfigFiles; 2469 SmallString<128> Path(FileName); 2470 if (std::error_code EC = FS->makeAbsolute(Path)) 2471 return make_string_error(EC.message()); 2472 2473 for (StringRef Directory = Path; !Directory.empty(); 2474 Directory = llvm::sys::path::parent_path(Directory)) { 2475 2476 auto Status = FS->status(Directory); 2477 if (!Status || 2478 Status->getType() != llvm::sys::fs::file_type::directory_file) { 2479 continue; 2480 } 2481 2482 SmallString<128> ConfigFile(Directory); 2483 2484 llvm::sys::path::append(ConfigFile, ".clang-format"); 2485 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2486 2487 Status = FS->status(ConfigFile.str()); 2488 bool FoundConfigFile = 2489 Status && (Status->getType() == llvm::sys::fs::file_type::regular_file); 2490 if (!FoundConfigFile) { 2491 // Try _clang-format too, since dotfiles are not commonly used on Windows. 2492 ConfigFile = Directory; 2493 llvm::sys::path::append(ConfigFile, "_clang-format"); 2494 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2495 Status = FS->status(ConfigFile.str()); 2496 FoundConfigFile = Status && (Status->getType() == 2497 llvm::sys::fs::file_type::regular_file); 2498 } 2499 2500 if (FoundConfigFile) { 2501 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 2502 FS->getBufferForFile(ConfigFile.str()); 2503 if (std::error_code EC = Text.getError()) 2504 return make_string_error(EC.message()); 2505 if (std::error_code ec = 2506 parseConfiguration(Text.get()->getBuffer(), &Style)) { 2507 if (ec == ParseError::Unsuitable) { 2508 if (!UnsuitableConfigFiles.empty()) 2509 UnsuitableConfigFiles.append(", "); 2510 UnsuitableConfigFiles.append(ConfigFile); 2511 continue; 2512 } 2513 return make_string_error("Error reading " + ConfigFile + ": " + 2514 ec.message()); 2515 } 2516 LLVM_DEBUG(llvm::dbgs() 2517 << "Using configuration file " << ConfigFile << "\n"); 2518 return Style; 2519 } 2520 } 2521 if (!UnsuitableConfigFiles.empty()) 2522 return make_string_error("Configuration file(s) do(es) not support " + 2523 getLanguageName(Style.Language) + ": " + 2524 UnsuitableConfigFiles); 2525 return FallbackStyle; 2526 } 2527 2528 } // namespace format 2529 } // namespace clang 2530