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