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