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.AfterUnion = true; 644 Expanded.BraceWrapping.AfterExternBlock = true; 645 Expanded.BraceWrapping.BeforeCatch = true; 646 Expanded.BraceWrapping.BeforeElse = true; 647 break; 648 case FormatStyle::BS_GNU: 649 Expanded.BraceWrapping = {true, true, true, true, true, true, true, true, 650 true, true, true, true, true, true, true, true}; 651 break; 652 case FormatStyle::BS_WebKit: 653 Expanded.BraceWrapping.AfterFunction = true; 654 break; 655 default: 656 break; 657 } 658 return Expanded; 659 } 660 661 FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { 662 FormatStyle LLVMStyle; 663 LLVMStyle.Language = Language; 664 LLVMStyle.AccessModifierOffset = -2; 665 LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right; 666 LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align; 667 LLVMStyle.AlignOperands = true; 668 LLVMStyle.AlignTrailingComments = true; 669 LLVMStyle.AlignConsecutiveAssignments = false; 670 LLVMStyle.AlignConsecutiveDeclarations = false; 671 LLVMStyle.AlignConsecutiveMacros = false; 672 LLVMStyle.AllowAllArgumentsOnNextLine = true; 673 LLVMStyle.AllowAllConstructorInitializersOnNextLine = true; 674 LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; 675 LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; 676 LLVMStyle.AllowShortBlocksOnASingleLine = false; 677 LLVMStyle.AllowShortCaseLabelsOnASingleLine = false; 678 LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 679 LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All; 680 LLVMStyle.AllowShortLoopsOnASingleLine = false; 681 LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None; 682 LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None; 683 LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; 684 LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine; 685 LLVMStyle.BinPackArguments = true; 686 LLVMStyle.BinPackParameters = true; 687 LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; 688 LLVMStyle.BreakBeforeTernaryOperators = true; 689 LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; 690 LLVMStyle.BraceWrapping = {false, false, false, false, false, false, 691 false, false, false, false, false, false, 692 false, true, true, true}; 693 LLVMStyle.BreakAfterJavaFieldAnnotations = false; 694 LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; 695 LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; 696 LLVMStyle.BreakStringLiterals = true; 697 LLVMStyle.ColumnLimit = 80; 698 LLVMStyle.CommentPragmas = "^ IWYU pragma:"; 699 LLVMStyle.CompactNamespaces = false; 700 LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false; 701 LLVMStyle.ConstructorInitializerIndentWidth = 4; 702 LLVMStyle.ContinuationIndentWidth = 4; 703 LLVMStyle.Cpp11BracedListStyle = true; 704 LLVMStyle.DerivePointerAlignment = false; 705 LLVMStyle.ExperimentalAutoDetectBinPacking = false; 706 LLVMStyle.FixNamespaceComments = true; 707 LLVMStyle.ForEachMacros.push_back("foreach"); 708 LLVMStyle.ForEachMacros.push_back("Q_FOREACH"); 709 LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH"); 710 LLVMStyle.IncludeStyle.IncludeCategories = { 711 {"^\"(llvm|llvm-c|clang|clang-c)/", 2}, 712 {"^(<|\"(gtest|gmock|isl|json)/)", 3}, 713 {".*", 1}}; 714 LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$"; 715 LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve; 716 LLVMStyle.IndentCaseLabels = false; 717 LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None; 718 LLVMStyle.IndentWrappedFunctionNames = false; 719 LLVMStyle.IndentWidth = 2; 720 LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave; 721 LLVMStyle.JavaScriptWrapImports = true; 722 LLVMStyle.TabWidth = 8; 723 LLVMStyle.MaxEmptyLinesToKeep = 1; 724 LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true; 725 LLVMStyle.NamespaceIndentation = FormatStyle::NI_None; 726 LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto; 727 LLVMStyle.ObjCBlockIndentWidth = 2; 728 LLVMStyle.ObjCSpaceAfterProperty = false; 729 LLVMStyle.ObjCSpaceBeforeProtocolList = true; 730 LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; 731 LLVMStyle.SpacesBeforeTrailingComments = 1; 732 LLVMStyle.Standard = FormatStyle::LS_Cpp11; 733 LLVMStyle.UseTab = FormatStyle::UT_Never; 734 LLVMStyle.ReflowComments = true; 735 LLVMStyle.SpacesInParentheses = false; 736 LLVMStyle.SpacesInSquareBrackets = false; 737 LLVMStyle.SpaceInEmptyParentheses = false; 738 LLVMStyle.SpacesInContainerLiterals = true; 739 LLVMStyle.SpacesInCStyleCastParentheses = false; 740 LLVMStyle.SpaceAfterCStyleCast = false; 741 LLVMStyle.SpaceAfterLogicalNot = false; 742 LLVMStyle.SpaceAfterTemplateKeyword = true; 743 LLVMStyle.SpaceBeforeCtorInitializerColon = true; 744 LLVMStyle.SpaceBeforeInheritanceColon = true; 745 LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements; 746 LLVMStyle.SpaceBeforeRangeBasedForLoopColon = true; 747 LLVMStyle.SpaceBeforeAssignmentOperators = true; 748 LLVMStyle.SpaceBeforeCpp11BracedList = false; 749 LLVMStyle.SpacesInAngles = false; 750 751 LLVMStyle.PenaltyBreakAssignment = prec::Assignment; 752 LLVMStyle.PenaltyBreakComment = 300; 753 LLVMStyle.PenaltyBreakFirstLessLess = 120; 754 LLVMStyle.PenaltyBreakString = 1000; 755 LLVMStyle.PenaltyExcessCharacter = 1000000; 756 LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60; 757 LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19; 758 LLVMStyle.PenaltyBreakTemplateDeclaration = prec::Relational; 759 760 LLVMStyle.DisableFormat = false; 761 LLVMStyle.SortIncludes = true; 762 LLVMStyle.SortUsingDeclarations = true; 763 LLVMStyle.StatementMacros.push_back("Q_UNUSED"); 764 LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION"); 765 766 // Defaults that differ when not C++. 767 if (Language == FormatStyle::LK_TableGen) { 768 LLVMStyle.SpacesInContainerLiterals = false; 769 } 770 771 return LLVMStyle; 772 } 773 774 FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { 775 if (Language == FormatStyle::LK_TextProto) { 776 FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto); 777 GoogleStyle.Language = FormatStyle::LK_TextProto; 778 779 return GoogleStyle; 780 } 781 782 FormatStyle GoogleStyle = getLLVMStyle(Language); 783 784 GoogleStyle.AccessModifierOffset = -1; 785 GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left; 786 GoogleStyle.AllowShortIfStatementsOnASingleLine = 787 FormatStyle::SIS_WithoutElse; 788 GoogleStyle.AllowShortLoopsOnASingleLine = true; 789 GoogleStyle.AlwaysBreakBeforeMultilineStrings = true; 790 GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; 791 GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; 792 GoogleStyle.DerivePointerAlignment = true; 793 GoogleStyle.IncludeStyle.IncludeCategories = { 794 {"^<ext/.*\\.h>", 2}, {"^<.*\\.h>", 1}, {"^<.*", 2}, {".*", 3}}; 795 GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$"; 796 GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 797 GoogleStyle.IndentCaseLabels = true; 798 GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false; 799 GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never; 800 GoogleStyle.ObjCSpaceAfterProperty = false; 801 GoogleStyle.ObjCSpaceBeforeProtocolList = true; 802 GoogleStyle.PointerAlignment = FormatStyle::PAS_Left; 803 GoogleStyle.RawStringFormats = { 804 { 805 FormatStyle::LK_Cpp, 806 /*Delimiters=*/ 807 { 808 "cc", 809 "CC", 810 "cpp", 811 "Cpp", 812 "CPP", 813 "c++", 814 "C++", 815 }, 816 /*EnclosingFunctionNames=*/ 817 {}, 818 /*CanonicalDelimiter=*/"", 819 /*BasedOnStyle=*/"google", 820 }, 821 { 822 FormatStyle::LK_TextProto, 823 /*Delimiters=*/ 824 { 825 "pb", 826 "PB", 827 "proto", 828 "PROTO", 829 }, 830 /*EnclosingFunctionNames=*/ 831 { 832 "EqualsProto", 833 "EquivToProto", 834 "PARSE_PARTIAL_TEXT_PROTO", 835 "PARSE_TEST_PROTO", 836 "PARSE_TEXT_PROTO", 837 "ParseTextOrDie", 838 "ParseTextProtoOrDie", 839 }, 840 /*CanonicalDelimiter=*/"", 841 /*BasedOnStyle=*/"google", 842 }, 843 }; 844 GoogleStyle.SpacesBeforeTrailingComments = 2; 845 GoogleStyle.Standard = FormatStyle::LS_Auto; 846 847 GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200; 848 GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1; 849 850 if (Language == FormatStyle::LK_Java) { 851 GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; 852 GoogleStyle.AlignOperands = false; 853 GoogleStyle.AlignTrailingComments = false; 854 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 855 GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 856 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 857 GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; 858 GoogleStyle.ColumnLimit = 100; 859 GoogleStyle.SpaceAfterCStyleCast = true; 860 GoogleStyle.SpacesBeforeTrailingComments = 1; 861 } else if (Language == FormatStyle::LK_JavaScript) { 862 GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; 863 GoogleStyle.AlignOperands = false; 864 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 865 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 866 GoogleStyle.BreakBeforeTernaryOperators = false; 867 // taze:, triple slash directives (`/// <...`), @see, which is commonly 868 // followed by overlong URLs. 869 GoogleStyle.CommentPragmas = "(taze:|^/[ \t]*<|@see)"; 870 GoogleStyle.MaxEmptyLinesToKeep = 3; 871 GoogleStyle.NamespaceIndentation = FormatStyle::NI_All; 872 GoogleStyle.SpacesInContainerLiterals = false; 873 GoogleStyle.JavaScriptQuotes = FormatStyle::JSQS_Single; 874 GoogleStyle.JavaScriptWrapImports = false; 875 } else if (Language == FormatStyle::LK_Proto) { 876 GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; 877 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 878 GoogleStyle.SpacesInContainerLiterals = false; 879 GoogleStyle.Cpp11BracedListStyle = false; 880 // This affects protocol buffer options specifications and text protos. 881 // Text protos are currently mostly formatted inside C++ raw string literals 882 // and often the current breaking behavior of string literals is not 883 // beneficial there. Investigate turning this on once proper string reflow 884 // has been implemented. 885 GoogleStyle.BreakStringLiterals = false; 886 } else if (Language == FormatStyle::LK_ObjC) { 887 GoogleStyle.AlwaysBreakBeforeMultilineStrings = false; 888 GoogleStyle.ColumnLimit = 100; 889 // "Regroup" doesn't work well for ObjC yet (main header heuristic, 890 // relationship between ObjC standard library headers and other heades, 891 // #imports, etc.) 892 GoogleStyle.IncludeStyle.IncludeBlocks = 893 tooling::IncludeStyle::IBS_Preserve; 894 } 895 896 return GoogleStyle; 897 } 898 899 FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) { 900 FormatStyle ChromiumStyle = getGoogleStyle(Language); 901 if (Language == FormatStyle::LK_Java) { 902 ChromiumStyle.AllowShortIfStatementsOnASingleLine = 903 FormatStyle::SIS_WithoutElse; 904 ChromiumStyle.BreakAfterJavaFieldAnnotations = true; 905 ChromiumStyle.ContinuationIndentWidth = 8; 906 ChromiumStyle.IndentWidth = 4; 907 // See styleguide for import groups: 908 // https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/java.md#Import-Order 909 ChromiumStyle.JavaImportGroups = { 910 "android", 911 "androidx", 912 "com", 913 "dalvik", 914 "junit", 915 "org", 916 "com.google.android.apps.chrome", 917 "org.chromium", 918 "java", 919 "javax", 920 }; 921 ChromiumStyle.SortIncludes = true; 922 } else if (Language == FormatStyle::LK_JavaScript) { 923 ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 924 ChromiumStyle.AllowShortLoopsOnASingleLine = false; 925 } else { 926 ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false; 927 ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 928 ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 929 ChromiumStyle.AllowShortLoopsOnASingleLine = false; 930 ChromiumStyle.BinPackParameters = false; 931 ChromiumStyle.DerivePointerAlignment = false; 932 if (Language == FormatStyle::LK_ObjC) 933 ChromiumStyle.ColumnLimit = 80; 934 } 935 return ChromiumStyle; 936 } 937 938 FormatStyle getMozillaStyle() { 939 FormatStyle MozillaStyle = getLLVMStyle(); 940 MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false; 941 MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 942 MozillaStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel; 943 MozillaStyle.AlwaysBreakAfterDefinitionReturnType = 944 FormatStyle::DRTBS_TopLevel; 945 MozillaStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; 946 MozillaStyle.BinPackParameters = false; 947 MozillaStyle.BinPackArguments = false; 948 MozillaStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla; 949 MozillaStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 950 MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma; 951 MozillaStyle.ConstructorInitializerIndentWidth = 2; 952 MozillaStyle.ContinuationIndentWidth = 2; 953 MozillaStyle.Cpp11BracedListStyle = false; 954 MozillaStyle.FixNamespaceComments = false; 955 MozillaStyle.IndentCaseLabels = true; 956 MozillaStyle.ObjCSpaceAfterProperty = true; 957 MozillaStyle.ObjCSpaceBeforeProtocolList = false; 958 MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200; 959 MozillaStyle.PointerAlignment = FormatStyle::PAS_Left; 960 MozillaStyle.SpaceAfterTemplateKeyword = false; 961 return MozillaStyle; 962 } 963 964 FormatStyle getWebKitStyle() { 965 FormatStyle Style = getLLVMStyle(); 966 Style.AccessModifierOffset = -4; 967 Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; 968 Style.AlignOperands = false; 969 Style.AlignTrailingComments = false; 970 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; 971 Style.BreakBeforeBraces = FormatStyle::BS_WebKit; 972 Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; 973 Style.Cpp11BracedListStyle = false; 974 Style.ColumnLimit = 0; 975 Style.FixNamespaceComments = false; 976 Style.IndentWidth = 4; 977 Style.NamespaceIndentation = FormatStyle::NI_Inner; 978 Style.ObjCBlockIndentWidth = 4; 979 Style.ObjCSpaceAfterProperty = true; 980 Style.PointerAlignment = FormatStyle::PAS_Left; 981 Style.SpaceBeforeCpp11BracedList = true; 982 return Style; 983 } 984 985 FormatStyle getGNUStyle() { 986 FormatStyle Style = getLLVMStyle(); 987 Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; 988 Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions; 989 Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; 990 Style.BreakBeforeBraces = FormatStyle::BS_GNU; 991 Style.BreakBeforeTernaryOperators = true; 992 Style.Cpp11BracedListStyle = false; 993 Style.ColumnLimit = 79; 994 Style.FixNamespaceComments = false; 995 Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 996 Style.Standard = FormatStyle::LS_Cpp03; 997 return Style; 998 } 999 1000 FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) { 1001 FormatStyle Style = getLLVMStyle(); 1002 Style.ColumnLimit = 120; 1003 Style.TabWidth = 4; 1004 Style.IndentWidth = 4; 1005 Style.UseTab = FormatStyle::UT_Never; 1006 Style.BreakBeforeBraces = FormatStyle::BS_Custom; 1007 Style.BraceWrapping.AfterClass = true; 1008 Style.BraceWrapping.AfterControlStatement = true; 1009 Style.BraceWrapping.AfterEnum = true; 1010 Style.BraceWrapping.AfterFunction = true; 1011 Style.BraceWrapping.AfterNamespace = true; 1012 Style.BraceWrapping.AfterObjCDeclaration = true; 1013 Style.BraceWrapping.AfterStruct = true; 1014 Style.BraceWrapping.AfterExternBlock = true; 1015 Style.BraceWrapping.BeforeCatch = true; 1016 Style.BraceWrapping.BeforeElse = true; 1017 Style.PenaltyReturnTypeOnItsOwnLine = 1000; 1018 Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; 1019 Style.AllowShortBlocksOnASingleLine = false; 1020 Style.AllowShortCaseLabelsOnASingleLine = false; 1021 Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; 1022 Style.AllowShortLoopsOnASingleLine = false; 1023 return Style; 1024 } 1025 1026 FormatStyle getNoStyle() { 1027 FormatStyle NoStyle = getLLVMStyle(); 1028 NoStyle.DisableFormat = true; 1029 NoStyle.SortIncludes = false; 1030 NoStyle.SortUsingDeclarations = false; 1031 return NoStyle; 1032 } 1033 1034 bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, 1035 FormatStyle *Style) { 1036 if (Name.equals_lower("llvm")) { 1037 *Style = getLLVMStyle(Language); 1038 } else if (Name.equals_lower("chromium")) { 1039 *Style = getChromiumStyle(Language); 1040 } else if (Name.equals_lower("mozilla")) { 1041 *Style = getMozillaStyle(); 1042 } else if (Name.equals_lower("google")) { 1043 *Style = getGoogleStyle(Language); 1044 } else if (Name.equals_lower("webkit")) { 1045 *Style = getWebKitStyle(); 1046 } else if (Name.equals_lower("gnu")) { 1047 *Style = getGNUStyle(); 1048 } else if (Name.equals_lower("microsoft")) { 1049 *Style = getMicrosoftStyle(Language); 1050 } else if (Name.equals_lower("none")) { 1051 *Style = getNoStyle(); 1052 } else { 1053 return false; 1054 } 1055 1056 Style->Language = Language; 1057 return true; 1058 } 1059 1060 std::error_code parseConfiguration(StringRef Text, FormatStyle *Style) { 1061 assert(Style); 1062 FormatStyle::LanguageKind Language = Style->Language; 1063 assert(Language != FormatStyle::LK_None); 1064 if (Text.trim().empty()) 1065 return make_error_code(ParseError::Error); 1066 Style->StyleSet.Clear(); 1067 std::vector<FormatStyle> Styles; 1068 llvm::yaml::Input Input(Text); 1069 // DocumentListTraits<vector<FormatStyle>> uses the context to get default 1070 // values for the fields, keys for which are missing from the configuration. 1071 // Mapping also uses the context to get the language to find the correct 1072 // base style. 1073 Input.setContext(Style); 1074 Input >> Styles; 1075 if (Input.error()) 1076 return Input.error(); 1077 1078 for (unsigned i = 0; i < Styles.size(); ++i) { 1079 // Ensures that only the first configuration can skip the Language option. 1080 if (Styles[i].Language == FormatStyle::LK_None && i != 0) 1081 return make_error_code(ParseError::Error); 1082 // Ensure that each language is configured at most once. 1083 for (unsigned j = 0; j < i; ++j) { 1084 if (Styles[i].Language == Styles[j].Language) { 1085 LLVM_DEBUG(llvm::dbgs() 1086 << "Duplicate languages in the config file on positions " 1087 << j << " and " << i << "\n"); 1088 return make_error_code(ParseError::Error); 1089 } 1090 } 1091 } 1092 // Look for a suitable configuration starting from the end, so we can 1093 // find the configuration for the specific language first, and the default 1094 // configuration (which can only be at slot 0) after it. 1095 FormatStyle::FormatStyleSet StyleSet; 1096 bool LanguageFound = false; 1097 for (int i = Styles.size() - 1; i >= 0; --i) { 1098 if (Styles[i].Language != FormatStyle::LK_None) 1099 StyleSet.Add(Styles[i]); 1100 if (Styles[i].Language == Language) 1101 LanguageFound = true; 1102 } 1103 if (!LanguageFound) { 1104 if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None) 1105 return make_error_code(ParseError::Unsuitable); 1106 FormatStyle DefaultStyle = Styles[0]; 1107 DefaultStyle.Language = Language; 1108 StyleSet.Add(std::move(DefaultStyle)); 1109 } 1110 *Style = *StyleSet.Get(Language); 1111 return make_error_code(ParseError::Success); 1112 } 1113 1114 std::string configurationAsText(const FormatStyle &Style) { 1115 std::string Text; 1116 llvm::raw_string_ostream Stream(Text); 1117 llvm::yaml::Output Output(Stream); 1118 // We use the same mapping method for input and output, so we need a non-const 1119 // reference here. 1120 FormatStyle NonConstStyle = expandPresets(Style); 1121 Output << NonConstStyle; 1122 return Stream.str(); 1123 } 1124 1125 llvm::Optional<FormatStyle> 1126 FormatStyle::FormatStyleSet::Get(FormatStyle::LanguageKind Language) const { 1127 if (!Styles) 1128 return None; 1129 auto It = Styles->find(Language); 1130 if (It == Styles->end()) 1131 return None; 1132 FormatStyle Style = It->second; 1133 Style.StyleSet = *this; 1134 return Style; 1135 } 1136 1137 void FormatStyle::FormatStyleSet::Add(FormatStyle Style) { 1138 assert(Style.Language != LK_None && 1139 "Cannot add a style for LK_None to a StyleSet"); 1140 assert( 1141 !Style.StyleSet.Styles && 1142 "Cannot add a style associated with an existing StyleSet to a StyleSet"); 1143 if (!Styles) 1144 Styles = std::make_shared<MapType>(); 1145 (*Styles)[Style.Language] = std::move(Style); 1146 } 1147 1148 void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); } 1149 1150 llvm::Optional<FormatStyle> 1151 FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const { 1152 return StyleSet.Get(Language); 1153 } 1154 1155 namespace { 1156 1157 class JavaScriptRequoter : public TokenAnalyzer { 1158 public: 1159 JavaScriptRequoter(const Environment &Env, const FormatStyle &Style) 1160 : TokenAnalyzer(Env, Style) {} 1161 1162 std::pair<tooling::Replacements, unsigned> 1163 analyze(TokenAnnotator &Annotator, 1164 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1165 FormatTokenLexer &Tokens) override { 1166 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 1167 tooling::Replacements Result; 1168 requoteJSStringLiteral(AnnotatedLines, Result); 1169 return {Result, 0}; 1170 } 1171 1172 private: 1173 // Replaces double/single-quoted string literal as appropriate, re-escaping 1174 // the contents in the process. 1175 void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines, 1176 tooling::Replacements &Result) { 1177 for (AnnotatedLine *Line : Lines) { 1178 requoteJSStringLiteral(Line->Children, Result); 1179 if (!Line->Affected) 1180 continue; 1181 for (FormatToken *FormatTok = Line->First; FormatTok; 1182 FormatTok = FormatTok->Next) { 1183 StringRef Input = FormatTok->TokenText; 1184 if (FormatTok->Finalized || !FormatTok->isStringLiteral() || 1185 // NB: testing for not starting with a double quote to avoid 1186 // breaking `template strings`. 1187 (Style.JavaScriptQuotes == FormatStyle::JSQS_Single && 1188 !Input.startswith("\"")) || 1189 (Style.JavaScriptQuotes == FormatStyle::JSQS_Double && 1190 !Input.startswith("\'"))) 1191 continue; 1192 1193 // Change start and end quote. 1194 bool IsSingle = Style.JavaScriptQuotes == FormatStyle::JSQS_Single; 1195 SourceLocation Start = FormatTok->Tok.getLocation(); 1196 auto Replace = [&](SourceLocation Start, unsigned Length, 1197 StringRef ReplacementText) { 1198 auto Err = Result.add(tooling::Replacement( 1199 Env.getSourceManager(), Start, Length, ReplacementText)); 1200 // FIXME: handle error. For now, print error message and skip the 1201 // replacement for release version. 1202 if (Err) { 1203 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1204 assert(false); 1205 } 1206 }; 1207 Replace(Start, 1, IsSingle ? "'" : "\""); 1208 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1, 1209 IsSingle ? "'" : "\""); 1210 1211 // Escape internal quotes. 1212 bool Escaped = false; 1213 for (size_t i = 1; i < Input.size() - 1; i++) { 1214 switch (Input[i]) { 1215 case '\\': 1216 if (!Escaped && i + 1 < Input.size() && 1217 ((IsSingle && Input[i + 1] == '"') || 1218 (!IsSingle && Input[i + 1] == '\''))) { 1219 // Remove this \, it's escaping a " or ' that no longer needs 1220 // escaping 1221 Replace(Start.getLocWithOffset(i), 1, ""); 1222 continue; 1223 } 1224 Escaped = !Escaped; 1225 break; 1226 case '\"': 1227 case '\'': 1228 if (!Escaped && IsSingle == (Input[i] == '\'')) { 1229 // Escape the quote. 1230 Replace(Start.getLocWithOffset(i), 0, "\\"); 1231 } 1232 Escaped = false; 1233 break; 1234 default: 1235 Escaped = false; 1236 break; 1237 } 1238 } 1239 } 1240 } 1241 } 1242 }; 1243 1244 class Formatter : public TokenAnalyzer { 1245 public: 1246 Formatter(const Environment &Env, const FormatStyle &Style, 1247 FormattingAttemptStatus *Status) 1248 : TokenAnalyzer(Env, Style), Status(Status) {} 1249 1250 std::pair<tooling::Replacements, unsigned> 1251 analyze(TokenAnnotator &Annotator, 1252 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1253 FormatTokenLexer &Tokens) override { 1254 tooling::Replacements Result; 1255 deriveLocalStyle(AnnotatedLines); 1256 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 1257 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1258 Annotator.calculateFormattingInformation(*AnnotatedLines[i]); 1259 } 1260 Annotator.setCommentLineLevels(AnnotatedLines); 1261 1262 WhitespaceManager Whitespaces( 1263 Env.getSourceManager(), Style, 1264 inputUsesCRLF(Env.getSourceManager().getBufferData(Env.getFileID()))); 1265 ContinuationIndenter Indenter(Style, Tokens.getKeywords(), 1266 Env.getSourceManager(), Whitespaces, Encoding, 1267 BinPackInconclusiveFunctions); 1268 unsigned Penalty = 1269 UnwrappedLineFormatter(&Indenter, &Whitespaces, Style, 1270 Tokens.getKeywords(), Env.getSourceManager(), 1271 Status) 1272 .format(AnnotatedLines, /*DryRun=*/false, 1273 /*AdditionalIndent=*/0, 1274 /*FixBadIndentation=*/false, 1275 /*FirstStartColumn=*/Env.getFirstStartColumn(), 1276 /*NextStartColumn=*/Env.getNextStartColumn(), 1277 /*LastStartColumn=*/Env.getLastStartColumn()); 1278 for (const auto &R : Whitespaces.generateReplacements()) 1279 if (Result.add(R)) 1280 return std::make_pair(Result, 0); 1281 return std::make_pair(Result, Penalty); 1282 } 1283 1284 private: 1285 static bool inputUsesCRLF(StringRef Text) { 1286 return Text.count('\r') * 2 > Text.count('\n'); 1287 } 1288 1289 bool 1290 hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) { 1291 for (const AnnotatedLine *Line : Lines) { 1292 if (hasCpp03IncompatibleFormat(Line->Children)) 1293 return true; 1294 for (FormatToken *Tok = Line->First->Next; Tok; Tok = Tok->Next) { 1295 if (Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) { 1296 if (Tok->is(tok::coloncolon) && Tok->Previous->is(TT_TemplateOpener)) 1297 return true; 1298 if (Tok->is(TT_TemplateCloser) && 1299 Tok->Previous->is(TT_TemplateCloser)) 1300 return true; 1301 } 1302 } 1303 } 1304 return false; 1305 } 1306 1307 int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) { 1308 int AlignmentDiff = 0; 1309 for (const AnnotatedLine *Line : Lines) { 1310 AlignmentDiff += countVariableAlignments(Line->Children); 1311 for (FormatToken *Tok = Line->First; Tok && Tok->Next; Tok = Tok->Next) { 1312 if (!Tok->is(TT_PointerOrReference)) 1313 continue; 1314 bool SpaceBefore = 1315 Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd(); 1316 bool SpaceAfter = Tok->Next->WhitespaceRange.getBegin() != 1317 Tok->Next->WhitespaceRange.getEnd(); 1318 if (SpaceBefore && !SpaceAfter) 1319 ++AlignmentDiff; 1320 if (!SpaceBefore && SpaceAfter) 1321 --AlignmentDiff; 1322 } 1323 } 1324 return AlignmentDiff; 1325 } 1326 1327 void 1328 deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 1329 bool HasBinPackedFunction = false; 1330 bool HasOnePerLineFunction = false; 1331 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1332 if (!AnnotatedLines[i]->First->Next) 1333 continue; 1334 FormatToken *Tok = AnnotatedLines[i]->First->Next; 1335 while (Tok->Next) { 1336 if (Tok->PackingKind == PPK_BinPacked) 1337 HasBinPackedFunction = true; 1338 if (Tok->PackingKind == PPK_OnePerLine) 1339 HasOnePerLineFunction = true; 1340 1341 Tok = Tok->Next; 1342 } 1343 } 1344 if (Style.DerivePointerAlignment) 1345 Style.PointerAlignment = countVariableAlignments(AnnotatedLines) <= 0 1346 ? FormatStyle::PAS_Left 1347 : FormatStyle::PAS_Right; 1348 if (Style.Standard == FormatStyle::LS_Auto) 1349 Style.Standard = hasCpp03IncompatibleFormat(AnnotatedLines) 1350 ? FormatStyle::LS_Cpp11 1351 : FormatStyle::LS_Cpp03; 1352 BinPackInconclusiveFunctions = 1353 HasBinPackedFunction || !HasOnePerLineFunction; 1354 } 1355 1356 bool BinPackInconclusiveFunctions; 1357 FormattingAttemptStatus *Status; 1358 }; 1359 1360 // This class clean up the erroneous/redundant code around the given ranges in 1361 // file. 1362 class Cleaner : public TokenAnalyzer { 1363 public: 1364 Cleaner(const Environment &Env, const FormatStyle &Style) 1365 : TokenAnalyzer(Env, Style), 1366 DeletedTokens(FormatTokenLess(Env.getSourceManager())) {} 1367 1368 // FIXME: eliminate unused parameters. 1369 std::pair<tooling::Replacements, unsigned> 1370 analyze(TokenAnnotator &Annotator, 1371 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1372 FormatTokenLexer &Tokens) override { 1373 // FIXME: in the current implementation the granularity of affected range 1374 // is an annotated line. However, this is not sufficient. Furthermore, 1375 // redundant code introduced by replacements does not necessarily 1376 // intercept with ranges of replacements that result in the redundancy. 1377 // To determine if some redundant code is actually introduced by 1378 // replacements(e.g. deletions), we need to come up with a more 1379 // sophisticated way of computing affected ranges. 1380 AffectedRangeMgr.computeAffectedLines(AnnotatedLines); 1381 1382 checkEmptyNamespace(AnnotatedLines); 1383 1384 for (auto &Line : AnnotatedLines) { 1385 if (Line->Affected) { 1386 cleanupRight(Line->First, tok::comma, tok::comma); 1387 cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma); 1388 cleanupRight(Line->First, tok::l_paren, tok::comma); 1389 cleanupLeft(Line->First, tok::comma, tok::r_paren); 1390 cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace); 1391 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace); 1392 cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal); 1393 } 1394 } 1395 1396 return {generateFixes(), 0}; 1397 } 1398 1399 private: 1400 bool containsOnlyComments(const AnnotatedLine &Line) { 1401 for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next) { 1402 if (Tok->isNot(tok::comment)) 1403 return false; 1404 } 1405 return true; 1406 } 1407 1408 // Iterate through all lines and remove any empty (nested) namespaces. 1409 void checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 1410 std::set<unsigned> DeletedLines; 1411 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1412 auto &Line = *AnnotatedLines[i]; 1413 if (Line.startsWithNamespace()) { 1414 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines); 1415 } 1416 } 1417 1418 for (auto Line : DeletedLines) { 1419 FormatToken *Tok = AnnotatedLines[Line]->First; 1420 while (Tok) { 1421 deleteToken(Tok); 1422 Tok = Tok->Next; 1423 } 1424 } 1425 } 1426 1427 // The function checks if the namespace, which starts from \p CurrentLine, and 1428 // its nested namespaces are empty and delete them if they are empty. It also 1429 // sets \p NewLine to the last line checked. 1430 // Returns true if the current namespace is empty. 1431 bool checkEmptyNamespace(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1432 unsigned CurrentLine, unsigned &NewLine, 1433 std::set<unsigned> &DeletedLines) { 1434 unsigned InitLine = CurrentLine, End = AnnotatedLines.size(); 1435 if (Style.BraceWrapping.AfterNamespace) { 1436 // If the left brace is in a new line, we should consume it first so that 1437 // it does not make the namespace non-empty. 1438 // FIXME: error handling if there is no left brace. 1439 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) { 1440 NewLine = CurrentLine; 1441 return false; 1442 } 1443 } else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) { 1444 return false; 1445 } 1446 while (++CurrentLine < End) { 1447 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace)) 1448 break; 1449 1450 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) { 1451 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine, 1452 DeletedLines)) 1453 return false; 1454 CurrentLine = NewLine; 1455 continue; 1456 } 1457 1458 if (containsOnlyComments(*AnnotatedLines[CurrentLine])) 1459 continue; 1460 1461 // If there is anything other than comments or nested namespaces in the 1462 // current namespace, the namespace cannot be empty. 1463 NewLine = CurrentLine; 1464 return false; 1465 } 1466 1467 NewLine = CurrentLine; 1468 if (CurrentLine >= End) 1469 return false; 1470 1471 // Check if the empty namespace is actually affected by changed ranges. 1472 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange( 1473 AnnotatedLines[InitLine]->First->Tok.getLocation(), 1474 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc()))) 1475 return false; 1476 1477 for (unsigned i = InitLine; i <= CurrentLine; ++i) { 1478 DeletedLines.insert(i); 1479 } 1480 1481 return true; 1482 } 1483 1484 // Checks pairs {start, start->next},..., {end->previous, end} and deletes one 1485 // of the token in the pair if the left token has \p LK token kind and the 1486 // right token has \p RK token kind. If \p DeleteLeft is true, the left token 1487 // is deleted on match; otherwise, the right token is deleted. 1488 template <typename LeftKind, typename RightKind> 1489 void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK, 1490 bool DeleteLeft) { 1491 auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * { 1492 for (auto *Res = Tok.Next; Res; Res = Res->Next) 1493 if (!Res->is(tok::comment) && 1494 DeletedTokens.find(Res) == DeletedTokens.end()) 1495 return Res; 1496 return nullptr; 1497 }; 1498 for (auto *Left = Start; Left;) { 1499 auto *Right = NextNotDeleted(*Left); 1500 if (!Right) 1501 break; 1502 if (Left->is(LK) && Right->is(RK)) { 1503 deleteToken(DeleteLeft ? Left : Right); 1504 for (auto *Tok = Left->Next; Tok && Tok != Right; Tok = Tok->Next) 1505 deleteToken(Tok); 1506 // If the right token is deleted, we should keep the left token 1507 // unchanged and pair it with the new right token. 1508 if (!DeleteLeft) 1509 continue; 1510 } 1511 Left = Right; 1512 } 1513 } 1514 1515 template <typename LeftKind, typename RightKind> 1516 void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) { 1517 cleanupPair(Start, LK, RK, /*DeleteLeft=*/true); 1518 } 1519 1520 template <typename LeftKind, typename RightKind> 1521 void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) { 1522 cleanupPair(Start, LK, RK, /*DeleteLeft=*/false); 1523 } 1524 1525 // Delete the given token. 1526 inline void deleteToken(FormatToken *Tok) { 1527 if (Tok) 1528 DeletedTokens.insert(Tok); 1529 } 1530 1531 tooling::Replacements generateFixes() { 1532 tooling::Replacements Fixes; 1533 std::vector<FormatToken *> Tokens; 1534 std::copy(DeletedTokens.begin(), DeletedTokens.end(), 1535 std::back_inserter(Tokens)); 1536 1537 // Merge multiple continuous token deletions into one big deletion so that 1538 // the number of replacements can be reduced. This makes computing affected 1539 // ranges more efficient when we run reformat on the changed code. 1540 unsigned Idx = 0; 1541 while (Idx < Tokens.size()) { 1542 unsigned St = Idx, End = Idx; 1543 while ((End + 1) < Tokens.size() && 1544 Tokens[End]->Next == Tokens[End + 1]) { 1545 End++; 1546 } 1547 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(), 1548 Tokens[End]->Tok.getEndLoc()); 1549 auto Err = 1550 Fixes.add(tooling::Replacement(Env.getSourceManager(), SR, "")); 1551 // FIXME: better error handling. for now just print error message and skip 1552 // for the release version. 1553 if (Err) { 1554 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1555 assert(false && "Fixes must not conflict!"); 1556 } 1557 Idx = End + 1; 1558 } 1559 1560 return Fixes; 1561 } 1562 1563 // Class for less-than inequality comparason for the set `RedundantTokens`. 1564 // We store tokens in the order they appear in the translation unit so that 1565 // we do not need to sort them in `generateFixes()`. 1566 struct FormatTokenLess { 1567 FormatTokenLess(const SourceManager &SM) : SM(SM) {} 1568 1569 bool operator()(const FormatToken *LHS, const FormatToken *RHS) const { 1570 return SM.isBeforeInTranslationUnit(LHS->Tok.getLocation(), 1571 RHS->Tok.getLocation()); 1572 } 1573 const SourceManager &SM; 1574 }; 1575 1576 // Tokens to be deleted. 1577 std::set<FormatToken *, FormatTokenLess> DeletedTokens; 1578 }; 1579 1580 class ObjCHeaderStyleGuesser : public TokenAnalyzer { 1581 public: 1582 ObjCHeaderStyleGuesser(const Environment &Env, const FormatStyle &Style) 1583 : TokenAnalyzer(Env, Style), IsObjC(false) {} 1584 1585 std::pair<tooling::Replacements, unsigned> 1586 analyze(TokenAnnotator &Annotator, 1587 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1588 FormatTokenLexer &Tokens) override { 1589 assert(Style.Language == FormatStyle::LK_Cpp); 1590 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines, 1591 Tokens.getKeywords()); 1592 tooling::Replacements Result; 1593 return {Result, 0}; 1594 } 1595 1596 bool isObjC() { return IsObjC; } 1597 1598 private: 1599 static bool 1600 guessIsObjC(const SourceManager &SourceManager, 1601 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1602 const AdditionalKeywords &Keywords) { 1603 // Keep this array sorted, since we are binary searching over it. 1604 static constexpr llvm::StringLiteral FoundationIdentifiers[] = { 1605 "CGFloat", 1606 "CGPoint", 1607 "CGPointMake", 1608 "CGPointZero", 1609 "CGRect", 1610 "CGRectEdge", 1611 "CGRectInfinite", 1612 "CGRectMake", 1613 "CGRectNull", 1614 "CGRectZero", 1615 "CGSize", 1616 "CGSizeMake", 1617 "CGVector", 1618 "CGVectorMake", 1619 "NSAffineTransform", 1620 "NSArray", 1621 "NSAttributedString", 1622 "NSBlockOperation", 1623 "NSBundle", 1624 "NSCache", 1625 "NSCalendar", 1626 "NSCharacterSet", 1627 "NSCountedSet", 1628 "NSData", 1629 "NSDataDetector", 1630 "NSDecimal", 1631 "NSDecimalNumber", 1632 "NSDictionary", 1633 "NSEdgeInsets", 1634 "NSHashTable", 1635 "NSIndexPath", 1636 "NSIndexSet", 1637 "NSInteger", 1638 "NSInvocationOperation", 1639 "NSLocale", 1640 "NSMapTable", 1641 "NSMutableArray", 1642 "NSMutableAttributedString", 1643 "NSMutableCharacterSet", 1644 "NSMutableData", 1645 "NSMutableDictionary", 1646 "NSMutableIndexSet", 1647 "NSMutableOrderedSet", 1648 "NSMutableSet", 1649 "NSMutableString", 1650 "NSNumber", 1651 "NSNumberFormatter", 1652 "NSObject", 1653 "NSOperation", 1654 "NSOperationQueue", 1655 "NSOperationQueuePriority", 1656 "NSOrderedSet", 1657 "NSPoint", 1658 "NSPointerArray", 1659 "NSQualityOfService", 1660 "NSRange", 1661 "NSRect", 1662 "NSRegularExpression", 1663 "NSSet", 1664 "NSSize", 1665 "NSString", 1666 "NSTimeZone", 1667 "NSUInteger", 1668 "NSURL", 1669 "NSURLComponents", 1670 "NSURLQueryItem", 1671 "NSUUID", 1672 "NSValue", 1673 "UIImage", 1674 "UIView", 1675 }; 1676 1677 for (auto Line : AnnotatedLines) { 1678 for (const FormatToken *FormatTok = Line->First; FormatTok; 1679 FormatTok = FormatTok->Next) { 1680 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) && 1681 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword || 1682 FormatTok->isOneOf(tok::numeric_constant, tok::l_square, 1683 tok::l_brace))) || 1684 (FormatTok->Tok.isAnyIdentifier() && 1685 std::binary_search(std::begin(FoundationIdentifiers), 1686 std::end(FoundationIdentifiers), 1687 FormatTok->TokenText)) || 1688 FormatTok->is(TT_ObjCStringLiteral) || 1689 FormatTok->isOneOf(Keywords.kw_NS_CLOSED_ENUM, Keywords.kw_NS_ENUM, 1690 Keywords.kw_NS_OPTIONS, TT_ObjCBlockLBrace, 1691 TT_ObjCBlockLParen, TT_ObjCDecl, TT_ObjCForIn, 1692 TT_ObjCMethodExpr, TT_ObjCMethodSpecifier, 1693 TT_ObjCProperty)) { 1694 LLVM_DEBUG(llvm::dbgs() 1695 << "Detected ObjC at location " 1696 << FormatTok->Tok.getLocation().printToString( 1697 SourceManager) 1698 << " token: " << FormatTok->TokenText << " token type: " 1699 << getTokenTypeName(FormatTok->Type) << "\n"); 1700 return true; 1701 } 1702 if (guessIsObjC(SourceManager, Line->Children, Keywords)) 1703 return true; 1704 } 1705 } 1706 return false; 1707 } 1708 1709 bool IsObjC; 1710 }; 1711 1712 struct IncludeDirective { 1713 StringRef Filename; 1714 StringRef Text; 1715 unsigned Offset; 1716 int Category; 1717 }; 1718 1719 struct JavaImportDirective { 1720 StringRef Identifier; 1721 StringRef Text; 1722 unsigned Offset; 1723 std::vector<StringRef> AssociatedCommentLines; 1724 bool IsStatic; 1725 }; 1726 1727 } // end anonymous namespace 1728 1729 // Determines whether 'Ranges' intersects with ('Start', 'End'). 1730 static bool affectsRange(ArrayRef<tooling::Range> Ranges, unsigned Start, 1731 unsigned End) { 1732 for (auto Range : Ranges) { 1733 if (Range.getOffset() < End && 1734 Range.getOffset() + Range.getLength() > Start) 1735 return true; 1736 } 1737 return false; 1738 } 1739 1740 // Returns a pair (Index, OffsetToEOL) describing the position of the cursor 1741 // before sorting/deduplicating. Index is the index of the include under the 1742 // cursor in the original set of includes. If this include has duplicates, it is 1743 // the index of the first of the duplicates as the others are going to be 1744 // removed. OffsetToEOL describes the cursor's position relative to the end of 1745 // its current line. 1746 // If `Cursor` is not on any #include, `Index` will be UINT_MAX. 1747 static std::pair<unsigned, unsigned> 1748 FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes, 1749 const SmallVectorImpl<unsigned> &Indices, unsigned Cursor) { 1750 unsigned CursorIndex = UINT_MAX; 1751 unsigned OffsetToEOL = 0; 1752 for (int i = 0, e = Includes.size(); i != e; ++i) { 1753 unsigned Start = Includes[Indices[i]].Offset; 1754 unsigned End = Start + Includes[Indices[i]].Text.size(); 1755 if (!(Cursor >= Start && Cursor < End)) 1756 continue; 1757 CursorIndex = Indices[i]; 1758 OffsetToEOL = End - Cursor; 1759 // Put the cursor on the only remaining #include among the duplicate 1760 // #includes. 1761 while (--i >= 0 && Includes[CursorIndex].Text == Includes[Indices[i]].Text) 1762 CursorIndex = i; 1763 break; 1764 } 1765 return std::make_pair(CursorIndex, OffsetToEOL); 1766 } 1767 1768 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically 1769 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict 1770 // source order. 1771 // #include directives with the same text will be deduplicated, and only the 1772 // first #include in the duplicate #includes remains. If the `Cursor` is 1773 // provided and put on a deleted #include, it will be moved to the remaining 1774 // #include in the duplicate #includes. 1775 static void sortCppIncludes(const FormatStyle &Style, 1776 const SmallVectorImpl<IncludeDirective> &Includes, 1777 ArrayRef<tooling::Range> Ranges, StringRef FileName, 1778 StringRef Code, tooling::Replacements &Replaces, 1779 unsigned *Cursor) { 1780 unsigned IncludesBeginOffset = Includes.front().Offset; 1781 unsigned IncludesEndOffset = 1782 Includes.back().Offset + Includes.back().Text.size(); 1783 unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset; 1784 if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset)) 1785 return; 1786 SmallVector<unsigned, 16> Indices; 1787 for (unsigned i = 0, e = Includes.size(); i != e; ++i) 1788 Indices.push_back(i); 1789 llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) { 1790 return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) < 1791 std::tie(Includes[RHSI].Category, Includes[RHSI].Filename); 1792 }); 1793 // The index of the include on which the cursor will be put after 1794 // sorting/deduplicating. 1795 unsigned CursorIndex; 1796 // The offset from cursor to the end of line. 1797 unsigned CursorToEOLOffset; 1798 if (Cursor) 1799 std::tie(CursorIndex, CursorToEOLOffset) = 1800 FindCursorIndex(Includes, Indices, *Cursor); 1801 1802 // Deduplicate #includes. 1803 Indices.erase(std::unique(Indices.begin(), Indices.end(), 1804 [&](unsigned LHSI, unsigned RHSI) { 1805 return Includes[LHSI].Text == Includes[RHSI].Text; 1806 }), 1807 Indices.end()); 1808 1809 int CurrentCategory = Includes.front().Category; 1810 1811 // If the #includes are out of order, we generate a single replacement fixing 1812 // the entire block. Otherwise, no replacement is generated. 1813 // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not 1814 // enough as additional newlines might be added or removed across #include 1815 // blocks. This we handle below by generating the updated #imclude blocks and 1816 // comparing it to the original. 1817 if (Indices.size() == Includes.size() && 1818 std::is_sorted(Indices.begin(), Indices.end()) && 1819 Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve) 1820 return; 1821 1822 std::string result; 1823 for (unsigned Index : Indices) { 1824 if (!result.empty()) { 1825 result += "\n"; 1826 if (Style.IncludeStyle.IncludeBlocks == 1827 tooling::IncludeStyle::IBS_Regroup && 1828 CurrentCategory != Includes[Index].Category) 1829 result += "\n"; 1830 } 1831 result += Includes[Index].Text; 1832 if (Cursor && CursorIndex == Index) 1833 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset; 1834 CurrentCategory = Includes[Index].Category; 1835 } 1836 1837 // If the #includes are out of order, we generate a single replacement fixing 1838 // the entire range of blocks. Otherwise, no replacement is generated. 1839 if (result == Code.substr(IncludesBeginOffset, IncludesBlockSize)) 1840 return; 1841 1842 auto Err = Replaces.add(tooling::Replacement( 1843 FileName, Includes.front().Offset, IncludesBlockSize, result)); 1844 // FIXME: better error handling. For now, just skip the replacement for the 1845 // release version. 1846 if (Err) { 1847 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 1848 assert(false); 1849 } 1850 } 1851 1852 namespace { 1853 1854 const char CppIncludeRegexPattern[] = 1855 R"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))"; 1856 1857 } // anonymous namespace 1858 1859 tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code, 1860 ArrayRef<tooling::Range> Ranges, 1861 StringRef FileName, 1862 tooling::Replacements &Replaces, 1863 unsigned *Cursor) { 1864 unsigned Prev = 0; 1865 unsigned SearchFrom = 0; 1866 llvm::Regex IncludeRegex(CppIncludeRegexPattern); 1867 SmallVector<StringRef, 4> Matches; 1868 SmallVector<IncludeDirective, 16> IncludesInBlock; 1869 1870 // In compiled files, consider the first #include to be the main #include of 1871 // the file if it is not a system #include. This ensures that the header 1872 // doesn't have hidden dependencies 1873 // (http://llvm.org/docs/CodingStandards.html#include-style). 1874 // 1875 // FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix 1876 // cases where the first #include is unlikely to be the main header. 1877 tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName); 1878 bool FirstIncludeBlock = true; 1879 bool MainIncludeFound = false; 1880 bool FormattingOff = false; 1881 1882 for (;;) { 1883 auto Pos = Code.find('\n', SearchFrom); 1884 StringRef Line = 1885 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); 1886 1887 StringRef Trimmed = Line.trim(); 1888 if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */") 1889 FormattingOff = true; 1890 else if (Trimmed == "// clang-format on" || 1891 Trimmed == "/* clang-format on */") 1892 FormattingOff = false; 1893 1894 const bool EmptyLineSkipped = 1895 Trimmed.empty() && 1896 (Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Merge || 1897 Style.IncludeStyle.IncludeBlocks == 1898 tooling::IncludeStyle::IBS_Regroup); 1899 1900 if (!FormattingOff && !Line.endswith("\\")) { 1901 if (IncludeRegex.match(Line, &Matches)) { 1902 StringRef IncludeName = Matches[2]; 1903 int Category = Categories.getIncludePriority( 1904 IncludeName, 1905 /*CheckMainHeader=*/!MainIncludeFound && FirstIncludeBlock); 1906 if (Category == 0) 1907 MainIncludeFound = true; 1908 IncludesInBlock.push_back({IncludeName, Line, Prev, Category}); 1909 } else if (!IncludesInBlock.empty() && !EmptyLineSkipped) { 1910 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, 1911 Replaces, Cursor); 1912 IncludesInBlock.clear(); 1913 FirstIncludeBlock = false; 1914 } 1915 Prev = Pos + 1; 1916 } 1917 if (Pos == StringRef::npos || Pos + 1 == Code.size()) 1918 break; 1919 SearchFrom = Pos + 1; 1920 } 1921 if (!IncludesInBlock.empty()) { 1922 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces, 1923 Cursor); 1924 } 1925 return Replaces; 1926 } 1927 1928 // Returns group number to use as a first order sort on imports. Gives UINT_MAX 1929 // if the import does not match any given groups. 1930 static unsigned findJavaImportGroup(const FormatStyle &Style, 1931 StringRef ImportIdentifier) { 1932 unsigned LongestMatchIndex = UINT_MAX; 1933 unsigned LongestMatchLength = 0; 1934 for (unsigned I = 0; I < Style.JavaImportGroups.size(); I++) { 1935 std::string GroupPrefix = Style.JavaImportGroups[I]; 1936 if (ImportIdentifier.startswith(GroupPrefix) && 1937 GroupPrefix.length() > LongestMatchLength) { 1938 LongestMatchIndex = I; 1939 LongestMatchLength = GroupPrefix.length(); 1940 } 1941 } 1942 return LongestMatchIndex; 1943 } 1944 1945 // Sorts and deduplicates a block of includes given by 'Imports' based on 1946 // JavaImportGroups, then adding the necessary replacement to 'Replaces'. 1947 // Import declarations with the same text will be deduplicated. Between each 1948 // import group, a newline is inserted, and within each import group, a 1949 // lexicographic sort based on ASCII value is performed. 1950 static void sortJavaImports(const FormatStyle &Style, 1951 const SmallVectorImpl<JavaImportDirective> &Imports, 1952 ArrayRef<tooling::Range> Ranges, StringRef FileName, 1953 StringRef Code, tooling::Replacements &Replaces) { 1954 unsigned ImportsBeginOffset = Imports.front().Offset; 1955 unsigned ImportsEndOffset = 1956 Imports.back().Offset + Imports.back().Text.size(); 1957 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset; 1958 if (!affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset)) 1959 return; 1960 SmallVector<unsigned, 16> Indices; 1961 SmallVector<unsigned, 16> JavaImportGroups; 1962 for (unsigned i = 0, e = Imports.size(); i != e; ++i) { 1963 Indices.push_back(i); 1964 JavaImportGroups.push_back( 1965 findJavaImportGroup(Style, Imports[i].Identifier)); 1966 } 1967 llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) { 1968 // Negating IsStatic to push static imports above non-static imports. 1969 return std::make_tuple(!Imports[LHSI].IsStatic, JavaImportGroups[LHSI], 1970 Imports[LHSI].Identifier) < 1971 std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI], 1972 Imports[RHSI].Identifier); 1973 }); 1974 1975 // Deduplicate imports. 1976 Indices.erase(std::unique(Indices.begin(), Indices.end(), 1977 [&](unsigned LHSI, unsigned RHSI) { 1978 return Imports[LHSI].Text == Imports[RHSI].Text; 1979 }), 1980 Indices.end()); 1981 1982 bool CurrentIsStatic = Imports[Indices.front()].IsStatic; 1983 unsigned CurrentImportGroup = JavaImportGroups[Indices.front()]; 1984 1985 std::string result; 1986 for (unsigned Index : Indices) { 1987 if (!result.empty()) { 1988 result += "\n"; 1989 if (CurrentIsStatic != Imports[Index].IsStatic || 1990 CurrentImportGroup != JavaImportGroups[Index]) 1991 result += "\n"; 1992 } 1993 for (StringRef CommentLine : Imports[Index].AssociatedCommentLines) { 1994 result += CommentLine; 1995 result += "\n"; 1996 } 1997 result += Imports[Index].Text; 1998 CurrentIsStatic = Imports[Index].IsStatic; 1999 CurrentImportGroup = JavaImportGroups[Index]; 2000 } 2001 2002 // If the imports are out of order, we generate a single replacement fixing 2003 // the entire block. Otherwise, no replacement is generated. 2004 if (result == Code.substr(Imports.front().Offset, ImportsBlockSize)) 2005 return; 2006 2007 auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset, 2008 ImportsBlockSize, result)); 2009 // FIXME: better error handling. For now, just skip the replacement for the 2010 // release version. 2011 if (Err) { 2012 llvm::errs() << llvm::toString(std::move(Err)) << "\n"; 2013 assert(false); 2014 } 2015 } 2016 2017 namespace { 2018 2019 const char JavaImportRegexPattern[] = 2020 "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;"; 2021 2022 } // anonymous namespace 2023 2024 tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code, 2025 ArrayRef<tooling::Range> Ranges, 2026 StringRef FileName, 2027 tooling::Replacements &Replaces) { 2028 unsigned Prev = 0; 2029 unsigned SearchFrom = 0; 2030 llvm::Regex ImportRegex(JavaImportRegexPattern); 2031 SmallVector<StringRef, 4> Matches; 2032 SmallVector<JavaImportDirective, 16> ImportsInBlock; 2033 std::vector<StringRef> AssociatedCommentLines; 2034 2035 bool FormattingOff = false; 2036 2037 for (;;) { 2038 auto Pos = Code.find('\n', SearchFrom); 2039 StringRef Line = 2040 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); 2041 2042 StringRef Trimmed = Line.trim(); 2043 if (Trimmed == "// clang-format off") 2044 FormattingOff = true; 2045 else if (Trimmed == "// clang-format on") 2046 FormattingOff = false; 2047 2048 if (ImportRegex.match(Line, &Matches)) { 2049 if (FormattingOff) { 2050 // If at least one import line has formatting turned off, turn off 2051 // formatting entirely. 2052 return Replaces; 2053 } 2054 StringRef Static = Matches[1]; 2055 StringRef Identifier = Matches[2]; 2056 bool IsStatic = false; 2057 if (Static.contains("static")) { 2058 IsStatic = true; 2059 } 2060 ImportsInBlock.push_back( 2061 {Identifier, Line, Prev, AssociatedCommentLines, IsStatic}); 2062 AssociatedCommentLines.clear(); 2063 } else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) { 2064 // Associating comments within the imports with the nearest import below 2065 AssociatedCommentLines.push_back(Line); 2066 } 2067 Prev = Pos + 1; 2068 if (Pos == StringRef::npos || Pos + 1 == Code.size()) 2069 break; 2070 SearchFrom = Pos + 1; 2071 } 2072 if (!ImportsInBlock.empty()) 2073 sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces); 2074 return Replaces; 2075 } 2076 2077 bool isMpegTS(StringRef Code) { 2078 // MPEG transport streams use the ".ts" file extension. clang-format should 2079 // not attempt to format those. MPEG TS' frame format starts with 0x47 every 2080 // 189 bytes - detect that and return. 2081 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47; 2082 } 2083 2084 bool isLikelyXml(StringRef Code) { return Code.ltrim().startswith("<"); } 2085 2086 tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, 2087 ArrayRef<tooling::Range> Ranges, 2088 StringRef FileName, unsigned *Cursor) { 2089 tooling::Replacements Replaces; 2090 if (!Style.SortIncludes) 2091 return Replaces; 2092 if (isLikelyXml(Code)) 2093 return Replaces; 2094 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript && 2095 isMpegTS(Code)) 2096 return Replaces; 2097 if (Style.Language == FormatStyle::LanguageKind::LK_JavaScript) 2098 return sortJavaScriptImports(Style, Code, Ranges, FileName); 2099 if (Style.Language == FormatStyle::LanguageKind::LK_Java) 2100 return sortJavaImports(Style, Code, Ranges, FileName, Replaces); 2101 sortCppIncludes(Style, Code, Ranges, FileName, Replaces, Cursor); 2102 return Replaces; 2103 } 2104 2105 template <typename T> 2106 static llvm::Expected<tooling::Replacements> 2107 processReplacements(T ProcessFunc, StringRef Code, 2108 const tooling::Replacements &Replaces, 2109 const FormatStyle &Style) { 2110 if (Replaces.empty()) 2111 return tooling::Replacements(); 2112 2113 auto NewCode = applyAllReplacements(Code, Replaces); 2114 if (!NewCode) 2115 return NewCode.takeError(); 2116 std::vector<tooling::Range> ChangedRanges = Replaces.getAffectedRanges(); 2117 StringRef FileName = Replaces.begin()->getFilePath(); 2118 2119 tooling::Replacements FormatReplaces = 2120 ProcessFunc(Style, *NewCode, ChangedRanges, FileName); 2121 2122 return Replaces.merge(FormatReplaces); 2123 } 2124 2125 llvm::Expected<tooling::Replacements> 2126 formatReplacements(StringRef Code, const tooling::Replacements &Replaces, 2127 const FormatStyle &Style) { 2128 // We need to use lambda function here since there are two versions of 2129 // `sortIncludes`. 2130 auto SortIncludes = [](const FormatStyle &Style, StringRef Code, 2131 std::vector<tooling::Range> Ranges, 2132 StringRef FileName) -> tooling::Replacements { 2133 return sortIncludes(Style, Code, Ranges, FileName); 2134 }; 2135 auto SortedReplaces = 2136 processReplacements(SortIncludes, Code, Replaces, Style); 2137 if (!SortedReplaces) 2138 return SortedReplaces.takeError(); 2139 2140 // We need to use lambda function here since there are two versions of 2141 // `reformat`. 2142 auto Reformat = [](const FormatStyle &Style, StringRef Code, 2143 std::vector<tooling::Range> Ranges, 2144 StringRef FileName) -> tooling::Replacements { 2145 return reformat(Style, Code, Ranges, FileName); 2146 }; 2147 return processReplacements(Reformat, Code, *SortedReplaces, Style); 2148 } 2149 2150 namespace { 2151 2152 inline bool isHeaderInsertion(const tooling::Replacement &Replace) { 2153 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 0 && 2154 llvm::Regex(CppIncludeRegexPattern) 2155 .match(Replace.getReplacementText()); 2156 } 2157 2158 inline bool isHeaderDeletion(const tooling::Replacement &Replace) { 2159 return Replace.getOffset() == UINT_MAX && Replace.getLength() == 1; 2160 } 2161 2162 // FIXME: insert empty lines between newly created blocks. 2163 tooling::Replacements 2164 fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, 2165 const FormatStyle &Style) { 2166 if (!Style.isCpp()) 2167 return Replaces; 2168 2169 tooling::Replacements HeaderInsertions; 2170 std::set<llvm::StringRef> HeadersToDelete; 2171 tooling::Replacements Result; 2172 for (const auto &R : Replaces) { 2173 if (isHeaderInsertion(R)) { 2174 // Replacements from \p Replaces must be conflict-free already, so we can 2175 // simply consume the error. 2176 llvm::consumeError(HeaderInsertions.add(R)); 2177 } else if (isHeaderDeletion(R)) { 2178 HeadersToDelete.insert(R.getReplacementText()); 2179 } else if (R.getOffset() == UINT_MAX) { 2180 llvm::errs() << "Insertions other than header #include insertion are " 2181 "not supported! " 2182 << R.getReplacementText() << "\n"; 2183 } else { 2184 llvm::consumeError(Result.add(R)); 2185 } 2186 } 2187 if (HeaderInsertions.empty() && HeadersToDelete.empty()) 2188 return Replaces; 2189 2190 StringRef FileName = Replaces.begin()->getFilePath(); 2191 tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle); 2192 2193 for (const auto &Header : HeadersToDelete) { 2194 tooling::Replacements Replaces = 2195 Includes.remove(Header.trim("\"<>"), Header.startswith("<")); 2196 for (const auto &R : Replaces) { 2197 auto Err = Result.add(R); 2198 if (Err) { 2199 // Ignore the deletion on conflict. 2200 llvm::errs() << "Failed to add header deletion replacement for " 2201 << Header << ": " << llvm::toString(std::move(Err)) 2202 << "\n"; 2203 } 2204 } 2205 } 2206 2207 llvm::Regex IncludeRegex = llvm::Regex(CppIncludeRegexPattern); 2208 llvm::SmallVector<StringRef, 4> Matches; 2209 for (const auto &R : HeaderInsertions) { 2210 auto IncludeDirective = R.getReplacementText(); 2211 bool Matched = IncludeRegex.match(IncludeDirective, &Matches); 2212 assert(Matched && "Header insertion replacement must have replacement text " 2213 "'#include ...'"); 2214 (void)Matched; 2215 auto IncludeName = Matches[2]; 2216 auto Replace = 2217 Includes.insert(IncludeName.trim("\"<>"), IncludeName.startswith("<")); 2218 if (Replace) { 2219 auto Err = Result.add(*Replace); 2220 if (Err) { 2221 llvm::consumeError(std::move(Err)); 2222 unsigned NewOffset = 2223 Result.getShiftedCodePosition(Replace->getOffset()); 2224 auto Shifted = tooling::Replacement(FileName, NewOffset, 0, 2225 Replace->getReplacementText()); 2226 Result = Result.merge(tooling::Replacements(Shifted)); 2227 } 2228 } 2229 } 2230 return Result; 2231 } 2232 2233 } // anonymous namespace 2234 2235 llvm::Expected<tooling::Replacements> 2236 cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces, 2237 const FormatStyle &Style) { 2238 // We need to use lambda function here since there are two versions of 2239 // `cleanup`. 2240 auto Cleanup = [](const FormatStyle &Style, StringRef Code, 2241 std::vector<tooling::Range> Ranges, 2242 StringRef FileName) -> tooling::Replacements { 2243 return cleanup(Style, Code, Ranges, FileName); 2244 }; 2245 // Make header insertion replacements insert new headers into correct blocks. 2246 tooling::Replacements NewReplaces = 2247 fixCppIncludeInsertions(Code, Replaces, Style); 2248 return processReplacements(Cleanup, Code, NewReplaces, Style); 2249 } 2250 2251 namespace internal { 2252 std::pair<tooling::Replacements, unsigned> 2253 reformat(const FormatStyle &Style, StringRef Code, 2254 ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn, 2255 unsigned NextStartColumn, unsigned LastStartColumn, StringRef FileName, 2256 FormattingAttemptStatus *Status) { 2257 FormatStyle Expanded = expandPresets(Style); 2258 if (Expanded.DisableFormat) 2259 return {tooling::Replacements(), 0}; 2260 if (isLikelyXml(Code)) 2261 return {tooling::Replacements(), 0}; 2262 if (Expanded.Language == FormatStyle::LK_JavaScript && isMpegTS(Code)) 2263 return {tooling::Replacements(), 0}; 2264 2265 typedef std::function<std::pair<tooling::Replacements, unsigned>( 2266 const Environment &)> 2267 AnalyzerPass; 2268 SmallVector<AnalyzerPass, 4> Passes; 2269 2270 if (Style.Language == FormatStyle::LK_Cpp) { 2271 if (Style.FixNamespaceComments) 2272 Passes.emplace_back([&](const Environment &Env) { 2273 return NamespaceEndCommentsFixer(Env, Expanded).process(); 2274 }); 2275 2276 if (Style.SortUsingDeclarations) 2277 Passes.emplace_back([&](const Environment &Env) { 2278 return UsingDeclarationsSorter(Env, Expanded).process(); 2279 }); 2280 } 2281 2282 if (Style.Language == FormatStyle::LK_JavaScript && 2283 Style.JavaScriptQuotes != FormatStyle::JSQS_Leave) 2284 Passes.emplace_back([&](const Environment &Env) { 2285 return JavaScriptRequoter(Env, Expanded).process(); 2286 }); 2287 2288 Passes.emplace_back([&](const Environment &Env) { 2289 return Formatter(Env, Expanded, Status).process(); 2290 }); 2291 2292 auto Env = 2293 llvm::make_unique<Environment>(Code, FileName, Ranges, FirstStartColumn, 2294 NextStartColumn, LastStartColumn); 2295 llvm::Optional<std::string> CurrentCode = None; 2296 tooling::Replacements Fixes; 2297 unsigned Penalty = 0; 2298 for (size_t I = 0, E = Passes.size(); I < E; ++I) { 2299 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env); 2300 auto NewCode = applyAllReplacements( 2301 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first); 2302 if (NewCode) { 2303 Fixes = Fixes.merge(PassFixes.first); 2304 Penalty += PassFixes.second; 2305 if (I + 1 < E) { 2306 CurrentCode = std::move(*NewCode); 2307 Env = llvm::make_unique<Environment>( 2308 *CurrentCode, FileName, 2309 tooling::calculateRangesAfterReplacements(Fixes, Ranges), 2310 FirstStartColumn, NextStartColumn, LastStartColumn); 2311 } 2312 } 2313 } 2314 2315 return {Fixes, Penalty}; 2316 } 2317 } // namespace internal 2318 2319 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 2320 ArrayRef<tooling::Range> Ranges, 2321 StringRef FileName, 2322 FormattingAttemptStatus *Status) { 2323 return internal::reformat(Style, Code, Ranges, 2324 /*FirstStartColumn=*/0, 2325 /*NextStartColumn=*/0, 2326 /*LastStartColumn=*/0, FileName, Status) 2327 .first; 2328 } 2329 2330 tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, 2331 ArrayRef<tooling::Range> Ranges, 2332 StringRef FileName) { 2333 // cleanups only apply to C++ (they mostly concern ctor commas etc.) 2334 if (Style.Language != FormatStyle::LK_Cpp) 2335 return tooling::Replacements(); 2336 return Cleaner(Environment(Code, FileName, Ranges), Style).process().first; 2337 } 2338 2339 tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 2340 ArrayRef<tooling::Range> Ranges, 2341 StringRef FileName, bool *IncompleteFormat) { 2342 FormattingAttemptStatus Status; 2343 auto Result = reformat(Style, Code, Ranges, FileName, &Status); 2344 if (!Status.FormatComplete) 2345 *IncompleteFormat = true; 2346 return Result; 2347 } 2348 2349 tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style, 2350 StringRef Code, 2351 ArrayRef<tooling::Range> Ranges, 2352 StringRef FileName) { 2353 return NamespaceEndCommentsFixer(Environment(Code, FileName, Ranges), Style) 2354 .process() 2355 .first; 2356 } 2357 2358 tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, 2359 StringRef Code, 2360 ArrayRef<tooling::Range> Ranges, 2361 StringRef FileName) { 2362 return UsingDeclarationsSorter(Environment(Code, FileName, Ranges), Style) 2363 .process() 2364 .first; 2365 } 2366 2367 LangOptions getFormattingLangOpts(const FormatStyle &Style) { 2368 LangOptions LangOpts; 2369 FormatStyle::LanguageStandard LexingStd = 2370 Style.Standard == FormatStyle::LS_Auto ? FormatStyle::LS_Cpp11 2371 : Style.Standard; 2372 LangOpts.CPlusPlus = 1; 2373 LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11; 2374 LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp11; 2375 LangOpts.CPlusPlus17 = LexingStd >= FormatStyle::LS_Cpp11; 2376 LangOpts.CPlusPlus2a = LexingStd >= FormatStyle::LS_Cpp11; 2377 LangOpts.LineComment = 1; 2378 bool AlternativeOperators = Style.isCpp(); 2379 LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0; 2380 LangOpts.Bool = 1; 2381 LangOpts.ObjC = 1; 2382 LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally. 2383 LangOpts.DeclSpecKeyword = 1; // To get __declspec. 2384 return LangOpts; 2385 } 2386 2387 const char *StyleOptionHelpDescription = 2388 "Coding style, currently supports:\n" 2389 " LLVM, Google, Chromium, Mozilla, WebKit.\n" 2390 "Use -style=file to load style configuration from\n" 2391 ".clang-format file located in one of the parent\n" 2392 "directories of the source file (or current\n" 2393 "directory for stdin).\n" 2394 "Use -style=\"{key: value, ...}\" to set specific\n" 2395 "parameters, e.g.:\n" 2396 " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\""; 2397 2398 static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) { 2399 if (FileName.endswith(".java")) 2400 return FormatStyle::LK_Java; 2401 if (FileName.endswith_lower(".js") || FileName.endswith_lower(".ts")) 2402 return FormatStyle::LK_JavaScript; // JavaScript or TypeScript. 2403 if (FileName.endswith(".m") || FileName.endswith(".mm")) 2404 return FormatStyle::LK_ObjC; 2405 if (FileName.endswith_lower(".proto") || 2406 FileName.endswith_lower(".protodevel")) 2407 return FormatStyle::LK_Proto; 2408 if (FileName.endswith_lower(".textpb") || 2409 FileName.endswith_lower(".pb.txt") || 2410 FileName.endswith_lower(".textproto") || 2411 FileName.endswith_lower(".asciipb")) 2412 return FormatStyle::LK_TextProto; 2413 if (FileName.endswith_lower(".td")) 2414 return FormatStyle::LK_TableGen; 2415 if (FileName.endswith_lower(".cs")) 2416 return FormatStyle::LK_CSharp; 2417 return FormatStyle::LK_Cpp; 2418 } 2419 2420 FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) { 2421 const auto GuessedLanguage = getLanguageByFileName(FileName); 2422 if (GuessedLanguage == FormatStyle::LK_Cpp) { 2423 auto Extension = llvm::sys::path::extension(FileName); 2424 // If there's no file extension (or it's .h), we need to check the contents 2425 // of the code to see if it contains Objective-C. 2426 if (Extension.empty() || Extension == ".h") { 2427 auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName; 2428 Environment Env(Code, NonEmptyFileName, /*Ranges=*/{}); 2429 ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle()); 2430 Guesser.process(); 2431 if (Guesser.isObjC()) 2432 return FormatStyle::LK_ObjC; 2433 } 2434 } 2435 return GuessedLanguage; 2436 } 2437 2438 const char *DefaultFormatStyle = "file"; 2439 2440 const char *DefaultFallbackStyle = "LLVM"; 2441 2442 llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName, 2443 StringRef FallbackStyleName, 2444 StringRef Code, 2445 llvm::vfs::FileSystem *FS) { 2446 if (!FS) { 2447 FS = llvm::vfs::getRealFileSystem().get(); 2448 } 2449 FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code)); 2450 2451 FormatStyle FallbackStyle = getNoStyle(); 2452 if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle)) 2453 return make_string_error("Invalid fallback style \"" + FallbackStyleName); 2454 2455 if (StyleName.startswith("{")) { 2456 // Parse YAML/JSON style from the command line. 2457 if (std::error_code ec = parseConfiguration(StyleName, &Style)) 2458 return make_string_error("Error parsing -style: " + ec.message()); 2459 return Style; 2460 } 2461 2462 if (!StyleName.equals_lower("file")) { 2463 if (!getPredefinedStyle(StyleName, Style.Language, &Style)) 2464 return make_string_error("Invalid value for -style"); 2465 return Style; 2466 } 2467 2468 // Look for .clang-format/_clang-format file in the file's parent directories. 2469 SmallString<128> UnsuitableConfigFiles; 2470 SmallString<128> Path(FileName); 2471 if (std::error_code EC = FS->makeAbsolute(Path)) 2472 return make_string_error(EC.message()); 2473 2474 for (StringRef Directory = Path; !Directory.empty(); 2475 Directory = llvm::sys::path::parent_path(Directory)) { 2476 2477 auto Status = FS->status(Directory); 2478 if (!Status || 2479 Status->getType() != llvm::sys::fs::file_type::directory_file) { 2480 continue; 2481 } 2482 2483 SmallString<128> ConfigFile(Directory); 2484 2485 llvm::sys::path::append(ConfigFile, ".clang-format"); 2486 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2487 2488 Status = FS->status(ConfigFile.str()); 2489 bool FoundConfigFile = 2490 Status && (Status->getType() == llvm::sys::fs::file_type::regular_file); 2491 if (!FoundConfigFile) { 2492 // Try _clang-format too, since dotfiles are not commonly used on Windows. 2493 ConfigFile = Directory; 2494 llvm::sys::path::append(ConfigFile, "_clang-format"); 2495 LLVM_DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2496 Status = FS->status(ConfigFile.str()); 2497 FoundConfigFile = Status && (Status->getType() == 2498 llvm::sys::fs::file_type::regular_file); 2499 } 2500 2501 if (FoundConfigFile) { 2502 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 2503 FS->getBufferForFile(ConfigFile.str()); 2504 if (std::error_code EC = Text.getError()) 2505 return make_string_error(EC.message()); 2506 if (std::error_code ec = 2507 parseConfiguration(Text.get()->getBuffer(), &Style)) { 2508 if (ec == ParseError::Unsuitable) { 2509 if (!UnsuitableConfigFiles.empty()) 2510 UnsuitableConfigFiles.append(", "); 2511 UnsuitableConfigFiles.append(ConfigFile); 2512 continue; 2513 } 2514 return make_string_error("Error reading " + ConfigFile + ": " + 2515 ec.message()); 2516 } 2517 LLVM_DEBUG(llvm::dbgs() 2518 << "Using configuration file " << ConfigFile << "\n"); 2519 return Style; 2520 } 2521 } 2522 if (!UnsuitableConfigFiles.empty()) 2523 return make_string_error("Configuration file(s) do(es) not support " + 2524 getLanguageName(Style.Language) + ": " + 2525 UnsuitableConfigFiles); 2526 return FallbackStyle; 2527 } 2528 2529 } // namespace format 2530 } // namespace clang 2531