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