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