Format.cpp revision 276479
1249261Sdim//===--- Format.cpp - Format C++ code -------------------------------------===// 2249261Sdim// 3249261Sdim// The LLVM Compiler Infrastructure 4249261Sdim// 5249261Sdim// This file is distributed under the University of Illinois Open Source 6249261Sdim// License. See LICENSE.TXT for details. 7249261Sdim// 8249261Sdim//===----------------------------------------------------------------------===// 9249261Sdim/// 10249261Sdim/// \file 11249261Sdim/// \brief This file implements functions declared in Format.h. This will be 12249261Sdim/// split into separate files as we go. 13249261Sdim/// 14249261Sdim//===----------------------------------------------------------------------===// 15249261Sdim 16261991Sdim#include "ContinuationIndenter.h" 17249261Sdim#include "TokenAnnotator.h" 18249261Sdim#include "UnwrappedLineParser.h" 19251662Sdim#include "WhitespaceManager.h" 20249261Sdim#include "clang/Basic/Diagnostic.h" 21276479Sdim#include "clang/Basic/DiagnosticOptions.h" 22249261Sdim#include "clang/Basic/SourceManager.h" 23249261Sdim#include "clang/Format/Format.h" 24249261Sdim#include "clang/Lex/Lexer.h" 25249261Sdim#include "llvm/ADT/STLExtras.h" 26249261Sdim#include "llvm/Support/Allocator.h" 27249261Sdim#include "llvm/Support/Debug.h" 28276479Sdim#include "llvm/Support/Path.h" 29261991Sdim#include "llvm/Support/YAMLTraits.h" 30249261Sdim#include <queue> 31249261Sdim#include <string> 32249261Sdim 33276479Sdim#define DEBUG_TYPE "format-formatter" 34276479Sdim 35276479Sdimusing clang::format::FormatStyle; 36276479Sdim 37276479SdimLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string) 38276479Sdim 39261991Sdimnamespace llvm { 40261991Sdimnamespace yaml { 41276479Sdimtemplate <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> { 42276479Sdim static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) { 43276479Sdim IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp); 44276479Sdim IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript); 45276479Sdim IO.enumCase(Value, "Proto", FormatStyle::LK_Proto); 46261991Sdim } 47261991Sdim}; 48261991Sdim 49276479Sdimtemplate <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> { 50276479Sdim static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) { 51276479Sdim IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03); 52276479Sdim IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03); 53276479Sdim IO.enumCase(Value, "Cpp11", FormatStyle::LS_Cpp11); 54276479Sdim IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11); 55276479Sdim IO.enumCase(Value, "Auto", FormatStyle::LS_Auto); 56276479Sdim } 57276479Sdim}; 58276479Sdim 59276479Sdimtemplate <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> { 60276479Sdim static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) { 61276479Sdim IO.enumCase(Value, "Never", FormatStyle::UT_Never); 62276479Sdim IO.enumCase(Value, "false", FormatStyle::UT_Never); 63276479Sdim IO.enumCase(Value, "Always", FormatStyle::UT_Always); 64276479Sdim IO.enumCase(Value, "true", FormatStyle::UT_Always); 65276479Sdim IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation); 66276479Sdim } 67276479Sdim}; 68276479Sdim 69276479Sdimtemplate <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> { 70276479Sdim static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) { 71276479Sdim IO.enumCase(Value, "None", FormatStyle::SFS_None); 72276479Sdim IO.enumCase(Value, "false", FormatStyle::SFS_None); 73276479Sdim IO.enumCase(Value, "All", FormatStyle::SFS_All); 74276479Sdim IO.enumCase(Value, "true", FormatStyle::SFS_All); 75276479Sdim IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline); 76276479Sdim } 77276479Sdim}; 78276479Sdim 79276479Sdimtemplate <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> { 80276479Sdim static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) { 81276479Sdim IO.enumCase(Value, "Attach", FormatStyle::BS_Attach); 82276479Sdim IO.enumCase(Value, "Linux", FormatStyle::BS_Linux); 83276479Sdim IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup); 84276479Sdim IO.enumCase(Value, "Allman", FormatStyle::BS_Allman); 85276479Sdim IO.enumCase(Value, "GNU", FormatStyle::BS_GNU); 86276479Sdim } 87276479Sdim}; 88276479Sdim 89261991Sdimtemplate <> 90276479Sdimstruct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> { 91261991Sdim static void enumeration(IO &IO, 92276479Sdim FormatStyle::NamespaceIndentationKind &Value) { 93276479Sdim IO.enumCase(Value, "None", FormatStyle::NI_None); 94276479Sdim IO.enumCase(Value, "Inner", FormatStyle::NI_Inner); 95276479Sdim IO.enumCase(Value, "All", FormatStyle::NI_All); 96261991Sdim } 97261991Sdim}; 98261991Sdim 99261991Sdimtemplate <> 100276479Sdimstruct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> { 101276479Sdim static void enumeration(IO &IO, 102276479Sdim FormatStyle::PointerAlignmentStyle &Value) { 103276479Sdim IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle); 104276479Sdim IO.enumCase(Value, "Left", FormatStyle::PAS_Left); 105276479Sdim IO.enumCase(Value, "Right", FormatStyle::PAS_Right); 106276479Sdim 107276479Sdim // For backward compatibility. 108276479Sdim IO.enumCase(Value, "true", FormatStyle::PAS_Left); 109276479Sdim IO.enumCase(Value, "false", FormatStyle::PAS_Right); 110261991Sdim } 111261991Sdim}; 112261991Sdim 113261991Sdimtemplate <> 114276479Sdimstruct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> { 115276479Sdim static void enumeration(IO &IO, 116276479Sdim FormatStyle::SpaceBeforeParensOptions &Value) { 117276479Sdim IO.enumCase(Value, "Never", FormatStyle::SBPO_Never); 118276479Sdim IO.enumCase(Value, "ControlStatements", 119276479Sdim FormatStyle::SBPO_ControlStatements); 120276479Sdim IO.enumCase(Value, "Always", FormatStyle::SBPO_Always); 121276479Sdim 122276479Sdim // For backward compatibility. 123276479Sdim IO.enumCase(Value, "false", FormatStyle::SBPO_Never); 124276479Sdim IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements); 125261991Sdim } 126261991Sdim}; 127261991Sdim 128276479Sdimtemplate <> struct MappingTraits<FormatStyle> { 129276479Sdim static void mapping(IO &IO, FormatStyle &Style) { 130276479Sdim // When reading, read the language first, we need it for getPredefinedStyle. 131276479Sdim IO.mapOptional("Language", Style.Language); 132276479Sdim 133261991Sdim if (IO.outputting()) { 134261991Sdim StringRef StylesArray[] = { "LLVM", "Google", "Chromium", 135276479Sdim "Mozilla", "WebKit", "GNU" }; 136261991Sdim ArrayRef<StringRef> Styles(StylesArray); 137261991Sdim for (size_t i = 0, e = Styles.size(); i < e; ++i) { 138261991Sdim StringRef StyleName(Styles[i]); 139276479Sdim FormatStyle PredefinedStyle; 140276479Sdim if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) && 141261991Sdim Style == PredefinedStyle) { 142261991Sdim IO.mapOptional("# BasedOnStyle", StyleName); 143261991Sdim break; 144261991Sdim } 145261991Sdim } 146261991Sdim } else { 147261991Sdim StringRef BasedOnStyle; 148261991Sdim IO.mapOptional("BasedOnStyle", BasedOnStyle); 149276479Sdim if (!BasedOnStyle.empty()) { 150276479Sdim FormatStyle::LanguageKind OldLanguage = Style.Language; 151276479Sdim FormatStyle::LanguageKind Language = 152276479Sdim ((FormatStyle *)IO.getContext())->Language; 153276479Sdim if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) { 154261991Sdim IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle)); 155261991Sdim return; 156261991Sdim } 157276479Sdim Style.Language = OldLanguage; 158276479Sdim } 159261991Sdim } 160261991Sdim 161261991Sdim IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset); 162261991Sdim IO.mapOptional("ConstructorInitializerIndentWidth", 163261991Sdim Style.ConstructorInitializerIndentWidth); 164261991Sdim IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft); 165261991Sdim IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); 166261991Sdim IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine", 167261991Sdim Style.AllowAllParametersOfDeclarationOnNextLine); 168276479Sdim IO.mapOptional("AllowShortBlocksOnASingleLine", 169276479Sdim Style.AllowShortBlocksOnASingleLine); 170261991Sdim IO.mapOptional("AllowShortIfStatementsOnASingleLine", 171261991Sdim Style.AllowShortIfStatementsOnASingleLine); 172261991Sdim IO.mapOptional("AllowShortLoopsOnASingleLine", 173261991Sdim Style.AllowShortLoopsOnASingleLine); 174276479Sdim IO.mapOptional("AllowShortFunctionsOnASingleLine", 175276479Sdim Style.AllowShortFunctionsOnASingleLine); 176261991Sdim IO.mapOptional("AlwaysBreakTemplateDeclarations", 177261991Sdim Style.AlwaysBreakTemplateDeclarations); 178261991Sdim IO.mapOptional("AlwaysBreakBeforeMultilineStrings", 179261991Sdim Style.AlwaysBreakBeforeMultilineStrings); 180261991Sdim IO.mapOptional("BreakBeforeBinaryOperators", 181261991Sdim Style.BreakBeforeBinaryOperators); 182261991Sdim IO.mapOptional("BreakBeforeTernaryOperators", 183261991Sdim Style.BreakBeforeTernaryOperators); 184261991Sdim IO.mapOptional("BreakConstructorInitializersBeforeComma", 185261991Sdim Style.BreakConstructorInitializersBeforeComma); 186261991Sdim IO.mapOptional("BinPackParameters", Style.BinPackParameters); 187261991Sdim IO.mapOptional("ColumnLimit", Style.ColumnLimit); 188261991Sdim IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine", 189261991Sdim Style.ConstructorInitializerAllOnOneLineOrOnePerLine); 190276479Sdim IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment); 191261991Sdim IO.mapOptional("ExperimentalAutoDetectBinPacking", 192261991Sdim Style.ExperimentalAutoDetectBinPacking); 193261991Sdim IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels); 194276479Sdim IO.mapOptional("IndentWrappedFunctionNames", 195276479Sdim Style.IndentWrappedFunctionNames); 196276479Sdim IO.mapOptional("IndentFunctionDeclarationAfterType", 197276479Sdim Style.IndentWrappedFunctionNames); 198261991Sdim IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep); 199276479Sdim IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks", 200276479Sdim Style.KeepEmptyLinesAtTheStartOfBlocks); 201261991Sdim IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation); 202276479Sdim IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty); 203261991Sdim IO.mapOptional("ObjCSpaceBeforeProtocolList", 204261991Sdim Style.ObjCSpaceBeforeProtocolList); 205261991Sdim IO.mapOptional("PenaltyBreakBeforeFirstCallParameter", 206261991Sdim Style.PenaltyBreakBeforeFirstCallParameter); 207261991Sdim IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment); 208261991Sdim IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString); 209261991Sdim IO.mapOptional("PenaltyBreakFirstLessLess", 210261991Sdim Style.PenaltyBreakFirstLessLess); 211261991Sdim IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter); 212261991Sdim IO.mapOptional("PenaltyReturnTypeOnItsOwnLine", 213261991Sdim Style.PenaltyReturnTypeOnItsOwnLine); 214276479Sdim IO.mapOptional("PointerAlignment", Style.PointerAlignment); 215261991Sdim IO.mapOptional("SpacesBeforeTrailingComments", 216261991Sdim Style.SpacesBeforeTrailingComments); 217261991Sdim IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle); 218261991Sdim IO.mapOptional("Standard", Style.Standard); 219261991Sdim IO.mapOptional("IndentWidth", Style.IndentWidth); 220261991Sdim IO.mapOptional("TabWidth", Style.TabWidth); 221261991Sdim IO.mapOptional("UseTab", Style.UseTab); 222261991Sdim IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); 223261991Sdim IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses); 224261991Sdim IO.mapOptional("SpacesInAngles", Style.SpacesInAngles); 225261991Sdim IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses); 226261991Sdim IO.mapOptional("SpacesInCStyleCastParentheses", 227261991Sdim Style.SpacesInCStyleCastParentheses); 228276479Sdim IO.mapOptional("SpacesInContainerLiterals", 229276479Sdim Style.SpacesInContainerLiterals); 230261991Sdim IO.mapOptional("SpaceBeforeAssignmentOperators", 231261991Sdim Style.SpaceBeforeAssignmentOperators); 232261991Sdim IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth); 233276479Sdim IO.mapOptional("CommentPragmas", Style.CommentPragmas); 234276479Sdim IO.mapOptional("ForEachMacros", Style.ForEachMacros); 235276479Sdim 236276479Sdim // For backward compatibility. 237276479Sdim if (!IO.outputting()) { 238276479Sdim IO.mapOptional("SpaceAfterControlStatementKeyword", 239276479Sdim Style.SpaceBeforeParens); 240276479Sdim IO.mapOptional("PointerBindsToType", Style.PointerAlignment); 241276479Sdim IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment); 242276479Sdim } 243276479Sdim IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens); 244276479Sdim IO.mapOptional("DisableFormat", Style.DisableFormat); 245261991Sdim } 246261991Sdim}; 247276479Sdim 248276479Sdim// Allows to read vector<FormatStyle> while keeping default values. 249276479Sdim// IO.getContext() should contain a pointer to the FormatStyle structure, that 250276479Sdim// will be used to get default values for missing keys. 251276479Sdim// If the first element has no Language specified, it will be treated as the 252276479Sdim// default one for the following elements. 253276479Sdimtemplate <> struct DocumentListTraits<std::vector<FormatStyle> > { 254276479Sdim static size_t size(IO &IO, std::vector<FormatStyle> &Seq) { 255276479Sdim return Seq.size(); 256276479Sdim } 257276479Sdim static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq, 258276479Sdim size_t Index) { 259276479Sdim if (Index >= Seq.size()) { 260276479Sdim assert(Index == Seq.size()); 261276479Sdim FormatStyle Template; 262276479Sdim if (Seq.size() > 0 && Seq[0].Language == FormatStyle::LK_None) { 263276479Sdim Template = Seq[0]; 264276479Sdim } else { 265276479Sdim Template = *((const FormatStyle *)IO.getContext()); 266276479Sdim Template.Language = FormatStyle::LK_None; 267276479Sdim } 268276479Sdim Seq.resize(Index + 1, Template); 269276479Sdim } 270276479Sdim return Seq[Index]; 271276479Sdim } 272276479Sdim}; 273261991Sdim} 274261991Sdim} 275261991Sdim 276249261Sdimnamespace clang { 277249261Sdimnamespace format { 278249261Sdim 279276479Sdimconst std::error_category &getParseCategory() { 280276479Sdim static ParseErrorCategory C; 281276479Sdim return C; 282261991Sdim} 283276479Sdimstd::error_code make_error_code(ParseError e) { 284276479Sdim return std::error_code(static_cast<int>(e), getParseCategory()); 285276479Sdim} 286261991Sdim 287276479Sdimconst char *ParseErrorCategory::name() const LLVM_NOEXCEPT { 288276479Sdim return "clang-format.parse_error"; 289276479Sdim} 290276479Sdim 291276479Sdimstd::string ParseErrorCategory::message(int EV) const { 292276479Sdim switch (static_cast<ParseError>(EV)) { 293276479Sdim case ParseError::Success: 294276479Sdim return "Success"; 295276479Sdim case ParseError::Error: 296276479Sdim return "Invalid argument"; 297276479Sdim case ParseError::Unsuitable: 298276479Sdim return "Unsuitable"; 299276479Sdim } 300276479Sdim llvm_unreachable("unexpected parse error"); 301276479Sdim} 302276479Sdim 303249261SdimFormatStyle getLLVMStyle() { 304249261Sdim FormatStyle LLVMStyle; 305276479Sdim LLVMStyle.Language = FormatStyle::LK_Cpp; 306251662Sdim LLVMStyle.AccessModifierOffset = -2; 307251662Sdim LLVMStyle.AlignEscapedNewlinesLeft = false; 308261991Sdim LLVMStyle.AlignTrailingComments = true; 309251662Sdim LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; 310276479Sdim LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; 311276479Sdim LLVMStyle.AllowShortBlocksOnASingleLine = false; 312251662Sdim LLVMStyle.AllowShortIfStatementsOnASingleLine = false; 313261991Sdim LLVMStyle.AllowShortLoopsOnASingleLine = false; 314261991Sdim LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; 315261991Sdim LLVMStyle.AlwaysBreakTemplateDeclarations = false; 316251662Sdim LLVMStyle.BinPackParameters = true; 317261991Sdim LLVMStyle.BreakBeforeBinaryOperators = false; 318261991Sdim LLVMStyle.BreakBeforeTernaryOperators = true; 319261991Sdim LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; 320261991Sdim LLVMStyle.BreakConstructorInitializersBeforeComma = false; 321249261Sdim LLVMStyle.ColumnLimit = 80; 322276479Sdim LLVMStyle.CommentPragmas = "^ IWYU pragma:"; 323251662Sdim LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false; 324261991Sdim LLVMStyle.ConstructorInitializerIndentWidth = 4; 325276479Sdim LLVMStyle.ContinuationIndentWidth = 4; 326276479Sdim LLVMStyle.Cpp11BracedListStyle = true; 327276479Sdim LLVMStyle.DerivePointerAlignment = false; 328261991Sdim LLVMStyle.ExperimentalAutoDetectBinPacking = false; 329276479Sdim LLVMStyle.ForEachMacros.push_back("foreach"); 330276479Sdim LLVMStyle.ForEachMacros.push_back("Q_FOREACH"); 331276479Sdim LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH"); 332249261Sdim LLVMStyle.IndentCaseLabels = false; 333276479Sdim LLVMStyle.IndentWrappedFunctionNames = false; 334261991Sdim LLVMStyle.IndentWidth = 2; 335261991Sdim LLVMStyle.TabWidth = 8; 336251662Sdim LLVMStyle.MaxEmptyLinesToKeep = 1; 337276479Sdim LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true; 338261991Sdim LLVMStyle.NamespaceIndentation = FormatStyle::NI_None; 339276479Sdim LLVMStyle.ObjCSpaceAfterProperty = false; 340249261Sdim LLVMStyle.ObjCSpaceBeforeProtocolList = true; 341276479Sdim LLVMStyle.PointerAlignment = FormatStyle::PAS_Right; 342251662Sdim LLVMStyle.SpacesBeforeTrailingComments = 1; 343276479Sdim LLVMStyle.Standard = FormatStyle::LS_Cpp11; 344261991Sdim LLVMStyle.UseTab = FormatStyle::UT_Never; 345261991Sdim LLVMStyle.SpacesInParentheses = false; 346261991Sdim LLVMStyle.SpaceInEmptyParentheses = false; 347276479Sdim LLVMStyle.SpacesInContainerLiterals = true; 348261991Sdim LLVMStyle.SpacesInCStyleCastParentheses = false; 349276479Sdim LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements; 350261991Sdim LLVMStyle.SpaceBeforeAssignmentOperators = true; 351261991Sdim LLVMStyle.SpacesInAngles = false; 352261991Sdim 353276479Sdim LLVMStyle.PenaltyBreakComment = 300; 354276479Sdim LLVMStyle.PenaltyBreakFirstLessLess = 120; 355276479Sdim LLVMStyle.PenaltyBreakString = 1000; 356276479Sdim LLVMStyle.PenaltyExcessCharacter = 1000000; 357261991Sdim LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60; 358261991Sdim LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19; 359261991Sdim 360276479Sdim LLVMStyle.DisableFormat = false; 361276479Sdim 362249261Sdim return LLVMStyle; 363249261Sdim} 364249261Sdim 365276479SdimFormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { 366276479Sdim FormatStyle GoogleStyle = getLLVMStyle(); 367276479Sdim GoogleStyle.Language = Language; 368276479Sdim 369251662Sdim GoogleStyle.AccessModifierOffset = -1; 370251662Sdim GoogleStyle.AlignEscapedNewlinesLeft = true; 371251662Sdim GoogleStyle.AllowShortIfStatementsOnASingleLine = true; 372261991Sdim GoogleStyle.AllowShortLoopsOnASingleLine = true; 373261991Sdim GoogleStyle.AlwaysBreakBeforeMultilineStrings = true; 374261991Sdim GoogleStyle.AlwaysBreakTemplateDeclarations = true; 375251662Sdim GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; 376276479Sdim GoogleStyle.DerivePointerAlignment = true; 377249261Sdim GoogleStyle.IndentCaseLabels = true; 378276479Sdim GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false; 379276479Sdim GoogleStyle.ObjCSpaceAfterProperty = false; 380249261Sdim GoogleStyle.ObjCSpaceBeforeProtocolList = false; 381276479Sdim GoogleStyle.PointerAlignment = FormatStyle::PAS_Left; 382251662Sdim GoogleStyle.SpacesBeforeTrailingComments = 2; 383251662Sdim GoogleStyle.Standard = FormatStyle::LS_Auto; 384261991Sdim 385261991Sdim GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200; 386261991Sdim GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1; 387261991Sdim 388276479Sdim if (Language == FormatStyle::LK_JavaScript) { 389276479Sdim GoogleStyle.BreakBeforeTernaryOperators = false; 390276479Sdim GoogleStyle.MaxEmptyLinesToKeep = 3; 391276479Sdim GoogleStyle.SpacesInContainerLiterals = false; 392276479Sdim } else if (Language == FormatStyle::LK_Proto) { 393276479Sdim GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; 394276479Sdim GoogleStyle.SpacesInContainerLiterals = false; 395276479Sdim } 396276479Sdim 397249261Sdim return GoogleStyle; 398249261Sdim} 399249261Sdim 400276479SdimFormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) { 401276479Sdim FormatStyle ChromiumStyle = getGoogleStyle(Language); 402249261Sdim ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false; 403276479Sdim ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 404251662Sdim ChromiumStyle.AllowShortIfStatementsOnASingleLine = false; 405261991Sdim ChromiumStyle.AllowShortLoopsOnASingleLine = false; 406249261Sdim ChromiumStyle.BinPackParameters = false; 407276479Sdim ChromiumStyle.DerivePointerAlignment = false; 408249261Sdim ChromiumStyle.Standard = FormatStyle::LS_Cpp03; 409249261Sdim return ChromiumStyle; 410249261Sdim} 411249261Sdim 412251662SdimFormatStyle getMozillaStyle() { 413251662Sdim FormatStyle MozillaStyle = getLLVMStyle(); 414251662Sdim MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false; 415276479Sdim MozillaStyle.Cpp11BracedListStyle = false; 416251662Sdim MozillaStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; 417276479Sdim MozillaStyle.DerivePointerAlignment = true; 418251662Sdim MozillaStyle.IndentCaseLabels = true; 419276479Sdim MozillaStyle.ObjCSpaceAfterProperty = true; 420251662Sdim MozillaStyle.ObjCSpaceBeforeProtocolList = false; 421251662Sdim MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200; 422276479Sdim MozillaStyle.PointerAlignment = FormatStyle::PAS_Left; 423276479Sdim MozillaStyle.Standard = FormatStyle::LS_Cpp03; 424251662Sdim return MozillaStyle; 425249261Sdim} 426249261Sdim 427261991SdimFormatStyle getWebKitStyle() { 428261991Sdim FormatStyle Style = getLLVMStyle(); 429261991Sdim Style.AccessModifierOffset = -4; 430261991Sdim Style.AlignTrailingComments = false; 431261991Sdim Style.BreakBeforeBinaryOperators = true; 432261991Sdim Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup; 433261991Sdim Style.BreakConstructorInitializersBeforeComma = true; 434276479Sdim Style.Cpp11BracedListStyle = false; 435261991Sdim Style.ColumnLimit = 0; 436261991Sdim Style.IndentWidth = 4; 437261991Sdim Style.NamespaceIndentation = FormatStyle::NI_Inner; 438276479Sdim Style.ObjCSpaceAfterProperty = true; 439276479Sdim Style.PointerAlignment = FormatStyle::PAS_Left; 440276479Sdim Style.Standard = FormatStyle::LS_Cpp03; 441261991Sdim return Style; 442249261Sdim} 443249261Sdim 444276479SdimFormatStyle getGNUStyle() { 445276479Sdim FormatStyle Style = getLLVMStyle(); 446276479Sdim Style.BreakBeforeBinaryOperators = true; 447276479Sdim Style.BreakBeforeBraces = FormatStyle::BS_GNU; 448276479Sdim Style.BreakBeforeTernaryOperators = true; 449276479Sdim Style.Cpp11BracedListStyle = false; 450276479Sdim Style.ColumnLimit = 79; 451276479Sdim Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 452276479Sdim Style.Standard = FormatStyle::LS_Cpp03; 453276479Sdim return Style; 454276479Sdim} 455276479Sdim 456276479SdimFormatStyle getNoStyle() { 457276479Sdim FormatStyle NoStyle = getLLVMStyle(); 458276479Sdim NoStyle.DisableFormat = true; 459276479Sdim return NoStyle; 460276479Sdim} 461276479Sdim 462276479Sdimbool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, 463276479Sdim FormatStyle *Style) { 464276479Sdim if (Name.equals_lower("llvm")) { 465261991Sdim *Style = getLLVMStyle(); 466276479Sdim } else if (Name.equals_lower("chromium")) { 467276479Sdim *Style = getChromiumStyle(Language); 468276479Sdim } else if (Name.equals_lower("mozilla")) { 469261991Sdim *Style = getMozillaStyle(); 470276479Sdim } else if (Name.equals_lower("google")) { 471276479Sdim *Style = getGoogleStyle(Language); 472276479Sdim } else if (Name.equals_lower("webkit")) { 473261991Sdim *Style = getWebKitStyle(); 474276479Sdim } else if (Name.equals_lower("gnu")) { 475276479Sdim *Style = getGNUStyle(); 476276479Sdim } else if (Name.equals_lower("none")) { 477276479Sdim *Style = getNoStyle(); 478276479Sdim } else { 479261991Sdim return false; 480276479Sdim } 481249261Sdim 482276479Sdim Style->Language = Language; 483261991Sdim return true; 484261991Sdim} 485249261Sdim 486276479Sdimstd::error_code parseConfiguration(StringRef Text, FormatStyle *Style) { 487276479Sdim assert(Style); 488276479Sdim FormatStyle::LanguageKind Language = Style->Language; 489276479Sdim assert(Language != FormatStyle::LK_None); 490261991Sdim if (Text.trim().empty()) 491276479Sdim return make_error_code(ParseError::Error); 492276479Sdim 493276479Sdim std::vector<FormatStyle> Styles; 494261991Sdim llvm::yaml::Input Input(Text); 495276479Sdim // DocumentListTraits<vector<FormatStyle>> uses the context to get default 496276479Sdim // values for the fields, keys for which are missing from the configuration. 497276479Sdim // Mapping also uses the context to get the language to find the correct 498276479Sdim // base style. 499276479Sdim Input.setContext(Style); 500276479Sdim Input >> Styles; 501276479Sdim if (Input.error()) 502276479Sdim return Input.error(); 503276479Sdim 504276479Sdim for (unsigned i = 0; i < Styles.size(); ++i) { 505276479Sdim // Ensures that only the first configuration can skip the Language option. 506276479Sdim if (Styles[i].Language == FormatStyle::LK_None && i != 0) 507276479Sdim return make_error_code(ParseError::Error); 508276479Sdim // Ensure that each language is configured at most once. 509276479Sdim for (unsigned j = 0; j < i; ++j) { 510276479Sdim if (Styles[i].Language == Styles[j].Language) { 511276479Sdim DEBUG(llvm::dbgs() 512276479Sdim << "Duplicate languages in the config file on positions " << j 513276479Sdim << " and " << i << "\n"); 514276479Sdim return make_error_code(ParseError::Error); 515276479Sdim } 516276479Sdim } 517276479Sdim } 518276479Sdim // Look for a suitable configuration starting from the end, so we can 519276479Sdim // find the configuration for the specific language first, and the default 520276479Sdim // configuration (which can only be at slot 0) after it. 521276479Sdim for (int i = Styles.size() - 1; i >= 0; --i) { 522276479Sdim if (Styles[i].Language == Language || 523276479Sdim Styles[i].Language == FormatStyle::LK_None) { 524276479Sdim *Style = Styles[i]; 525276479Sdim Style->Language = Language; 526276479Sdim return make_error_code(ParseError::Success); 527276479Sdim } 528276479Sdim } 529276479Sdim return make_error_code(ParseError::Unsuitable); 530261991Sdim} 531249261Sdim 532261991Sdimstd::string configurationAsText(const FormatStyle &Style) { 533261991Sdim std::string Text; 534261991Sdim llvm::raw_string_ostream Stream(Text); 535261991Sdim llvm::yaml::Output Output(Stream); 536261991Sdim // We use the same mapping method for input and output, so we need a non-const 537261991Sdim // reference here. 538261991Sdim FormatStyle NonConstStyle = Style; 539261991Sdim Output << NonConstStyle; 540261991Sdim return Stream.str(); 541261991Sdim} 542249261Sdim 543261991Sdimnamespace { 544249261Sdim 545261991Sdimclass NoColumnLimitFormatter { 546261991Sdimpublic: 547261991Sdim NoColumnLimitFormatter(ContinuationIndenter *Indenter) : Indenter(Indenter) {} 548261991Sdim 549261991Sdim /// \brief Formats the line starting at \p State, simply keeping all of the 550261991Sdim /// input's line breaking decisions. 551261991Sdim void format(unsigned FirstIndent, const AnnotatedLine *Line) { 552261991Sdim LineState State = 553261991Sdim Indenter->getInitialState(FirstIndent, Line, /*DryRun=*/false); 554276479Sdim while (State.NextToken) { 555261991Sdim bool Newline = 556261991Sdim Indenter->mustBreak(State) || 557261991Sdim (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0); 558261991Sdim Indenter->addTokenToState(State, Newline, /*DryRun=*/false); 559261991Sdim } 560249261Sdim } 561249261Sdim 562249261Sdimprivate: 563261991Sdim ContinuationIndenter *Indenter; 564261991Sdim}; 565249261Sdim 566261991Sdimclass LineJoiner { 567261991Sdimpublic: 568261991Sdim LineJoiner(const FormatStyle &Style) : Style(Style) {} 569249261Sdim 570261991Sdim /// \brief Calculates how many lines can be merged into 1 starting at \p I. 571261991Sdim unsigned 572261991Sdim tryFitMultipleLinesInOne(unsigned Indent, 573276479Sdim SmallVectorImpl<AnnotatedLine *>::const_iterator I, 574261991Sdim SmallVectorImpl<AnnotatedLine *>::const_iterator E) { 575261991Sdim // We can never merge stuff if there are trailing line comments. 576276479Sdim const AnnotatedLine *TheLine = *I; 577261991Sdim if (TheLine->Last->Type == TT_LineComment) 578261991Sdim return 0; 579249261Sdim 580276479Sdim if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit) 581261991Sdim return 0; 582249261Sdim 583261991Sdim unsigned Limit = 584261991Sdim Style.ColumnLimit == 0 ? UINT_MAX : Style.ColumnLimit - Indent; 585261991Sdim // If we already exceed the column limit, we set 'Limit' to 0. The different 586261991Sdim // tryMerge..() functions can then decide whether to still do merging. 587261991Sdim Limit = TheLine->Last->TotalLength > Limit 588261991Sdim ? 0 589261991Sdim : Limit - TheLine->Last->TotalLength; 590249261Sdim 591276479Sdim if (I + 1 == E || I[1]->Type == LT_Invalid || I[1]->First->MustBreakBefore) 592261991Sdim return 0; 593249261Sdim 594276479Sdim // FIXME: TheLine->Level != 0 might or might not be the right check to do. 595276479Sdim // If necessary, change to something smarter. 596276479Sdim bool MergeShortFunctions = 597276479Sdim Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All || 598276479Sdim (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline && 599276479Sdim TheLine->Level != 0); 600276479Sdim 601276479Sdim if (TheLine->Last->Type == TT_FunctionLBrace && 602276479Sdim TheLine->First != TheLine->Last) { 603276479Sdim return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0; 604276479Sdim } 605261991Sdim if (TheLine->Last->is(tok::l_brace)) { 606276479Sdim return Style.BreakBeforeBraces == FormatStyle::BS_Attach 607276479Sdim ? tryMergeSimpleBlock(I, E, Limit) 608276479Sdim : 0; 609276479Sdim } 610276479Sdim if (I[1]->First->Type == TT_FunctionLBrace && 611276479Sdim Style.BreakBeforeBraces != FormatStyle::BS_Attach) { 612276479Sdim // Check for Limit <= 2 to account for the " {". 613276479Sdim if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(TheLine))) 614276479Sdim return 0; 615276479Sdim Limit -= 2; 616276479Sdim 617276479Sdim unsigned MergedLines = 0; 618276479Sdim if (MergeShortFunctions) { 619276479Sdim MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); 620276479Sdim // If we managed to merge the block, count the function header, which is 621276479Sdim // on a separate line. 622276479Sdim if (MergedLines > 0) 623276479Sdim ++MergedLines; 624276479Sdim } 625276479Sdim return MergedLines; 626276479Sdim } 627276479Sdim if (TheLine->First->is(tok::kw_if)) { 628276479Sdim return Style.AllowShortIfStatementsOnASingleLine 629276479Sdim ? tryMergeSimpleControlStatement(I, E, Limit) 630276479Sdim : 0; 631276479Sdim } 632276479Sdim if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) { 633276479Sdim return Style.AllowShortLoopsOnASingleLine 634276479Sdim ? tryMergeSimpleControlStatement(I, E, Limit) 635276479Sdim : 0; 636276479Sdim } 637276479Sdim if (TheLine->InPPDirective && 638276479Sdim (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) { 639261991Sdim return tryMergeSimplePPDirective(I, E, Limit); 640261991Sdim } 641261991Sdim return 0; 642261991Sdim } 643249261Sdim 644261991Sdimprivate: 645261991Sdim unsigned 646276479Sdim tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I, 647261991Sdim SmallVectorImpl<AnnotatedLine *>::const_iterator E, 648261991Sdim unsigned Limit) { 649261991Sdim if (Limit == 0) 650261991Sdim return 0; 651261991Sdim if (!I[1]->InPPDirective || I[1]->First->HasUnescapedNewline) 652261991Sdim return 0; 653261991Sdim if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline) 654261991Sdim return 0; 655261991Sdim if (1 + I[1]->Last->TotalLength > Limit) 656261991Sdim return 0; 657261991Sdim return 1; 658261991Sdim } 659249261Sdim 660261991Sdim unsigned tryMergeSimpleControlStatement( 661276479Sdim SmallVectorImpl<AnnotatedLine *>::const_iterator I, 662261991Sdim SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) { 663261991Sdim if (Limit == 0) 664261991Sdim return 0; 665276479Sdim if ((Style.BreakBeforeBraces == FormatStyle::BS_Allman || 666276479Sdim Style.BreakBeforeBraces == FormatStyle::BS_GNU) && 667276479Sdim (I[1]->First->is(tok::l_brace) && !Style.AllowShortBlocksOnASingleLine)) 668261991Sdim return 0; 669261991Sdim if (I[1]->InPPDirective != (*I)->InPPDirective || 670261991Sdim (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline)) 671261991Sdim return 0; 672276479Sdim Limit = limitConsideringMacros(I + 1, E, Limit); 673261991Sdim AnnotatedLine &Line = **I; 674261991Sdim if (Line.Last->isNot(tok::r_paren)) 675261991Sdim return 0; 676261991Sdim if (1 + I[1]->Last->TotalLength > Limit) 677261991Sdim return 0; 678261991Sdim if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, 679276479Sdim tok::kw_while) || 680261991Sdim I[1]->First->Type == TT_LineComment) 681261991Sdim return 0; 682261991Sdim // Only inline simple if's (no nested if or else). 683261991Sdim if (I + 2 != E && Line.First->is(tok::kw_if) && 684261991Sdim I[2]->First->is(tok::kw_else)) 685261991Sdim return 0; 686261991Sdim return 1; 687261991Sdim } 688249261Sdim 689261991Sdim unsigned 690276479Sdim tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I, 691261991Sdim SmallVectorImpl<AnnotatedLine *>::const_iterator E, 692261991Sdim unsigned Limit) { 693276479Sdim AnnotatedLine &Line = **I; 694276479Sdim 695276479Sdim // Don't merge ObjC @ keywords and methods. 696276479Sdim if (Line.First->isOneOf(tok::at, tok::minus, tok::plus)) 697261991Sdim return 0; 698249261Sdim 699276479Sdim // Check that the current line allows merging. This depends on whether we 700276479Sdim // are in a control flow statements as well as several style flags. 701276479Sdim if (Line.First->isOneOf(tok::kw_else, tok::kw_case)) 702261991Sdim return 0; 703276479Sdim if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::kw_try, 704276479Sdim tok::kw_catch, tok::kw_for, tok::r_brace)) { 705276479Sdim if (!Style.AllowShortBlocksOnASingleLine) 706276479Sdim return 0; 707276479Sdim if (!Style.AllowShortIfStatementsOnASingleLine && 708276479Sdim Line.First->is(tok::kw_if)) 709276479Sdim return 0; 710276479Sdim if (!Style.AllowShortLoopsOnASingleLine && 711276479Sdim Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for)) 712276479Sdim return 0; 713276479Sdim // FIXME: Consider an option to allow short exception handling clauses on 714276479Sdim // a single line. 715276479Sdim if (Line.First->isOneOf(tok::kw_try, tok::kw_catch)) 716276479Sdim return 0; 717276479Sdim } 718249261Sdim 719261991Sdim FormatToken *Tok = I[1]->First; 720261991Sdim if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore && 721276479Sdim (Tok->getNextNonComment() == nullptr || 722261991Sdim Tok->getNextNonComment()->is(tok::semi))) { 723261991Sdim // We merge empty blocks even if the line exceeds the column limit. 724261991Sdim Tok->SpacesRequiredBefore = 0; 725261991Sdim Tok->CanBreakBefore = true; 726261991Sdim return 1; 727261991Sdim } else if (Limit != 0 && Line.First->isNot(tok::kw_namespace)) { 728276479Sdim // We don't merge short records. 729276479Sdim if (Line.First->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct)) 730276479Sdim return 0; 731276479Sdim 732261991Sdim // Check that we still have three lines and they fit into the limit. 733261991Sdim if (I + 2 == E || I[2]->Type == LT_Invalid) 734261991Sdim return 0; 735276479Sdim Limit = limitConsideringMacros(I + 2, E, Limit); 736249261Sdim 737261991Sdim if (!nextTwoLinesFitInto(I, Limit)) 738261991Sdim return 0; 739249261Sdim 740261991Sdim // Second, check that the next line does not contain any braces - if it 741261991Sdim // does, readability declines when putting it into a single line. 742276479Sdim if (I[1]->Last->Type == TT_LineComment) 743261991Sdim return 0; 744261991Sdim do { 745276479Sdim if (Tok->is(tok::l_brace) && Tok->BlockKind != BK_BracedInit) 746261991Sdim return 0; 747261991Sdim Tok = Tok->Next; 748276479Sdim } while (Tok); 749249261Sdim 750276479Sdim // Last, check that the third line starts with a closing brace. 751261991Sdim Tok = I[2]->First; 752276479Sdim if (Tok->isNot(tok::r_brace)) 753261991Sdim return 0; 754249261Sdim 755261991Sdim return 2; 756249261Sdim } 757261991Sdim return 0; 758261991Sdim } 759249261Sdim 760276479Sdim /// Returns the modified column limit for \p I if it is inside a macro and 761276479Sdim /// needs a trailing '\'. 762276479Sdim unsigned 763276479Sdim limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I, 764276479Sdim SmallVectorImpl<AnnotatedLine *>::const_iterator E, 765276479Sdim unsigned Limit) { 766276479Sdim if (I[0]->InPPDirective && I + 1 != E && 767276479Sdim !I[1]->First->HasUnescapedNewline && !I[1]->First->is(tok::eof)) { 768276479Sdim return Limit < 2 ? 0 : Limit - 2; 769276479Sdim } 770276479Sdim return Limit; 771276479Sdim } 772276479Sdim 773261991Sdim bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I, 774261991Sdim unsigned Limit) { 775276479Sdim if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore) 776276479Sdim return false; 777261991Sdim return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit; 778261991Sdim } 779249261Sdim 780276479Sdim bool containsMustBreak(const AnnotatedLine *Line) { 781276479Sdim for (const FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) { 782276479Sdim if (Tok->MustBreakBefore) 783276479Sdim return true; 784276479Sdim } 785276479Sdim return false; 786276479Sdim } 787276479Sdim 788261991Sdim const FormatStyle &Style; 789261991Sdim}; 790249261Sdim 791261991Sdimclass UnwrappedLineFormatter { 792261991Sdimpublic: 793276479Sdim UnwrappedLineFormatter(ContinuationIndenter *Indenter, 794261991Sdim WhitespaceManager *Whitespaces, 795261991Sdim const FormatStyle &Style) 796276479Sdim : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style), 797276479Sdim Joiner(Style) {} 798249261Sdim 799261991Sdim unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun, 800276479Sdim int AdditionalIndent = 0, bool FixBadIndentation = false) { 801276479Sdim // Try to look up already computed penalty in DryRun-mode. 802276479Sdim std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey( 803276479Sdim &Lines, AdditionalIndent); 804276479Sdim auto CacheIt = PenaltyCache.find(CacheKey); 805276479Sdim if (DryRun && CacheIt != PenaltyCache.end()) 806276479Sdim return CacheIt->second; 807276479Sdim 808261991Sdim assert(!Lines.empty()); 809261991Sdim unsigned Penalty = 0; 810261991Sdim std::vector<int> IndentForLevel; 811261991Sdim for (unsigned i = 0, e = Lines[0]->Level; i != e; ++i) 812261991Sdim IndentForLevel.push_back(Style.IndentWidth * i + AdditionalIndent); 813276479Sdim const AnnotatedLine *PreviousLine = nullptr; 814261991Sdim for (SmallVectorImpl<AnnotatedLine *>::const_iterator I = Lines.begin(), 815261991Sdim E = Lines.end(); 816261991Sdim I != E; ++I) { 817261991Sdim const AnnotatedLine &TheLine = **I; 818261991Sdim const FormatToken *FirstTok = TheLine.First; 819261991Sdim int Offset = getIndentOffset(*FirstTok); 820249261Sdim 821261991Sdim // Determine indent and try to merge multiple unwrapped lines. 822276479Sdim unsigned Indent; 823276479Sdim if (TheLine.InPPDirective) { 824276479Sdim Indent = TheLine.Level * Style.IndentWidth; 825276479Sdim } else { 826276479Sdim while (IndentForLevel.size() <= TheLine.Level) 827276479Sdim IndentForLevel.push_back(-1); 828276479Sdim IndentForLevel.resize(TheLine.Level + 1); 829276479Sdim Indent = getIndent(IndentForLevel, TheLine.Level); 830276479Sdim } 831276479Sdim unsigned LevelIndent = Indent; 832261991Sdim if (static_cast<int>(Indent) + Offset >= 0) 833261991Sdim Indent += Offset; 834276479Sdim 835276479Sdim // Merge multiple lines if possible. 836261991Sdim unsigned MergedLines = Joiner.tryFitMultipleLinesInOne(Indent, I, E); 837276479Sdim if (MergedLines > 0 && Style.ColumnLimit == 0) { 838276479Sdim // Disallow line merging if there is a break at the start of one of the 839276479Sdim // input lines. 840276479Sdim for (unsigned i = 0; i < MergedLines; ++i) { 841276479Sdim if (I[i + 1]->First->NewlinesBefore > 0) 842276479Sdim MergedLines = 0; 843276479Sdim } 844276479Sdim } 845261991Sdim if (!DryRun) { 846261991Sdim for (unsigned i = 0; i < MergedLines; ++i) { 847261991Sdim join(*I[i], *I[i + 1]); 848261991Sdim } 849261991Sdim } 850261991Sdim I += MergedLines; 851249261Sdim 852276479Sdim bool FixIndentation = 853276479Sdim FixBadIndentation && (LevelIndent != FirstTok->OriginalColumn); 854261991Sdim if (TheLine.First->is(tok::eof)) { 855276479Sdim if (PreviousLine && PreviousLine->Affected && !DryRun) { 856276479Sdim // Remove the file's trailing whitespace. 857261991Sdim unsigned Newlines = std::min(FirstTok->NewlinesBefore, 1u); 858261991Sdim Whitespaces->replaceWhitespace(*TheLine.First, Newlines, 859261991Sdim /*IndentLevel=*/0, /*Spaces=*/0, 860261991Sdim /*TargetColumn=*/0); 861249261Sdim } 862261991Sdim } else if (TheLine.Type != LT_Invalid && 863276479Sdim (TheLine.Affected || FixIndentation)) { 864261991Sdim if (FirstTok->WhitespaceRange.isValid()) { 865261991Sdim if (!DryRun) 866261991Sdim formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level, 867261991Sdim Indent, TheLine.InPPDirective); 868249261Sdim } else { 869261991Sdim Indent = LevelIndent = FirstTok->OriginalColumn; 870249261Sdim } 871261991Sdim 872261991Sdim // If everything fits on a single line, just put it there. 873261991Sdim unsigned ColumnLimit = Style.ColumnLimit; 874261991Sdim if (I + 1 != E) { 875261991Sdim AnnotatedLine *NextLine = I[1]; 876261991Sdim if (NextLine->InPPDirective && !NextLine->First->HasUnescapedNewline) 877261991Sdim ColumnLimit = getColumnLimit(TheLine.InPPDirective); 878249261Sdim } 879249261Sdim 880261991Sdim if (TheLine.Last->TotalLength + Indent <= ColumnLimit) { 881261991Sdim LineState State = Indenter->getInitialState(Indent, &TheLine, DryRun); 882276479Sdim while (State.NextToken) { 883276479Sdim formatChildren(State, /*Newline=*/false, /*DryRun=*/false, Penalty); 884261991Sdim Indenter->addTokenToState(State, /*Newline=*/false, DryRun); 885276479Sdim } 886261991Sdim } else if (Style.ColumnLimit == 0) { 887276479Sdim // FIXME: Implement nested blocks for ColumnLimit = 0. 888261991Sdim NoColumnLimitFormatter Formatter(Indenter); 889261991Sdim if (!DryRun) 890261991Sdim Formatter.format(Indent, &TheLine); 891261991Sdim } else { 892261991Sdim Penalty += format(TheLine, Indent, DryRun); 893249261Sdim } 894249261Sdim 895276479Sdim if (!TheLine.InPPDirective) 896276479Sdim IndentForLevel[TheLine.Level] = LevelIndent; 897276479Sdim } else if (TheLine.ChildrenAffected) { 898276479Sdim format(TheLine.Children, DryRun); 899249261Sdim } else { 900261991Sdim // Format the first token if necessary, and notify the WhitespaceManager 901261991Sdim // about the unchanged whitespace. 902276479Sdim for (FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next) { 903261991Sdim if (Tok == TheLine.First && 904261991Sdim (Tok->NewlinesBefore > 0 || Tok->IsFirst)) { 905261991Sdim unsigned LevelIndent = Tok->OriginalColumn; 906261991Sdim if (!DryRun) { 907276479Sdim // Remove trailing whitespace of the previous line. 908276479Sdim if ((PreviousLine && PreviousLine->Affected) || 909276479Sdim TheLine.LeadingEmptyLinesAffected) { 910261991Sdim formatFirstToken(*Tok, PreviousLine, TheLine.Level, LevelIndent, 911261991Sdim TheLine.InPPDirective); 912261991Sdim } else { 913261991Sdim Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective); 914261991Sdim } 915261991Sdim } 916251662Sdim 917261991Sdim if (static_cast<int>(LevelIndent) - Offset >= 0) 918261991Sdim LevelIndent -= Offset; 919276479Sdim if (Tok->isNot(tok::comment) && !TheLine.InPPDirective) 920261991Sdim IndentForLevel[TheLine.Level] = LevelIndent; 921261991Sdim } else if (!DryRun) { 922261991Sdim Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective); 923261991Sdim } 924251662Sdim } 925251662Sdim } 926249261Sdim if (!DryRun) { 927276479Sdim for (FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next) { 928261991Sdim Tok->Finalized = true; 929261991Sdim } 930249261Sdim } 931261991Sdim PreviousLine = *I; 932251662Sdim } 933276479Sdim PenaltyCache[CacheKey] = Penalty; 934249261Sdim return Penalty; 935249261Sdim } 936249261Sdim 937261991Sdimprivate: 938261991Sdim /// \brief Formats an \c AnnotatedLine and returns the penalty. 939261991Sdim /// 940261991Sdim /// If \p DryRun is \c false, directly applies the changes. 941261991Sdim unsigned format(const AnnotatedLine &Line, unsigned FirstIndent, 942261991Sdim bool DryRun) { 943261991Sdim LineState State = Indenter->getInitialState(FirstIndent, &Line, DryRun); 944261991Sdim 945261991Sdim // If the ObjC method declaration does not fit on a line, we should format 946261991Sdim // it with one arg per line. 947261991Sdim if (State.Line->Type == LT_ObjCMethodDecl) 948261991Sdim State.Stack.back().BreakBeforeParameter = true; 949261991Sdim 950261991Sdim // Find best solution in solution space. 951261991Sdim return analyzeSolutionSpace(State, DryRun); 952249261Sdim } 953249261Sdim 954249261Sdim /// \brief An edge in the solution space from \c Previous->State to \c State, 955249261Sdim /// inserting a newline dependent on the \c NewLine. 956249261Sdim struct StateNode { 957249261Sdim StateNode(const LineState &State, bool NewLine, StateNode *Previous) 958249261Sdim : State(State), NewLine(NewLine), Previous(Previous) {} 959249261Sdim LineState State; 960249261Sdim bool NewLine; 961249261Sdim StateNode *Previous; 962249261Sdim }; 963249261Sdim 964249261Sdim /// \brief A pair of <penalty, count> that is used to prioritize the BFS on. 965249261Sdim /// 966249261Sdim /// In case of equal penalties, we want to prefer states that were inserted 967249261Sdim /// first. During state generation we make sure that we insert states first 968249261Sdim /// that break the line as late as possible. 969249261Sdim typedef std::pair<unsigned, unsigned> OrderedPenalty; 970249261Sdim 971249261Sdim /// \brief An item in the prioritized BFS search queue. The \c StateNode's 972249261Sdim /// \c State has the given \c OrderedPenalty. 973249261Sdim typedef std::pair<OrderedPenalty, StateNode *> QueueItem; 974249261Sdim 975249261Sdim /// \brief The BFS queue type. 976249261Sdim typedef std::priority_queue<QueueItem, std::vector<QueueItem>, 977249261Sdim std::greater<QueueItem> > QueueType; 978249261Sdim 979261991Sdim /// \brief Get the offset of the line relatively to the level. 980261991Sdim /// 981261991Sdim /// For example, 'public:' labels in classes are offset by 1 or 2 982261991Sdim /// characters to the left from their level. 983261991Sdim int getIndentOffset(const FormatToken &RootToken) { 984261991Sdim if (RootToken.isAccessSpecifier(false) || RootToken.isObjCAccessSpecifier()) 985261991Sdim return Style.AccessModifierOffset; 986261991Sdim return 0; 987261991Sdim } 988261991Sdim 989261991Sdim /// \brief Add a new line and the required indent before the first Token 990261991Sdim /// of the \c UnwrappedLine if there was no structural parsing error. 991261991Sdim void formatFirstToken(FormatToken &RootToken, 992261991Sdim const AnnotatedLine *PreviousLine, unsigned IndentLevel, 993261991Sdim unsigned Indent, bool InPPDirective) { 994261991Sdim unsigned Newlines = 995261991Sdim std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1); 996261991Sdim // Remove empty lines before "}" where applicable. 997261991Sdim if (RootToken.is(tok::r_brace) && 998261991Sdim (!RootToken.Next || 999261991Sdim (RootToken.Next->is(tok::semi) && !RootToken.Next->Next))) 1000261991Sdim Newlines = std::min(Newlines, 1u); 1001261991Sdim if (Newlines == 0 && !RootToken.IsFirst) 1002261991Sdim Newlines = 1; 1003276479Sdim if (RootToken.IsFirst && !RootToken.HasUnescapedNewline) 1004276479Sdim Newlines = 0; 1005261991Sdim 1006276479Sdim // Remove empty lines after "{". 1007276479Sdim if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine && 1008276479Sdim PreviousLine->Last->is(tok::l_brace) && 1009276479Sdim PreviousLine->First->isNot(tok::kw_namespace)) 1010276479Sdim Newlines = 1; 1011276479Sdim 1012261991Sdim // Insert extra new line before access specifiers. 1013261991Sdim if (PreviousLine && PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) && 1014261991Sdim RootToken.isAccessSpecifier() && RootToken.NewlinesBefore == 1) 1015261991Sdim ++Newlines; 1016261991Sdim 1017261991Sdim // Remove empty lines after access specifiers. 1018261991Sdim if (PreviousLine && PreviousLine->First->isAccessSpecifier()) 1019261991Sdim Newlines = std::min(1u, Newlines); 1020261991Sdim 1021276479Sdim Whitespaces->replaceWhitespace(RootToken, Newlines, IndentLevel, Indent, 1022276479Sdim Indent, InPPDirective && 1023276479Sdim !RootToken.HasUnescapedNewline); 1024261991Sdim } 1025261991Sdim 1026261991Sdim /// \brief Get the indent of \p Level from \p IndentForLevel. 1027261991Sdim /// 1028261991Sdim /// \p IndentForLevel must contain the indent for the level \c l 1029261991Sdim /// at \p IndentForLevel[l], or a value < 0 if the indent for 1030261991Sdim /// that level is unknown. 1031261991Sdim unsigned getIndent(const std::vector<int> IndentForLevel, unsigned Level) { 1032261991Sdim if (IndentForLevel[Level] != -1) 1033261991Sdim return IndentForLevel[Level]; 1034261991Sdim if (Level == 0) 1035261991Sdim return 0; 1036261991Sdim return getIndent(IndentForLevel, Level - 1) + Style.IndentWidth; 1037261991Sdim } 1038261991Sdim 1039261991Sdim void join(AnnotatedLine &A, const AnnotatedLine &B) { 1040261991Sdim assert(!A.Last->Next); 1041261991Sdim assert(!B.First->Previous); 1042276479Sdim if (B.Affected) 1043276479Sdim A.Affected = true; 1044261991Sdim A.Last->Next = B.First; 1045261991Sdim B.First->Previous = A.Last; 1046261991Sdim B.First->CanBreakBefore = true; 1047261991Sdim unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore; 1048261991Sdim for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) { 1049261991Sdim Tok->TotalLength += LengthA; 1050261991Sdim A.Last = Tok; 1051261991Sdim } 1052261991Sdim } 1053261991Sdim 1054261991Sdim unsigned getColumnLimit(bool InPPDirective) const { 1055261991Sdim // In preprocessor directives reserve two chars for trailing " \" 1056261991Sdim return Style.ColumnLimit - (InPPDirective ? 2 : 0); 1057261991Sdim } 1058261991Sdim 1059276479Sdim struct CompareLineStatePointers { 1060276479Sdim bool operator()(LineState *obj1, LineState *obj2) const { 1061276479Sdim return *obj1 < *obj2; 1062261991Sdim } 1063276479Sdim }; 1064261991Sdim 1065249261Sdim /// \brief Analyze the entire solution space starting from \p InitialState. 1066249261Sdim /// 1067249261Sdim /// This implements a variant of Dijkstra's algorithm on the graph that spans 1068249261Sdim /// the solution space (\c LineStates are the nodes). The algorithm tries to 1069249261Sdim /// find the shortest path (the one with lowest penalty) from \p InitialState 1070261991Sdim /// to a state where all tokens are placed. Returns the penalty. 1071261991Sdim /// 1072261991Sdim /// If \p DryRun is \c false, directly applies the changes. 1073261991Sdim unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun = false) { 1074276479Sdim std::set<LineState *, CompareLineStatePointers> Seen; 1075249261Sdim 1076261991Sdim // Increasing count of \c StateNode items we have created. This is used to 1077261991Sdim // create a deterministic order independent of the container. 1078261991Sdim unsigned Count = 0; 1079261991Sdim QueueType Queue; 1080261991Sdim 1081249261Sdim // Insert start element into queue. 1082249261Sdim StateNode *Node = 1083276479Sdim new (Allocator.Allocate()) StateNode(InitialState, false, nullptr); 1084249261Sdim Queue.push(QueueItem(OrderedPenalty(0, Count), Node)); 1085249261Sdim ++Count; 1086249261Sdim 1087261991Sdim unsigned Penalty = 0; 1088261991Sdim 1089249261Sdim // While not empty, take first element and follow edges. 1090249261Sdim while (!Queue.empty()) { 1091261991Sdim Penalty = Queue.top().first.first; 1092249261Sdim StateNode *Node = Queue.top().second; 1093276479Sdim if (!Node->State.NextToken) { 1094261991Sdim DEBUG(llvm::dbgs() << "\n---\nPenalty for line: " << Penalty << "\n"); 1095249261Sdim break; 1096249261Sdim } 1097249261Sdim Queue.pop(); 1098249261Sdim 1099261991Sdim // Cut off the analysis of certain solutions if the analysis gets too 1100261991Sdim // complex. See description of IgnoreStackForComparison. 1101261991Sdim if (Count > 10000) 1102261991Sdim Node->State.IgnoreStackForComparison = true; 1103261991Sdim 1104276479Sdim if (!Seen.insert(&Node->State).second) 1105249261Sdim // State already examined with lower penalty. 1106249261Sdim continue; 1107249261Sdim 1108261991Sdim FormatDecision LastFormat = Node->State.NextToken->Decision; 1109261991Sdim if (LastFormat == FD_Unformatted || LastFormat == FD_Continue) 1110261991Sdim addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue); 1111261991Sdim if (LastFormat == FD_Unformatted || LastFormat == FD_Break) 1112261991Sdim addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue); 1113249261Sdim } 1114249261Sdim 1115261991Sdim if (Queue.empty()) { 1116249261Sdim // We were unable to find a solution, do nothing. 1117249261Sdim // FIXME: Add diagnostic? 1118261991Sdim DEBUG(llvm::dbgs() << "Could not find a solution.\n"); 1119249261Sdim return 0; 1120261991Sdim } 1121249261Sdim 1122249261Sdim // Reconstruct the solution. 1123261991Sdim if (!DryRun) 1124261991Sdim reconstructPath(InitialState, Queue.top().second); 1125249261Sdim 1126261991Sdim DEBUG(llvm::dbgs() << "Total number of analyzed states: " << Count << "\n"); 1127261991Sdim DEBUG(llvm::dbgs() << "---\n"); 1128261991Sdim 1129261991Sdim return Penalty; 1130249261Sdim } 1131249261Sdim 1132249261Sdim void reconstructPath(LineState &State, StateNode *Current) { 1133261991Sdim std::deque<StateNode *> Path; 1134261991Sdim // We do not need a break before the initial token. 1135261991Sdim while (Current->Previous) { 1136261991Sdim Path.push_front(Current); 1137261991Sdim Current = Current->Previous; 1138261991Sdim } 1139261991Sdim for (std::deque<StateNode *>::iterator I = Path.begin(), E = Path.end(); 1140261991Sdim I != E; ++I) { 1141261991Sdim unsigned Penalty = 0; 1142261991Sdim formatChildren(State, (*I)->NewLine, /*DryRun=*/false, Penalty); 1143261991Sdim Penalty += Indenter->addTokenToState(State, (*I)->NewLine, false); 1144261991Sdim 1145261991Sdim DEBUG({ 1146261991Sdim if ((*I)->NewLine) { 1147261991Sdim llvm::dbgs() << "Penalty for placing " 1148261991Sdim << (*I)->Previous->State.NextToken->Tok.getName() << ": " 1149261991Sdim << Penalty << "\n"; 1150261991Sdim } 1151261991Sdim }); 1152261991Sdim } 1153249261Sdim } 1154249261Sdim 1155249261Sdim /// \brief Add the following state to the analysis queue \c Queue. 1156249261Sdim /// 1157249261Sdim /// Assume the current state is \p PreviousNode and has been reached with a 1158249261Sdim /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true. 1159249261Sdim void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode, 1160261991Sdim bool NewLine, unsigned *Count, QueueType *Queue) { 1161261991Sdim if (NewLine && !Indenter->canBreak(PreviousNode->State)) 1162249261Sdim return; 1163261991Sdim if (!NewLine && Indenter->mustBreak(PreviousNode->State)) 1164249261Sdim return; 1165249261Sdim 1166249261Sdim StateNode *Node = new (Allocator.Allocate()) 1167249261Sdim StateNode(PreviousNode->State, NewLine, PreviousNode); 1168261991Sdim if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty)) 1169261991Sdim return; 1170249261Sdim 1171261991Sdim Penalty += Indenter->addTokenToState(Node->State, NewLine, true); 1172249261Sdim 1173261991Sdim Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node)); 1174261991Sdim ++(*Count); 1175249261Sdim } 1176249261Sdim 1177261991Sdim /// \brief If the \p State's next token is an r_brace closing a nested block, 1178261991Sdim /// format the nested block before it. 1179261991Sdim /// 1180261991Sdim /// Returns \c true if all children could be placed successfully and adapts 1181261991Sdim /// \p Penalty as well as \p State. If \p DryRun is false, also directly 1182261991Sdim /// creates changes using \c Whitespaces. 1183261991Sdim /// 1184261991Sdim /// The crucial idea here is that children always get formatted upon 1185261991Sdim /// encountering the closing brace right after the nested block. Now, if we 1186261991Sdim /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is 1187261991Sdim /// \c false), the entire block has to be kept on the same line (which is only 1188261991Sdim /// possible if it fits on the line, only contains a single statement, etc. 1189261991Sdim /// 1190261991Sdim /// If \p NewLine is true, we format the nested block on separate lines, i.e. 1191261991Sdim /// break after the "{", format all lines with correct indentation and the put 1192261991Sdim /// the closing "}" on yet another new line. 1193261991Sdim /// 1194261991Sdim /// This enables us to keep the simple structure of the 1195261991Sdim /// \c UnwrappedLineFormatter, where we only have two options for each token: 1196261991Sdim /// break or don't break. 1197261991Sdim bool formatChildren(LineState &State, bool NewLine, bool DryRun, 1198261991Sdim unsigned &Penalty) { 1199261991Sdim FormatToken &Previous = *State.NextToken->Previous; 1200261991Sdim const FormatToken *LBrace = State.NextToken->getPreviousNonComment(); 1201261991Sdim if (!LBrace || LBrace->isNot(tok::l_brace) || 1202261991Sdim LBrace->BlockKind != BK_Block || Previous.Children.size() == 0) 1203261991Sdim // The previous token does not open a block. Nothing to do. We don't 1204261991Sdim // assert so that we can simply call this function for all tokens. 1205249261Sdim return true; 1206261991Sdim 1207261991Sdim if (NewLine) { 1208276479Sdim int AdditionalIndent = 1209276479Sdim State.FirstIndent - State.Line->Level * Style.IndentWidth; 1210276479Sdim if (State.Stack.size() < 2 || 1211276479Sdim !State.Stack[State.Stack.size() - 2].JSFunctionInlined) { 1212276479Sdim AdditionalIndent = State.Stack.back().Indent - 1213276479Sdim Previous.Children[0]->Level * Style.IndentWidth; 1214276479Sdim } 1215276479Sdim 1216276479Sdim Penalty += format(Previous.Children, DryRun, AdditionalIndent, 1217276479Sdim /*FixBadIndentation=*/true); 1218249261Sdim return true; 1219261991Sdim } 1220249261Sdim 1221261991Sdim // Cannot merge multiple statements into a single line. 1222261991Sdim if (Previous.Children.size() > 1) 1223276479Sdim return false; 1224261991Sdim 1225276479Sdim // Cannot merge into one line if this line ends on a comment. 1226276479Sdim if (Previous.is(tok::comment)) 1227276479Sdim return false; 1228276479Sdim 1229261991Sdim // We can't put the closing "}" on a line with a trailing comment. 1230261991Sdim if (Previous.Children[0]->Last->isTrailingComment()) 1231261991Sdim return false; 1232261991Sdim 1233276479Sdim // If the child line exceeds the column limit, we wouldn't want to merge it. 1234276479Sdim // We add +2 for the trailing " }". 1235276479Sdim if (Style.ColumnLimit > 0 && 1236276479Sdim Previous.Children[0]->Last->TotalLength + State.Column + 2 > 1237276479Sdim Style.ColumnLimit) 1238276479Sdim return false; 1239276479Sdim 1240261991Sdim if (!DryRun) { 1241261991Sdim Whitespaces->replaceWhitespace( 1242261991Sdim *Previous.Children[0]->First, 1243261991Sdim /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1, 1244261991Sdim /*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective); 1245261991Sdim } 1246261991Sdim Penalty += format(*Previous.Children[0], State.Column + 1, DryRun); 1247261991Sdim 1248261991Sdim State.Column += 1 + Previous.Children[0]->Last->TotalLength; 1249261991Sdim return true; 1250249261Sdim } 1251249261Sdim 1252261991Sdim ContinuationIndenter *Indenter; 1253261991Sdim WhitespaceManager *Whitespaces; 1254249261Sdim FormatStyle Style; 1255261991Sdim LineJoiner Joiner; 1256249261Sdim 1257249261Sdim llvm::SpecificBumpPtrAllocator<StateNode> Allocator; 1258276479Sdim 1259276479Sdim // Cache to store the penalty of formatting a vector of AnnotatedLines 1260276479Sdim // starting from a specific additional offset. Improves performance if there 1261276479Sdim // are many nested blocks. 1262276479Sdim std::map<std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned>, 1263276479Sdim unsigned> PenaltyCache; 1264249261Sdim}; 1265249261Sdim 1266261991Sdimclass FormatTokenLexer { 1267249261Sdimpublic: 1268261991Sdim FormatTokenLexer(Lexer &Lex, SourceManager &SourceMgr, FormatStyle &Style, 1269261991Sdim encoding::Encoding Encoding) 1270276479Sdim : FormatTok(nullptr), IsFirstToken(true), GreaterStashed(false), 1271276479Sdim Column(0), TrailingWhitespace(0), Lex(Lex), SourceMgr(SourceMgr), 1272276479Sdim Style(Style), IdentTable(getFormattingLangOpts()), Encoding(Encoding), 1273276479Sdim FirstInLineIndex(0) { 1274249261Sdim Lex.SetKeepWhitespaceMode(true); 1275276479Sdim 1276276479Sdim for (const std::string &ForEachMacro : Style.ForEachMacros) 1277276479Sdim ForEachMacros.push_back(&IdentTable.get(ForEachMacro)); 1278276479Sdim std::sort(ForEachMacros.begin(), ForEachMacros.end()); 1279249261Sdim } 1280249261Sdim 1281261991Sdim ArrayRef<FormatToken *> lex() { 1282261991Sdim assert(Tokens.empty()); 1283276479Sdim assert(FirstInLineIndex == 0); 1284261991Sdim do { 1285261991Sdim Tokens.push_back(getNextToken()); 1286276479Sdim tryMergePreviousTokens(); 1287276479Sdim if (Tokens.back()->NewlinesBefore > 0) 1288276479Sdim FirstInLineIndex = Tokens.size() - 1; 1289261991Sdim } while (Tokens.back()->Tok.isNot(tok::eof)); 1290261991Sdim return Tokens; 1291261991Sdim } 1292261991Sdim 1293261991Sdim IdentifierTable &getIdentTable() { return IdentTable; } 1294261991Sdim 1295261991Sdimprivate: 1296276479Sdim void tryMergePreviousTokens() { 1297276479Sdim if (tryMerge_TMacro()) 1298276479Sdim return; 1299276479Sdim if (tryMergeConflictMarkers()) 1300276479Sdim return; 1301276479Sdim 1302276479Sdim if (Style.Language == FormatStyle::LK_JavaScript) { 1303276479Sdim if (tryMergeEscapeSequence()) 1304276479Sdim return; 1305276479Sdim if (tryMergeJSRegexLiteral()) 1306276479Sdim return; 1307276479Sdim 1308276479Sdim static tok::TokenKind JSIdentity[] = { tok::equalequal, tok::equal }; 1309276479Sdim static tok::TokenKind JSNotIdentity[] = { tok::exclaimequal, tok::equal }; 1310276479Sdim static tok::TokenKind JSShiftEqual[] = { tok::greater, tok::greater, 1311276479Sdim tok::greaterequal }; 1312276479Sdim static tok::TokenKind JSRightArrow[] = { tok::equal, tok::greater }; 1313276479Sdim // FIXME: We probably need to change token type to mimic operator with the 1314276479Sdim // correct priority. 1315276479Sdim if (tryMergeTokens(JSIdentity)) 1316276479Sdim return; 1317276479Sdim if (tryMergeTokens(JSNotIdentity)) 1318276479Sdim return; 1319276479Sdim if (tryMergeTokens(JSShiftEqual)) 1320276479Sdim return; 1321276479Sdim if (tryMergeTokens(JSRightArrow)) 1322276479Sdim return; 1323276479Sdim } 1324276479Sdim } 1325276479Sdim 1326276479Sdim bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds) { 1327276479Sdim if (Tokens.size() < Kinds.size()) 1328276479Sdim return false; 1329276479Sdim 1330276479Sdim SmallVectorImpl<FormatToken *>::const_iterator First = 1331276479Sdim Tokens.end() - Kinds.size(); 1332276479Sdim if (!First[0]->is(Kinds[0])) 1333276479Sdim return false; 1334276479Sdim unsigned AddLength = 0; 1335276479Sdim for (unsigned i = 1; i < Kinds.size(); ++i) { 1336276479Sdim if (!First[i]->is(Kinds[i]) || First[i]->WhitespaceRange.getBegin() != 1337276479Sdim First[i]->WhitespaceRange.getEnd()) 1338276479Sdim return false; 1339276479Sdim AddLength += First[i]->TokenText.size(); 1340276479Sdim } 1341276479Sdim Tokens.resize(Tokens.size() - Kinds.size() + 1); 1342276479Sdim First[0]->TokenText = StringRef(First[0]->TokenText.data(), 1343276479Sdim First[0]->TokenText.size() + AddLength); 1344276479Sdim First[0]->ColumnWidth += AddLength; 1345276479Sdim return true; 1346276479Sdim } 1347276479Sdim 1348276479Sdim // Tries to merge an escape sequence, i.e. a "\\" and the following 1349276479Sdim // character. Use e.g. inside JavaScript regex literals. 1350276479Sdim bool tryMergeEscapeSequence() { 1351276479Sdim if (Tokens.size() < 2) 1352276479Sdim return false; 1353276479Sdim FormatToken *Previous = Tokens[Tokens.size() - 2]; 1354276479Sdim if (Previous->isNot(tok::unknown) || Previous->TokenText != "\\" || 1355276479Sdim Tokens.back()->NewlinesBefore != 0) 1356276479Sdim return false; 1357276479Sdim Previous->ColumnWidth += Tokens.back()->ColumnWidth; 1358276479Sdim StringRef Text = Previous->TokenText; 1359276479Sdim Previous->TokenText = 1360276479Sdim StringRef(Text.data(), Text.size() + Tokens.back()->TokenText.size()); 1361276479Sdim Tokens.resize(Tokens.size() - 1); 1362276479Sdim return true; 1363276479Sdim } 1364276479Sdim 1365276479Sdim // Try to determine whether the current token ends a JavaScript regex literal. 1366276479Sdim // We heuristically assume that this is a regex literal if we find two 1367276479Sdim // unescaped slashes on a line and the token before the first slash is one of 1368276479Sdim // "(;,{}![:?", a binary operator or 'return', as those cannot be followed by 1369276479Sdim // a division. 1370276479Sdim bool tryMergeJSRegexLiteral() { 1371276479Sdim if (Tokens.size() < 2 || Tokens.back()->isNot(tok::slash) || 1372276479Sdim (Tokens[Tokens.size() - 2]->is(tok::unknown) && 1373276479Sdim Tokens[Tokens.size() - 2]->TokenText == "\\")) 1374276479Sdim return false; 1375276479Sdim unsigned TokenCount = 0; 1376276479Sdim unsigned LastColumn = Tokens.back()->OriginalColumn; 1377276479Sdim for (auto I = Tokens.rbegin() + 1, E = Tokens.rend(); I != E; ++I) { 1378276479Sdim ++TokenCount; 1379276479Sdim if (I[0]->is(tok::slash) && I + 1 != E && 1380276479Sdim (I[1]->isOneOf(tok::l_paren, tok::semi, tok::l_brace, tok::r_brace, 1381276479Sdim tok::exclaim, tok::l_square, tok::colon, tok::comma, 1382276479Sdim tok::question, tok::kw_return) || 1383276479Sdim I[1]->isBinaryOperator())) { 1384276479Sdim Tokens.resize(Tokens.size() - TokenCount); 1385276479Sdim Tokens.back()->Tok.setKind(tok::unknown); 1386276479Sdim Tokens.back()->Type = TT_RegexLiteral; 1387276479Sdim Tokens.back()->ColumnWidth += LastColumn - I[0]->OriginalColumn; 1388276479Sdim return true; 1389276479Sdim } 1390276479Sdim 1391276479Sdim // There can't be a newline inside a regex literal. 1392276479Sdim if (I[0]->NewlinesBefore > 0) 1393276479Sdim return false; 1394276479Sdim } 1395276479Sdim return false; 1396276479Sdim } 1397276479Sdim 1398276479Sdim bool tryMerge_TMacro() { 1399261991Sdim if (Tokens.size() < 4) 1400276479Sdim return false; 1401261991Sdim FormatToken *Last = Tokens.back(); 1402261991Sdim if (!Last->is(tok::r_paren)) 1403276479Sdim return false; 1404261991Sdim 1405261991Sdim FormatToken *String = Tokens[Tokens.size() - 2]; 1406261991Sdim if (!String->is(tok::string_literal) || String->IsMultiline) 1407276479Sdim return false; 1408261991Sdim 1409261991Sdim if (!Tokens[Tokens.size() - 3]->is(tok::l_paren)) 1410276479Sdim return false; 1411261991Sdim 1412261991Sdim FormatToken *Macro = Tokens[Tokens.size() - 4]; 1413261991Sdim if (Macro->TokenText != "_T") 1414276479Sdim return false; 1415261991Sdim 1416261991Sdim const char *Start = Macro->TokenText.data(); 1417261991Sdim const char *End = Last->TokenText.data() + Last->TokenText.size(); 1418261991Sdim String->TokenText = StringRef(Start, End - Start); 1419261991Sdim String->IsFirst = Macro->IsFirst; 1420261991Sdim String->LastNewlineOffset = Macro->LastNewlineOffset; 1421261991Sdim String->WhitespaceRange = Macro->WhitespaceRange; 1422261991Sdim String->OriginalColumn = Macro->OriginalColumn; 1423261991Sdim String->ColumnWidth = encoding::columnWidthWithTabs( 1424261991Sdim String->TokenText, String->OriginalColumn, Style.TabWidth, Encoding); 1425261991Sdim 1426261991Sdim Tokens.pop_back(); 1427261991Sdim Tokens.pop_back(); 1428261991Sdim Tokens.pop_back(); 1429261991Sdim Tokens.back() = String; 1430276479Sdim return true; 1431261991Sdim } 1432261991Sdim 1433276479Sdim bool tryMergeConflictMarkers() { 1434276479Sdim if (Tokens.back()->NewlinesBefore == 0 && Tokens.back()->isNot(tok::eof)) 1435276479Sdim return false; 1436276479Sdim 1437276479Sdim // Conflict lines look like: 1438276479Sdim // <marker> <text from the vcs> 1439276479Sdim // For example: 1440276479Sdim // >>>>>>> /file/in/file/system at revision 1234 1441276479Sdim // 1442276479Sdim // We merge all tokens in a line that starts with a conflict marker 1443276479Sdim // into a single token with a special token type that the unwrapped line 1444276479Sdim // parser will use to correctly rebuild the underlying code. 1445276479Sdim 1446276479Sdim FileID ID; 1447276479Sdim // Get the position of the first token in the line. 1448276479Sdim unsigned FirstInLineOffset; 1449276479Sdim std::tie(ID, FirstInLineOffset) = SourceMgr.getDecomposedLoc( 1450276479Sdim Tokens[FirstInLineIndex]->getStartOfNonWhitespace()); 1451276479Sdim StringRef Buffer = SourceMgr.getBuffer(ID)->getBuffer(); 1452276479Sdim // Calculate the offset of the start of the current line. 1453276479Sdim auto LineOffset = Buffer.rfind('\n', FirstInLineOffset); 1454276479Sdim if (LineOffset == StringRef::npos) { 1455276479Sdim LineOffset = 0; 1456276479Sdim } else { 1457276479Sdim ++LineOffset; 1458276479Sdim } 1459276479Sdim 1460276479Sdim auto FirstSpace = Buffer.find_first_of(" \n", LineOffset); 1461276479Sdim StringRef LineStart; 1462276479Sdim if (FirstSpace == StringRef::npos) { 1463276479Sdim LineStart = Buffer.substr(LineOffset); 1464276479Sdim } else { 1465276479Sdim LineStart = Buffer.substr(LineOffset, FirstSpace - LineOffset); 1466276479Sdim } 1467276479Sdim 1468276479Sdim TokenType Type = TT_Unknown; 1469276479Sdim if (LineStart == "<<<<<<<" || LineStart == ">>>>") { 1470276479Sdim Type = TT_ConflictStart; 1471276479Sdim } else if (LineStart == "|||||||" || LineStart == "=======" || 1472276479Sdim LineStart == "====") { 1473276479Sdim Type = TT_ConflictAlternative; 1474276479Sdim } else if (LineStart == ">>>>>>>" || LineStart == "<<<<") { 1475276479Sdim Type = TT_ConflictEnd; 1476276479Sdim } 1477276479Sdim 1478276479Sdim if (Type != TT_Unknown) { 1479276479Sdim FormatToken *Next = Tokens.back(); 1480276479Sdim 1481276479Sdim Tokens.resize(FirstInLineIndex + 1); 1482276479Sdim // We do not need to build a complete token here, as we will skip it 1483276479Sdim // during parsing anyway (as we must not touch whitespace around conflict 1484276479Sdim // markers). 1485276479Sdim Tokens.back()->Type = Type; 1486276479Sdim Tokens.back()->Tok.setKind(tok::kw___unknown_anytype); 1487276479Sdim 1488276479Sdim Tokens.push_back(Next); 1489276479Sdim return true; 1490276479Sdim } 1491276479Sdim 1492276479Sdim return false; 1493276479Sdim } 1494276479Sdim 1495261991Sdim FormatToken *getNextToken() { 1496249261Sdim if (GreaterStashed) { 1497261991Sdim // Create a synthesized second '>' token. 1498261991Sdim // FIXME: Increment Column and set OriginalColumn. 1499261991Sdim Token Greater = FormatTok->Tok; 1500261991Sdim FormatTok = new (Allocator.Allocate()) FormatToken; 1501261991Sdim FormatTok->Tok = Greater; 1502261991Sdim SourceLocation GreaterLocation = 1503261991Sdim FormatTok->Tok.getLocation().getLocWithOffset(1); 1504261991Sdim FormatTok->WhitespaceRange = 1505261991Sdim SourceRange(GreaterLocation, GreaterLocation); 1506261991Sdim FormatTok->TokenText = ">"; 1507261991Sdim FormatTok->ColumnWidth = 1; 1508249261Sdim GreaterStashed = false; 1509249261Sdim return FormatTok; 1510249261Sdim } 1511249261Sdim 1512261991Sdim FormatTok = new (Allocator.Allocate()) FormatToken; 1513261991Sdim readRawToken(*FormatTok); 1514261991Sdim SourceLocation WhitespaceStart = 1515261991Sdim FormatTok->Tok.getLocation().getLocWithOffset(-TrailingWhitespace); 1516261991Sdim FormatTok->IsFirst = IsFirstToken; 1517261991Sdim IsFirstToken = false; 1518249261Sdim 1519249261Sdim // Consume and record whitespace until we find a significant token. 1520261991Sdim unsigned WhitespaceLength = TrailingWhitespace; 1521261991Sdim while (FormatTok->Tok.is(tok::unknown)) { 1522261991Sdim for (int i = 0, e = FormatTok->TokenText.size(); i != e; ++i) { 1523261991Sdim switch (FormatTok->TokenText[i]) { 1524261991Sdim case '\n': 1525261991Sdim ++FormatTok->NewlinesBefore; 1526261991Sdim // FIXME: This is technically incorrect, as it could also 1527261991Sdim // be a literal backslash at the end of the line. 1528261991Sdim if (i == 0 || (FormatTok->TokenText[i - 1] != '\\' && 1529261991Sdim (FormatTok->TokenText[i - 1] != '\r' || i == 1 || 1530261991Sdim FormatTok->TokenText[i - 2] != '\\'))) 1531261991Sdim FormatTok->HasUnescapedNewline = true; 1532261991Sdim FormatTok->LastNewlineOffset = WhitespaceLength + i + 1; 1533261991Sdim Column = 0; 1534261991Sdim break; 1535261991Sdim case '\r': 1536261991Sdim case '\f': 1537261991Sdim case '\v': 1538261991Sdim Column = 0; 1539261991Sdim break; 1540261991Sdim case ' ': 1541261991Sdim ++Column; 1542261991Sdim break; 1543261991Sdim case '\t': 1544261991Sdim Column += Style.TabWidth - Column % Style.TabWidth; 1545261991Sdim break; 1546261991Sdim case '\\': 1547261991Sdim ++Column; 1548261991Sdim if (i + 1 == e || (FormatTok->TokenText[i + 1] != '\r' && 1549261991Sdim FormatTok->TokenText[i + 1] != '\n')) 1550261991Sdim FormatTok->Type = TT_ImplicitStringLiteral; 1551261991Sdim break; 1552261991Sdim default: 1553261991Sdim FormatTok->Type = TT_ImplicitStringLiteral; 1554261991Sdim ++Column; 1555261991Sdim break; 1556261991Sdim } 1557261991Sdim } 1558249261Sdim 1559261991Sdim if (FormatTok->Type == TT_ImplicitStringLiteral) 1560261991Sdim break; 1561261991Sdim WhitespaceLength += FormatTok->Tok.getLength(); 1562249261Sdim 1563261991Sdim readRawToken(*FormatTok); 1564251662Sdim } 1565251662Sdim 1566249261Sdim // In case the token starts with escaped newlines, we want to 1567249261Sdim // take them into account as whitespace - this pattern is quite frequent 1568249261Sdim // in macro definitions. 1569249261Sdim // FIXME: Add a more explicit test. 1570261991Sdim while (FormatTok->TokenText.size() > 1 && FormatTok->TokenText[0] == '\\' && 1571261991Sdim FormatTok->TokenText[1] == '\n') { 1572276479Sdim ++FormatTok->NewlinesBefore; 1573261991Sdim WhitespaceLength += 2; 1574261991Sdim Column = 0; 1575261991Sdim FormatTok->TokenText = FormatTok->TokenText.substr(2); 1576249261Sdim } 1577249261Sdim 1578261991Sdim FormatTok->WhitespaceRange = SourceRange( 1579261991Sdim WhitespaceStart, WhitespaceStart.getLocWithOffset(WhitespaceLength)); 1580249261Sdim 1581261991Sdim FormatTok->OriginalColumn = Column; 1582261991Sdim 1583261991Sdim TrailingWhitespace = 0; 1584261991Sdim if (FormatTok->Tok.is(tok::comment)) { 1585261991Sdim // FIXME: Add the trimmed whitespace to Column. 1586261991Sdim StringRef UntrimmedText = FormatTok->TokenText; 1587261991Sdim FormatTok->TokenText = FormatTok->TokenText.rtrim(" \t\v\f"); 1588261991Sdim TrailingWhitespace = UntrimmedText.size() - FormatTok->TokenText.size(); 1589261991Sdim } else if (FormatTok->Tok.is(tok::raw_identifier)) { 1590261991Sdim IdentifierInfo &Info = IdentTable.get(FormatTok->TokenText); 1591261991Sdim FormatTok->Tok.setIdentifierInfo(&Info); 1592261991Sdim FormatTok->Tok.setKind(Info.getTokenID()); 1593261991Sdim } else if (FormatTok->Tok.is(tok::greatergreater)) { 1594261991Sdim FormatTok->Tok.setKind(tok::greater); 1595261991Sdim FormatTok->TokenText = FormatTok->TokenText.substr(0, 1); 1596249261Sdim GreaterStashed = true; 1597249261Sdim } 1598249261Sdim 1599261991Sdim // Now FormatTok is the next non-whitespace token. 1600261991Sdim 1601261991Sdim StringRef Text = FormatTok->TokenText; 1602261991Sdim size_t FirstNewlinePos = Text.find('\n'); 1603261991Sdim if (FirstNewlinePos == StringRef::npos) { 1604261991Sdim // FIXME: ColumnWidth actually depends on the start column, we need to 1605261991Sdim // take this into account when the token is moved. 1606261991Sdim FormatTok->ColumnWidth = 1607261991Sdim encoding::columnWidthWithTabs(Text, Column, Style.TabWidth, Encoding); 1608261991Sdim Column += FormatTok->ColumnWidth; 1609261991Sdim } else { 1610261991Sdim FormatTok->IsMultiline = true; 1611261991Sdim // FIXME: ColumnWidth actually depends on the start column, we need to 1612261991Sdim // take this into account when the token is moved. 1613261991Sdim FormatTok->ColumnWidth = encoding::columnWidthWithTabs( 1614261991Sdim Text.substr(0, FirstNewlinePos), Column, Style.TabWidth, Encoding); 1615261991Sdim 1616261991Sdim // The last line of the token always starts in column 0. 1617261991Sdim // Thus, the length can be precomputed even in the presence of tabs. 1618261991Sdim FormatTok->LastLineColumnWidth = encoding::columnWidthWithTabs( 1619261991Sdim Text.substr(Text.find_last_of('\n') + 1), 0, Style.TabWidth, 1620261991Sdim Encoding); 1621261991Sdim Column = FormatTok->LastLineColumnWidth; 1622261991Sdim } 1623261991Sdim 1624276479Sdim FormatTok->IsForEachMacro = 1625276479Sdim std::binary_search(ForEachMacros.begin(), ForEachMacros.end(), 1626276479Sdim FormatTok->Tok.getIdentifierInfo()); 1627276479Sdim 1628249261Sdim return FormatTok; 1629249261Sdim } 1630249261Sdim 1631261991Sdim FormatToken *FormatTok; 1632261991Sdim bool IsFirstToken; 1633249261Sdim bool GreaterStashed; 1634261991Sdim unsigned Column; 1635261991Sdim unsigned TrailingWhitespace; 1636249261Sdim Lexer &Lex; 1637249261Sdim SourceManager &SourceMgr; 1638261991Sdim FormatStyle &Style; 1639249261Sdim IdentifierTable IdentTable; 1640261991Sdim encoding::Encoding Encoding; 1641261991Sdim llvm::SpecificBumpPtrAllocator<FormatToken> Allocator; 1642276479Sdim // Index (in 'Tokens') of the last token that starts a new line. 1643276479Sdim unsigned FirstInLineIndex; 1644261991Sdim SmallVector<FormatToken *, 16> Tokens; 1645276479Sdim SmallVector<IdentifierInfo *, 8> ForEachMacros; 1646249261Sdim 1647261991Sdim void readRawToken(FormatToken &Tok) { 1648261991Sdim Lex.LexFromRawLexer(Tok.Tok); 1649261991Sdim Tok.TokenText = StringRef(SourceMgr.getCharacterData(Tok.Tok.getLocation()), 1650261991Sdim Tok.Tok.getLength()); 1651261991Sdim // For formatting, treat unterminated string literals like normal string 1652261991Sdim // literals. 1653276479Sdim if (Tok.is(tok::unknown)) { 1654276479Sdim if (!Tok.TokenText.empty() && Tok.TokenText[0] == '"') { 1655276479Sdim Tok.Tok.setKind(tok::string_literal); 1656276479Sdim Tok.IsUnterminatedLiteral = true; 1657276479Sdim } else if (Style.Language == FormatStyle::LK_JavaScript && 1658276479Sdim Tok.TokenText == "''") { 1659276479Sdim Tok.Tok.setKind(tok::char_constant); 1660276479Sdim } 1661261991Sdim } 1662249261Sdim } 1663249261Sdim}; 1664249261Sdim 1665276479Sdimstatic StringRef getLanguageName(FormatStyle::LanguageKind Language) { 1666276479Sdim switch (Language) { 1667276479Sdim case FormatStyle::LK_Cpp: 1668276479Sdim return "C++"; 1669276479Sdim case FormatStyle::LK_JavaScript: 1670276479Sdim return "JavaScript"; 1671276479Sdim case FormatStyle::LK_Proto: 1672276479Sdim return "Proto"; 1673276479Sdim default: 1674276479Sdim return "Unknown"; 1675276479Sdim } 1676276479Sdim} 1677276479Sdim 1678249261Sdimclass Formatter : public UnwrappedLineConsumer { 1679249261Sdimpublic: 1680261991Sdim Formatter(const FormatStyle &Style, Lexer &Lex, SourceManager &SourceMgr, 1681249261Sdim const std::vector<CharSourceRange> &Ranges) 1682261991Sdim : Style(Style), Lex(Lex), SourceMgr(SourceMgr), 1683261991Sdim Whitespaces(SourceMgr, Style, inputUsesCRLF(Lex.getBuffer())), 1684261991Sdim Ranges(Ranges.begin(), Ranges.end()), UnwrappedLines(1), 1685261991Sdim Encoding(encoding::detectEncoding(Lex.getBuffer())) { 1686261991Sdim DEBUG(llvm::dbgs() << "File encoding: " 1687261991Sdim << (Encoding == encoding::Encoding_UTF8 ? "UTF8" 1688261991Sdim : "unknown") 1689261991Sdim << "\n"); 1690276479Sdim DEBUG(llvm::dbgs() << "Language: " << getLanguageName(Style.Language) 1691276479Sdim << "\n"); 1692261991Sdim } 1693249261Sdim 1694261991Sdim tooling::Replacements format() { 1695261991Sdim tooling::Replacements Result; 1696261991Sdim FormatTokenLexer Tokens(Lex, SourceMgr, Style, Encoding); 1697249261Sdim 1698261991Sdim UnwrappedLineParser Parser(Style, Tokens.lex(), *this); 1699251662Sdim bool StructuralError = Parser.parse(); 1700261991Sdim assert(UnwrappedLines.rbegin()->empty()); 1701261991Sdim for (unsigned Run = 0, RunE = UnwrappedLines.size(); Run + 1 != RunE; 1702261991Sdim ++Run) { 1703261991Sdim DEBUG(llvm::dbgs() << "Run " << Run << "...\n"); 1704261991Sdim SmallVector<AnnotatedLine *, 16> AnnotatedLines; 1705261991Sdim for (unsigned i = 0, e = UnwrappedLines[Run].size(); i != e; ++i) { 1706261991Sdim AnnotatedLines.push_back(new AnnotatedLine(UnwrappedLines[Run][i])); 1707261991Sdim } 1708261991Sdim tooling::Replacements RunResult = 1709261991Sdim format(AnnotatedLines, StructuralError, Tokens); 1710261991Sdim DEBUG({ 1711261991Sdim llvm::dbgs() << "Replacements for run " << Run << ":\n"; 1712261991Sdim for (tooling::Replacements::iterator I = RunResult.begin(), 1713261991Sdim E = RunResult.end(); 1714261991Sdim I != E; ++I) { 1715261991Sdim llvm::dbgs() << I->toString() << "\n"; 1716261991Sdim } 1717261991Sdim }); 1718261991Sdim for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1719261991Sdim delete AnnotatedLines[i]; 1720261991Sdim } 1721261991Sdim Result.insert(RunResult.begin(), RunResult.end()); 1722261991Sdim Whitespaces.reset(); 1723261991Sdim } 1724261991Sdim return Result; 1725261991Sdim } 1726261991Sdim 1727261991Sdim tooling::Replacements format(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 1728261991Sdim bool StructuralError, FormatTokenLexer &Tokens) { 1729261991Sdim TokenAnnotator Annotator(Style, Tokens.getIdentTable().get("in")); 1730249261Sdim for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1731261991Sdim Annotator.annotate(*AnnotatedLines[i]); 1732249261Sdim } 1733261991Sdim deriveLocalStyle(AnnotatedLines); 1734249261Sdim for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1735261991Sdim Annotator.calculateFormattingInformation(*AnnotatedLines[i]); 1736251662Sdim } 1737276479Sdim computeAffectedLines(AnnotatedLines.begin(), AnnotatedLines.end()); 1738249261Sdim 1739261991Sdim Annotator.setCommentLineLevels(AnnotatedLines); 1740261991Sdim ContinuationIndenter Indenter(Style, SourceMgr, Whitespaces, Encoding, 1741261991Sdim BinPackInconclusiveFunctions); 1742276479Sdim UnwrappedLineFormatter Formatter(&Indenter, &Whitespaces, Style); 1743261991Sdim Formatter.format(AnnotatedLines, /*DryRun=*/false); 1744249261Sdim return Whitespaces.generateReplacements(); 1745249261Sdim } 1746249261Sdim 1747249261Sdimprivate: 1748276479Sdim // Determines which lines are affected by the SourceRanges given as input. 1749276479Sdim // Returns \c true if at least one line between I and E or one of their 1750276479Sdim // children is affected. 1751276479Sdim bool computeAffectedLines(SmallVectorImpl<AnnotatedLine *>::iterator I, 1752276479Sdim SmallVectorImpl<AnnotatedLine *>::iterator E) { 1753276479Sdim bool SomeLineAffected = false; 1754276479Sdim const AnnotatedLine *PreviousLine = nullptr; 1755276479Sdim while (I != E) { 1756276479Sdim AnnotatedLine *Line = *I; 1757276479Sdim Line->LeadingEmptyLinesAffected = affectsLeadingEmptyLines(*Line->First); 1758276479Sdim 1759276479Sdim // If a line is part of a preprocessor directive, it needs to be formatted 1760276479Sdim // if any token within the directive is affected. 1761276479Sdim if (Line->InPPDirective) { 1762276479Sdim FormatToken *Last = Line->Last; 1763276479Sdim SmallVectorImpl<AnnotatedLine *>::iterator PPEnd = I + 1; 1764276479Sdim while (PPEnd != E && !(*PPEnd)->First->HasUnescapedNewline) { 1765276479Sdim Last = (*PPEnd)->Last; 1766276479Sdim ++PPEnd; 1767276479Sdim } 1768276479Sdim 1769276479Sdim if (affectsTokenRange(*Line->First, *Last, 1770276479Sdim /*IncludeLeadingNewlines=*/false)) { 1771276479Sdim SomeLineAffected = true; 1772276479Sdim markAllAsAffected(I, PPEnd); 1773276479Sdim } 1774276479Sdim I = PPEnd; 1775276479Sdim continue; 1776276479Sdim } 1777276479Sdim 1778276479Sdim if (nonPPLineAffected(Line, PreviousLine)) 1779276479Sdim SomeLineAffected = true; 1780276479Sdim 1781276479Sdim PreviousLine = Line; 1782276479Sdim ++I; 1783276479Sdim } 1784276479Sdim return SomeLineAffected; 1785276479Sdim } 1786276479Sdim 1787276479Sdim // Determines whether 'Line' is affected by the SourceRanges given as input. 1788276479Sdim // Returns \c true if line or one if its children is affected. 1789276479Sdim bool nonPPLineAffected(AnnotatedLine *Line, 1790276479Sdim const AnnotatedLine *PreviousLine) { 1791276479Sdim bool SomeLineAffected = false; 1792276479Sdim Line->ChildrenAffected = 1793276479Sdim computeAffectedLines(Line->Children.begin(), Line->Children.end()); 1794276479Sdim if (Line->ChildrenAffected) 1795276479Sdim SomeLineAffected = true; 1796276479Sdim 1797276479Sdim // Stores whether one of the line's tokens is directly affected. 1798276479Sdim bool SomeTokenAffected = false; 1799276479Sdim // Stores whether we need to look at the leading newlines of the next token 1800276479Sdim // in order to determine whether it was affected. 1801276479Sdim bool IncludeLeadingNewlines = false; 1802276479Sdim 1803276479Sdim // Stores whether the first child line of any of this line's tokens is 1804276479Sdim // affected. 1805276479Sdim bool SomeFirstChildAffected = false; 1806276479Sdim 1807276479Sdim for (FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) { 1808276479Sdim // Determine whether 'Tok' was affected. 1809276479Sdim if (affectsTokenRange(*Tok, *Tok, IncludeLeadingNewlines)) 1810276479Sdim SomeTokenAffected = true; 1811276479Sdim 1812276479Sdim // Determine whether the first child of 'Tok' was affected. 1813276479Sdim if (!Tok->Children.empty() && Tok->Children.front()->Affected) 1814276479Sdim SomeFirstChildAffected = true; 1815276479Sdim 1816276479Sdim IncludeLeadingNewlines = Tok->Children.empty(); 1817276479Sdim } 1818276479Sdim 1819276479Sdim // Was this line moved, i.e. has it previously been on the same line as an 1820276479Sdim // affected line? 1821276479Sdim bool LineMoved = PreviousLine && PreviousLine->Affected && 1822276479Sdim Line->First->NewlinesBefore == 0; 1823276479Sdim 1824276479Sdim bool IsContinuedComment = 1825276479Sdim Line->First->is(tok::comment) && Line->First->Next == nullptr && 1826276479Sdim Line->First->NewlinesBefore < 2 && PreviousLine && 1827276479Sdim PreviousLine->Affected && PreviousLine->Last->is(tok::comment); 1828276479Sdim 1829276479Sdim if (SomeTokenAffected || SomeFirstChildAffected || LineMoved || 1830276479Sdim IsContinuedComment) { 1831276479Sdim Line->Affected = true; 1832276479Sdim SomeLineAffected = true; 1833276479Sdim } 1834276479Sdim return SomeLineAffected; 1835276479Sdim } 1836276479Sdim 1837276479Sdim // Marks all lines between I and E as well as all their children as affected. 1838276479Sdim void markAllAsAffected(SmallVectorImpl<AnnotatedLine *>::iterator I, 1839276479Sdim SmallVectorImpl<AnnotatedLine *>::iterator E) { 1840276479Sdim while (I != E) { 1841276479Sdim (*I)->Affected = true; 1842276479Sdim markAllAsAffected((*I)->Children.begin(), (*I)->Children.end()); 1843276479Sdim ++I; 1844276479Sdim } 1845276479Sdim } 1846276479Sdim 1847276479Sdim // Returns true if the range from 'First' to 'Last' intersects with one of the 1848276479Sdim // input ranges. 1849276479Sdim bool affectsTokenRange(const FormatToken &First, const FormatToken &Last, 1850276479Sdim bool IncludeLeadingNewlines) { 1851276479Sdim SourceLocation Start = First.WhitespaceRange.getBegin(); 1852276479Sdim if (!IncludeLeadingNewlines) 1853276479Sdim Start = Start.getLocWithOffset(First.LastNewlineOffset); 1854276479Sdim SourceLocation End = Last.getStartOfNonWhitespace(); 1855276479Sdim if (Last.TokenText.size() > 0) 1856276479Sdim End = End.getLocWithOffset(Last.TokenText.size() - 1); 1857276479Sdim CharSourceRange Range = CharSourceRange::getCharRange(Start, End); 1858276479Sdim return affectsCharSourceRange(Range); 1859276479Sdim } 1860276479Sdim 1861276479Sdim // Returns true if one of the input ranges intersect the leading empty lines 1862276479Sdim // before 'Tok'. 1863276479Sdim bool affectsLeadingEmptyLines(const FormatToken &Tok) { 1864276479Sdim CharSourceRange EmptyLineRange = CharSourceRange::getCharRange( 1865276479Sdim Tok.WhitespaceRange.getBegin(), 1866276479Sdim Tok.WhitespaceRange.getBegin().getLocWithOffset(Tok.LastNewlineOffset)); 1867276479Sdim return affectsCharSourceRange(EmptyLineRange); 1868276479Sdim } 1869276479Sdim 1870276479Sdim // Returns true if 'Range' intersects with one of the input ranges. 1871276479Sdim bool affectsCharSourceRange(const CharSourceRange &Range) { 1872276479Sdim for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(), 1873276479Sdim E = Ranges.end(); 1874276479Sdim I != E; ++I) { 1875276479Sdim if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), I->getBegin()) && 1876276479Sdim !SourceMgr.isBeforeInTranslationUnit(I->getEnd(), Range.getBegin())) 1877276479Sdim return true; 1878276479Sdim } 1879276479Sdim return false; 1880276479Sdim } 1881276479Sdim 1882261991Sdim static bool inputUsesCRLF(StringRef Text) { 1883261991Sdim return Text.count('\r') * 2 > Text.count('\n'); 1884261991Sdim } 1885261991Sdim 1886261991Sdim void 1887261991Sdim deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) { 1888249261Sdim unsigned CountBoundToVariable = 0; 1889249261Sdim unsigned CountBoundToType = 0; 1890249261Sdim bool HasCpp03IncompatibleFormat = false; 1891261991Sdim bool HasBinPackedFunction = false; 1892261991Sdim bool HasOnePerLineFunction = false; 1893249261Sdim for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) { 1894261991Sdim if (!AnnotatedLines[i]->First->Next) 1895249261Sdim continue; 1896261991Sdim FormatToken *Tok = AnnotatedLines[i]->First->Next; 1897261991Sdim while (Tok->Next) { 1898249261Sdim if (Tok->Type == TT_PointerOrReference) { 1899261991Sdim bool SpacesBefore = 1900261991Sdim Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd(); 1901261991Sdim bool SpacesAfter = Tok->Next->WhitespaceRange.getBegin() != 1902261991Sdim Tok->Next->WhitespaceRange.getEnd(); 1903249261Sdim if (SpacesBefore && !SpacesAfter) 1904249261Sdim ++CountBoundToVariable; 1905249261Sdim else if (!SpacesBefore && SpacesAfter) 1906249261Sdim ++CountBoundToType; 1907249261Sdim } 1908249261Sdim 1909261991Sdim if (Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) { 1910261991Sdim if (Tok->is(tok::coloncolon) && 1911261991Sdim Tok->Previous->Type == TT_TemplateOpener) 1912261991Sdim HasCpp03IncompatibleFormat = true; 1913261991Sdim if (Tok->Type == TT_TemplateCloser && 1914261991Sdim Tok->Previous->Type == TT_TemplateCloser) 1915261991Sdim HasCpp03IncompatibleFormat = true; 1916261991Sdim } 1917261991Sdim 1918261991Sdim if (Tok->PackingKind == PPK_BinPacked) 1919261991Sdim HasBinPackedFunction = true; 1920261991Sdim if (Tok->PackingKind == PPK_OnePerLine) 1921261991Sdim HasOnePerLineFunction = true; 1922261991Sdim 1923261991Sdim Tok = Tok->Next; 1924249261Sdim } 1925249261Sdim } 1926276479Sdim if (Style.DerivePointerAlignment) { 1927249261Sdim if (CountBoundToType > CountBoundToVariable) 1928276479Sdim Style.PointerAlignment = FormatStyle::PAS_Left; 1929249261Sdim else if (CountBoundToType < CountBoundToVariable) 1930276479Sdim Style.PointerAlignment = FormatStyle::PAS_Right; 1931249261Sdim } 1932249261Sdim if (Style.Standard == FormatStyle::LS_Auto) { 1933249261Sdim Style.Standard = HasCpp03IncompatibleFormat ? FormatStyle::LS_Cpp11 1934249261Sdim : FormatStyle::LS_Cpp03; 1935249261Sdim } 1936261991Sdim BinPackInconclusiveFunctions = 1937261991Sdim HasBinPackedFunction || !HasOnePerLineFunction; 1938249261Sdim } 1939249261Sdim 1940276479Sdim void consumeUnwrappedLine(const UnwrappedLine &TheLine) override { 1941261991Sdim assert(!UnwrappedLines.empty()); 1942261991Sdim UnwrappedLines.back().push_back(TheLine); 1943249261Sdim } 1944249261Sdim 1945276479Sdim void finishRun() override { 1946261991Sdim UnwrappedLines.push_back(SmallVector<UnwrappedLine, 16>()); 1947249261Sdim } 1948249261Sdim 1949261991Sdim FormatStyle Style; 1950261991Sdim Lexer &Lex; 1951261991Sdim SourceManager &SourceMgr; 1952261991Sdim WhitespaceManager Whitespaces; 1953261991Sdim SmallVector<CharSourceRange, 8> Ranges; 1954261991Sdim SmallVector<SmallVector<UnwrappedLine, 16>, 2> UnwrappedLines; 1955249261Sdim 1956261991Sdim encoding::Encoding Encoding; 1957261991Sdim bool BinPackInconclusiveFunctions; 1958261991Sdim}; 1959249261Sdim 1960261991Sdim} // end anonymous namespace 1961249261Sdim 1962261991Sdimtooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex, 1963261991Sdim SourceManager &SourceMgr, 1964261991Sdim std::vector<CharSourceRange> Ranges) { 1965276479Sdim if (Style.DisableFormat) { 1966276479Sdim tooling::Replacements EmptyResult; 1967276479Sdim return EmptyResult; 1968276479Sdim } 1969276479Sdim 1970261991Sdim Formatter formatter(Style, Lex, SourceMgr, Ranges); 1971261991Sdim return formatter.format(); 1972261991Sdim} 1973249261Sdim 1974261991Sdimtooling::Replacements reformat(const FormatStyle &Style, StringRef Code, 1975261991Sdim std::vector<tooling::Range> Ranges, 1976261991Sdim StringRef FileName) { 1977261991Sdim FileManager Files((FileSystemOptions())); 1978261991Sdim DiagnosticsEngine Diagnostics( 1979261991Sdim IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), 1980261991Sdim new DiagnosticOptions); 1981261991Sdim SourceManager SourceMgr(Diagnostics, Files); 1982261991Sdim llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(Code, FileName); 1983261991Sdim const clang::FileEntry *Entry = 1984261991Sdim Files.getVirtualFile(FileName, Buf->getBufferSize(), 0); 1985261991Sdim SourceMgr.overrideFileContents(Entry, Buf); 1986261991Sdim FileID ID = 1987261991Sdim SourceMgr.createFileID(Entry, SourceLocation(), clang::SrcMgr::C_User); 1988261991Sdim Lexer Lex(ID, SourceMgr.getBuffer(ID), SourceMgr, 1989261991Sdim getFormattingLangOpts(Style.Standard)); 1990261991Sdim SourceLocation StartOfFile = SourceMgr.getLocForStartOfFile(ID); 1991261991Sdim std::vector<CharSourceRange> CharRanges; 1992261991Sdim for (unsigned i = 0, e = Ranges.size(); i != e; ++i) { 1993261991Sdim SourceLocation Start = StartOfFile.getLocWithOffset(Ranges[i].getOffset()); 1994261991Sdim SourceLocation End = Start.getLocWithOffset(Ranges[i].getLength()); 1995261991Sdim CharRanges.push_back(CharSourceRange::getCharRange(Start, End)); 1996249261Sdim } 1997261991Sdim return reformat(Style, Lex, SourceMgr, CharRanges); 1998261991Sdim} 1999249261Sdim 2000261991SdimLangOptions getFormattingLangOpts(FormatStyle::LanguageStandard Standard) { 2001261991Sdim LangOptions LangOpts; 2002261991Sdim LangOpts.CPlusPlus = 1; 2003261991Sdim LangOpts.CPlusPlus11 = Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2004276479Sdim LangOpts.CPlusPlus1y = Standard == FormatStyle::LS_Cpp03 ? 0 : 1; 2005261991Sdim LangOpts.LineComment = 1; 2006276479Sdim LangOpts.CXXOperatorNames = 1; 2007261991Sdim LangOpts.Bool = 1; 2008261991Sdim LangOpts.ObjC1 = 1; 2009261991Sdim LangOpts.ObjC2 = 1; 2010261991Sdim return LangOpts; 2011261991Sdim} 2012249261Sdim 2013261991Sdimconst char *StyleOptionHelpDescription = 2014261991Sdim "Coding style, currently supports:\n" 2015261991Sdim " LLVM, Google, Chromium, Mozilla, WebKit.\n" 2016261991Sdim "Use -style=file to load style configuration from\n" 2017261991Sdim ".clang-format file located in one of the parent\n" 2018261991Sdim "directories of the source file (or current\n" 2019261991Sdim "directory for stdin).\n" 2020261991Sdim "Use -style=\"{key: value, ...}\" to set specific\n" 2021261991Sdim "parameters, e.g.:\n" 2022261991Sdim " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\""; 2023249261Sdim 2024276479Sdimstatic FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) { 2025276479Sdim if (FileName.endswith_lower(".js")) { 2026276479Sdim return FormatStyle::LK_JavaScript; 2027276479Sdim } else if (FileName.endswith_lower(".proto") || 2028276479Sdim FileName.endswith_lower(".protodevel")) { 2029276479Sdim return FormatStyle::LK_Proto; 2030276479Sdim } 2031276479Sdim return FormatStyle::LK_Cpp; 2032276479Sdim} 2033249261Sdim 2034276479SdimFormatStyle getStyle(StringRef StyleName, StringRef FileName, 2035276479Sdim StringRef FallbackStyle) { 2036276479Sdim FormatStyle Style = getLLVMStyle(); 2037276479Sdim Style.Language = getLanguageByFileName(FileName); 2038276479Sdim if (!getPredefinedStyle(FallbackStyle, Style.Language, &Style)) { 2039276479Sdim llvm::errs() << "Invalid fallback style \"" << FallbackStyle 2040276479Sdim << "\" using LLVM style\n"; 2041276479Sdim return Style; 2042276479Sdim } 2043276479Sdim 2044261991Sdim if (StyleName.startswith("{")) { 2045261991Sdim // Parse YAML/JSON style from the command line. 2046276479Sdim if (std::error_code ec = parseConfiguration(StyleName, &Style)) { 2047261991Sdim llvm::errs() << "Error parsing -style: " << ec.message() << ", using " 2048261991Sdim << FallbackStyle << " style\n"; 2049249261Sdim } 2050261991Sdim return Style; 2051249261Sdim } 2052249261Sdim 2053261991Sdim if (!StyleName.equals_lower("file")) { 2054276479Sdim if (!getPredefinedStyle(StyleName, Style.Language, &Style)) 2055261991Sdim llvm::errs() << "Invalid value for -style, using " << FallbackStyle 2056261991Sdim << " style\n"; 2057261991Sdim return Style; 2058249261Sdim } 2059249261Sdim 2060276479Sdim // Look for .clang-format/_clang-format file in the file's parent directories. 2061276479Sdim SmallString<128> UnsuitableConfigFiles; 2062261991Sdim SmallString<128> Path(FileName); 2063261991Sdim llvm::sys::fs::make_absolute(Path); 2064261991Sdim for (StringRef Directory = Path; !Directory.empty(); 2065261991Sdim Directory = llvm::sys::path::parent_path(Directory)) { 2066261991Sdim if (!llvm::sys::fs::is_directory(Directory)) 2067261991Sdim continue; 2068261991Sdim SmallString<128> ConfigFile(Directory); 2069249261Sdim 2070261991Sdim llvm::sys::path::append(ConfigFile, ".clang-format"); 2071261991Sdim DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2072261991Sdim bool IsFile = false; 2073261991Sdim // Ignore errors from is_regular_file: we only need to know if we can read 2074261991Sdim // the file or not. 2075261991Sdim llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile); 2076261991Sdim 2077261991Sdim if (!IsFile) { 2078261991Sdim // Try _clang-format too, since dotfiles are not commonly used on Windows. 2079261991Sdim ConfigFile = Directory; 2080261991Sdim llvm::sys::path::append(ConfigFile, "_clang-format"); 2081261991Sdim DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); 2082261991Sdim llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile); 2083249261Sdim } 2084249261Sdim 2085261991Sdim if (IsFile) { 2086276479Sdim llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 2087276479Sdim llvm::MemoryBuffer::getFile(ConfigFile.c_str()); 2088276479Sdim if (std::error_code EC = Text.getError()) { 2089276479Sdim llvm::errs() << EC.message() << "\n"; 2090276479Sdim break; 2091261991Sdim } 2092276479Sdim if (std::error_code ec = 2093276479Sdim parseConfiguration(Text.get()->getBuffer(), &Style)) { 2094276479Sdim if (ec == ParseError::Unsuitable) { 2095276479Sdim if (!UnsuitableConfigFiles.empty()) 2096276479Sdim UnsuitableConfigFiles.append(", "); 2097276479Sdim UnsuitableConfigFiles.append(ConfigFile); 2098276479Sdim continue; 2099276479Sdim } 2100261991Sdim llvm::errs() << "Error reading " << ConfigFile << ": " << ec.message() 2101261991Sdim << "\n"; 2102276479Sdim break; 2103261991Sdim } 2104261991Sdim DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n"); 2105261991Sdim return Style; 2106249261Sdim } 2107249261Sdim } 2108261991Sdim llvm::errs() << "Can't find usable .clang-format, using " << FallbackStyle 2109261991Sdim << " style\n"; 2110276479Sdim if (!UnsuitableConfigFiles.empty()) { 2111276479Sdim llvm::errs() << "Configuration file(s) do(es) not support " 2112276479Sdim << getLanguageName(Style.Language) << ": " 2113276479Sdim << UnsuitableConfigFiles << "\n"; 2114276479Sdim } 2115261991Sdim return Style; 2116249261Sdim} 2117249261Sdim 2118249261Sdim} // namespace format 2119249261Sdim} // namespace clang 2120