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