blob: cb07cb56a555da5a3d035bc8a805c82a3ed2c718 [file] [log] [blame]
Daniel Jasperbac016b2012-12-03 18:12:45 +00001//===--- 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///
Daniel Jasperbac016b2012-12-03 18:12:45 +000014//===----------------------------------------------------------------------===//
15
Manuel Klimekca547db2013-01-16 14:55:28 +000016#define DEBUG_TYPE "format-formatter"
17
Daniel Jasper6b2afe42013-08-16 11:20:30 +000018#include "ContinuationIndenter.h"
Daniel Jasper32d28ee2013-01-29 21:01:14 +000019#include "TokenAnnotator.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000020#include "UnwrappedLineParser.h"
Alexander Kornienko70ce7882013-04-15 14:28:00 +000021#include "WhitespaceManager.h"
Daniel Jasper8a999452013-05-16 10:40:07 +000022#include "clang/Basic/Diagnostic.h"
Chandler Carruthb99083e2013-01-02 10:28:36 +000023#include "clang/Basic/SourceManager.h"
Manuel Klimekca547db2013-01-16 14:55:28 +000024#include "clang/Format/Format.h"
Daniel Jasperbac016b2012-12-03 18:12:45 +000025#include "clang/Lex/Lexer.h"
Alexander Kornienko5262dd92013-03-27 11:52:18 +000026#include "llvm/ADT/STLExtras.h"
Manuel Klimek32a2fd72013-02-13 10:46:36 +000027#include "llvm/Support/Allocator.h"
Manuel Klimekca547db2013-01-16 14:55:28 +000028#include "llvm/Support/Debug.h"
Edwin Vanef4e12c82013-09-30 13:31:48 +000029#include "llvm/Support/Path.h"
Stephen Hines651f13c2014-04-23 16:59:28 -070030#include "llvm/Support/YAMLTraits.h"
Manuel Klimek32a2fd72013-02-13 10:46:36 +000031#include <queue>
Daniel Jasper8822d3a2012-12-04 13:02:32 +000032#include <string>
33
Stephen Hines651f13c2014-04-23 16:59:28 -070034using clang::format::FormatStyle;
35
36LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
37
Alexander Kornienkod71ec162013-05-07 15:32:14 +000038namespace llvm {
39namespace yaml {
Stephen Hines651f13c2014-04-23 16:59:28 -070040template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
41 static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) {
42 IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
43 IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
44 IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
45 }
46};
47
48template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {
49 static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) {
50 IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03);
51 IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03);
52 IO.enumCase(Value, "Cpp11", FormatStyle::LS_Cpp11);
53 IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11);
54 IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);
55 }
56};
57
58template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
59 static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) {
60 IO.enumCase(Value, "Never", FormatStyle::UT_Never);
61 IO.enumCase(Value, "false", FormatStyle::UT_Never);
62 IO.enumCase(Value, "Always", FormatStyle::UT_Always);
63 IO.enumCase(Value, "true", FormatStyle::UT_Always);
64 IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
65 }
66};
67
68template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {
69 static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) {
70 IO.enumCase(Value, "Attach", FormatStyle::BS_Attach);
71 IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);
72 IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);
73 IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);
74 IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);
75 }
76};
77
Alexander Kornienkod71ec162013-05-07 15:32:14 +000078template <>
Stephen Hines651f13c2014-04-23 16:59:28 -070079struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {
Manuel Klimek44135b82013-05-13 12:51:40 +000080 static void enumeration(IO &IO,
Stephen Hines651f13c2014-04-23 16:59:28 -070081 FormatStyle::NamespaceIndentationKind &Value) {
82 IO.enumCase(Value, "None", FormatStyle::NI_None);
83 IO.enumCase(Value, "Inner", FormatStyle::NI_Inner);
84 IO.enumCase(Value, "All", FormatStyle::NI_All);
Manuel Klimek44135b82013-05-13 12:51:40 +000085 }
86};
87
Daniel Jasper1fb8d882013-05-14 09:30:02 +000088template <>
Stephen Hines651f13c2014-04-23 16:59:28 -070089struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
Alexander Kornienkof0fc89c2013-10-14 00:46:35 +000090 static void enumeration(IO &IO,
Stephen Hines651f13c2014-04-23 16:59:28 -070091 FormatStyle::SpaceBeforeParensOptions &Value) {
92 IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
93 IO.enumCase(Value, "ControlStatements",
94 FormatStyle::SBPO_ControlStatements);
95 IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
96
97 // For backward compatibility.
98 IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
99 IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
Alexander Kornienko3d9ffcf2013-09-27 16:14:22 +0000100 }
101};
102
Stephen Hines651f13c2014-04-23 16:59:28 -0700103template <> struct MappingTraits<FormatStyle> {
104 static void mapping(IO &IO, FormatStyle &Style) {
105 // When reading, read the language first, we need it for getPredefinedStyle.
106 IO.mapOptional("Language", Style.Language);
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000107
Alexander Kornienkodd256312013-05-10 11:56:10 +0000108 if (IO.outputting()) {
Alexander Kornienko4e65c982013-09-02 16:39:23 +0000109 StringRef StylesArray[] = { "LLVM", "Google", "Chromium",
Stephen Hines651f13c2014-04-23 16:59:28 -0700110 "Mozilla", "WebKit", "GNU" };
Alexander Kornienkodd256312013-05-10 11:56:10 +0000111 ArrayRef<StringRef> Styles(StylesArray);
112 for (size_t i = 0, e = Styles.size(); i < e; ++i) {
113 StringRef StyleName(Styles[i]);
Stephen Hines651f13c2014-04-23 16:59:28 -0700114 FormatStyle PredefinedStyle;
115 if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
Alexander Kornienko885f87b2013-05-19 00:53:30 +0000116 Style == PredefinedStyle) {
Alexander Kornienkodd256312013-05-10 11:56:10 +0000117 IO.mapOptional("# BasedOnStyle", StyleName);
118 break;
119 }
120 }
121 } else {
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000122 StringRef BasedOnStyle;
123 IO.mapOptional("BasedOnStyle", BasedOnStyle);
Stephen Hines651f13c2014-04-23 16:59:28 -0700124 if (!BasedOnStyle.empty()) {
125 FormatStyle::LanguageKind OldLanguage = Style.Language;
126 FormatStyle::LanguageKind Language =
127 ((FormatStyle *)IO.getContext())->Language;
128 if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
Alexander Kornienko885f87b2013-05-19 00:53:30 +0000129 IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));
130 return;
131 }
Stephen Hines651f13c2014-04-23 16:59:28 -0700132 Style.Language = OldLanguage;
133 }
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000134 }
135
136 IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
Daniel Jasper6315fec2013-08-13 10:58:30 +0000137 IO.mapOptional("ConstructorInitializerIndentWidth",
138 Style.ConstructorInitializerIndentWidth);
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000139 IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft);
Daniel Jasper893ea8d2013-07-31 23:55:15 +0000140 IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000141 IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
142 Style.AllowAllParametersOfDeclarationOnNextLine);
143 IO.mapOptional("AllowShortIfStatementsOnASingleLine",
144 Style.AllowShortIfStatementsOnASingleLine);
Daniel Jasperf11bbb92013-05-16 12:12:21 +0000145 IO.mapOptional("AllowShortLoopsOnASingleLine",
146 Style.AllowShortLoopsOnASingleLine);
Stephen Hines651f13c2014-04-23 16:59:28 -0700147 IO.mapOptional("AllowShortFunctionsOnASingleLine",
148 Style.AllowShortFunctionsOnASingleLine);
Daniel Jasperbbc87762013-05-29 12:07:31 +0000149 IO.mapOptional("AlwaysBreakTemplateDeclarations",
150 Style.AlwaysBreakTemplateDeclarations);
Alexander Kornienko56312022013-07-04 12:02:44 +0000151 IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
152 Style.AlwaysBreakBeforeMultilineStrings);
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000153 IO.mapOptional("BreakBeforeBinaryOperators",
154 Style.BreakBeforeBinaryOperators);
Daniel Jasper1a896a52013-11-08 00:57:11 +0000155 IO.mapOptional("BreakBeforeTernaryOperators",
156 Style.BreakBeforeTernaryOperators);
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000157 IO.mapOptional("BreakConstructorInitializersBeforeComma",
158 Style.BreakConstructorInitializersBeforeComma);
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000159 IO.mapOptional("BinPackParameters", Style.BinPackParameters);
160 IO.mapOptional("ColumnLimit", Style.ColumnLimit);
161 IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
162 Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
163 IO.mapOptional("DerivePointerBinding", Style.DerivePointerBinding);
Daniel Jasperc7bd68f2013-07-10 14:02:49 +0000164 IO.mapOptional("ExperimentalAutoDetectBinPacking",
165 Style.ExperimentalAutoDetectBinPacking);
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000166 IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
167 IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
Stephen Hines651f13c2014-04-23 16:59:28 -0700168 IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
169 Style.KeepEmptyLinesAtTheStartOfBlocks);
Daniel Jaspereff18b92013-07-31 23:16:02 +0000170 IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
Stephen Hines651f13c2014-04-23 16:59:28 -0700171 IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000172 IO.mapOptional("ObjCSpaceBeforeProtocolList",
173 Style.ObjCSpaceBeforeProtocolList);
Daniel Jasper47066e42013-10-25 14:29:37 +0000174 IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
175 Style.PenaltyBreakBeforeFirstCallParameter);
Alexander Kornienko2785b9a2013-06-07 16:02:52 +0000176 IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
177 IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
Daniel Jasperfaec47b2013-07-11 20:41:21 +0000178 IO.mapOptional("PenaltyBreakFirstLessLess",
179 Style.PenaltyBreakFirstLessLess);
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000180 IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
181 IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
182 Style.PenaltyReturnTypeOnItsOwnLine);
183 IO.mapOptional("PointerBindsToType", Style.PointerBindsToType);
184 IO.mapOptional("SpacesBeforeTrailingComments",
185 Style.SpacesBeforeTrailingComments);
Daniel Jasperb5dc3f42013-07-16 18:22:10 +0000186 IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000187 IO.mapOptional("Standard", Style.Standard);
Manuel Klimek07a64ec2013-05-13 08:42:42 +0000188 IO.mapOptional("IndentWidth", Style.IndentWidth);
Alexander Kornienko0b62cc32013-09-05 14:08:34 +0000189 IO.mapOptional("TabWidth", Style.TabWidth);
Manuel Klimek7c9a93e2013-05-13 09:22:11 +0000190 IO.mapOptional("UseTab", Style.UseTab);
Manuel Klimek44135b82013-05-13 12:51:40 +0000191 IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
Manuel Klimeka9a7f102013-06-21 17:25:42 +0000192 IO.mapOptional("IndentFunctionDeclarationAfterType",
193 Style.IndentFunctionDeclarationAfterType);
Daniel Jasper7df56bf2013-08-20 12:36:34 +0000194 IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
Daniel Jasperd8ee5c12013-10-29 14:52:02 +0000195 IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
Daniel Jasper34f3d052013-08-21 08:39:01 +0000196 IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses);
Daniel Jasper7df56bf2013-08-20 12:36:34 +0000197 IO.mapOptional("SpacesInCStyleCastParentheses",
198 Style.SpacesInCStyleCastParentheses);
Stephen Hines651f13c2014-04-23 16:59:28 -0700199 IO.mapOptional("SpacesInContainerLiterals",
200 Style.SpacesInContainerLiterals);
Daniel Jasper9b4de852013-09-25 15:15:02 +0000201 IO.mapOptional("SpaceBeforeAssignmentOperators",
202 Style.SpaceBeforeAssignmentOperators);
Daniel Jasperc2827ec2013-10-18 10:38:14 +0000203 IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
Stephen Hines651f13c2014-04-23 16:59:28 -0700204 IO.mapOptional("CommentPragmas", Style.CommentPragmas);
205 IO.mapOptional("ForEachMacros", Style.ForEachMacros);
206
207 // For backward compatibility.
208 if (!IO.outputting()) {
209 IO.mapOptional("SpaceAfterControlStatementKeyword",
210 Style.SpaceBeforeParens);
211 }
212 IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
213 }
214};
215
216// Allows to read vector<FormatStyle> while keeping default values.
217// IO.getContext() should contain a pointer to the FormatStyle structure, that
218// will be used to get default values for missing keys.
219// If the first element has no Language specified, it will be treated as the
220// default one for the following elements.
221template <> struct DocumentListTraits<std::vector<FormatStyle> > {
222 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
223 return Seq.size();
224 }
225 static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq,
226 size_t Index) {
227 if (Index >= Seq.size()) {
228 assert(Index == Seq.size());
229 FormatStyle Template;
230 if (Seq.size() > 0 && Seq[0].Language == FormatStyle::LK_None) {
231 Template = Seq[0];
232 } else {
233 Template = *((const FormatStyle*)IO.getContext());
234 Template.Language = FormatStyle::LK_None;
235 }
236 Seq.resize(Index + 1, Template);
237 }
238 return Seq[Index];
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000239 }
240};
241}
242}
243
Daniel Jasperbac016b2012-12-03 18:12:45 +0000244namespace clang {
245namespace format {
246
Daniel Jasperbac016b2012-12-03 18:12:45 +0000247FormatStyle getLLVMStyle() {
248 FormatStyle LLVMStyle;
Stephen Hines651f13c2014-04-23 16:59:28 -0700249 LLVMStyle.Language = FormatStyle::LK_Cpp;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000250 LLVMStyle.AccessModifierOffset = -2;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000251 LLVMStyle.AlignEscapedNewlinesLeft = false;
Daniel Jasper893ea8d2013-07-31 23:55:15 +0000252 LLVMStyle.AlignTrailingComments = true;
Daniel Jasperf1579602013-01-29 16:03:49 +0000253 LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
Stephen Hines651f13c2014-04-23 16:59:28 -0700254 LLVMStyle.AllowShortFunctionsOnASingleLine = true;
Daniel Jasper6f5bb2c2013-01-14 16:24:39 +0000255 LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
Daniel Jasperf11bbb92013-05-16 12:12:21 +0000256 LLVMStyle.AllowShortLoopsOnASingleLine = false;
Alexander Kornienko56312022013-07-04 12:02:44 +0000257 LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000258 LLVMStyle.AlwaysBreakTemplateDeclarations = false;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000259 LLVMStyle.BinPackParameters = true;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000260 LLVMStyle.BreakBeforeBinaryOperators = false;
Daniel Jasper1a896a52013-11-08 00:57:11 +0000261 LLVMStyle.BreakBeforeTernaryOperators = true;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000262 LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
263 LLVMStyle.BreakConstructorInitializersBeforeComma = false;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000264 LLVMStyle.ColumnLimit = 80;
Stephen Hines651f13c2014-04-23 16:59:28 -0700265 LLVMStyle.CommentPragmas = "^ IWYU pragma:";
Alexander Kornienkofb594862013-05-06 14:11:27 +0000266 LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
Daniel Jasper6315fec2013-08-13 10:58:30 +0000267 LLVMStyle.ConstructorInitializerIndentWidth = 4;
Stephen Hines651f13c2014-04-23 16:59:28 -0700268 LLVMStyle.ContinuationIndentWidth = 4;
269 LLVMStyle.Cpp11BracedListStyle = true;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000270 LLVMStyle.DerivePointerBinding = false;
Daniel Jasperc7bd68f2013-07-10 14:02:49 +0000271 LLVMStyle.ExperimentalAutoDetectBinPacking = false;
Stephen Hines651f13c2014-04-23 16:59:28 -0700272 LLVMStyle.ForEachMacros.push_back("foreach");
273 LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
274 LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
Alexander Kornienkofb594862013-05-06 14:11:27 +0000275 LLVMStyle.IndentCaseLabels = false;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000276 LLVMStyle.IndentFunctionDeclarationAfterType = false;
277 LLVMStyle.IndentWidth = 2;
Alexander Kornienko0b62cc32013-09-05 14:08:34 +0000278 LLVMStyle.TabWidth = 8;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000279 LLVMStyle.MaxEmptyLinesToKeep = 1;
Stephen Hines651f13c2014-04-23 16:59:28 -0700280 LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true;
Daniel Jaspereff18b92013-07-31 23:16:02 +0000281 LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
Stephen Hines651f13c2014-04-23 16:59:28 -0700282 LLVMStyle.ObjCSpaceAfterProperty = false;
Nico Weber5f500df2013-01-10 20:12:55 +0000283 LLVMStyle.ObjCSpaceBeforeProtocolList = true;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000284 LLVMStyle.PointerBindsToType = false;
285 LLVMStyle.SpacesBeforeTrailingComments = 1;
Stephen Hines651f13c2014-04-23 16:59:28 -0700286 LLVMStyle.Standard = FormatStyle::LS_Cpp11;
Alexander Kornienko3d9ffcf2013-09-27 16:14:22 +0000287 LLVMStyle.UseTab = FormatStyle::UT_Never;
Daniel Jasper7df56bf2013-08-20 12:36:34 +0000288 LLVMStyle.SpacesInParentheses = false;
289 LLVMStyle.SpaceInEmptyParentheses = false;
Stephen Hines651f13c2014-04-23 16:59:28 -0700290 LLVMStyle.SpacesInContainerLiterals = true;
Daniel Jasper7df56bf2013-08-20 12:36:34 +0000291 LLVMStyle.SpacesInCStyleCastParentheses = false;
Stephen Hines651f13c2014-04-23 16:59:28 -0700292 LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
Daniel Jasper9b4de852013-09-25 15:15:02 +0000293 LLVMStyle.SpaceBeforeAssignmentOperators = true;
Daniel Jasperd8ee5c12013-10-29 14:52:02 +0000294 LLVMStyle.SpacesInAngles = false;
Daniel Jasperfaec47b2013-07-11 20:41:21 +0000295
Stephen Hines651f13c2014-04-23 16:59:28 -0700296 LLVMStyle.PenaltyBreakComment = 300;
297 LLVMStyle.PenaltyBreakFirstLessLess = 120;
298 LLVMStyle.PenaltyBreakString = 1000;
299 LLVMStyle.PenaltyExcessCharacter = 1000000;
Daniel Jasperfaec47b2013-07-11 20:41:21 +0000300 LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
Daniel Jasper47066e42013-10-25 14:29:37 +0000301 LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
Daniel Jasperfaec47b2013-07-11 20:41:21 +0000302
Daniel Jasperbac016b2012-12-03 18:12:45 +0000303 return LLVMStyle;
304}
305
Stephen Hines651f13c2014-04-23 16:59:28 -0700306FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
307 FormatStyle GoogleStyle = getLLVMStyle();
308 GoogleStyle.Language = Language;
309
Daniel Jasperbac016b2012-12-03 18:12:45 +0000310 GoogleStyle.AccessModifierOffset = -1;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000311 GoogleStyle.AlignEscapedNewlinesLeft = true;
Daniel Jasper94d6ad72013-04-24 13:46:00 +0000312 GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
Daniel Jasper1bee0732013-05-23 18:05:18 +0000313 GoogleStyle.AllowShortLoopsOnASingleLine = true;
Alexander Kornienko56312022013-07-04 12:02:44 +0000314 GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000315 GoogleStyle.AlwaysBreakTemplateDeclarations = true;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000316 GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
317 GoogleStyle.DerivePointerBinding = true;
318 GoogleStyle.IndentCaseLabels = true;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000319 GoogleStyle.IndentFunctionDeclarationAfterType = true;
Stephen Hines651f13c2014-04-23 16:59:28 -0700320 GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
321 GoogleStyle.ObjCSpaceAfterProperty = false;
Nico Weber5f500df2013-01-10 20:12:55 +0000322 GoogleStyle.ObjCSpaceBeforeProtocolList = false;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000323 GoogleStyle.PointerBindsToType = true;
324 GoogleStyle.SpacesBeforeTrailingComments = 2;
325 GoogleStyle.Standard = FormatStyle::LS_Auto;
Daniel Jasperfaec47b2013-07-11 20:41:21 +0000326
Daniel Jasperfaec47b2013-07-11 20:41:21 +0000327 GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
Daniel Jasper47066e42013-10-25 14:29:37 +0000328 GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1;
Daniel Jasperfaec47b2013-07-11 20:41:21 +0000329
Stephen Hines651f13c2014-04-23 16:59:28 -0700330 if (Language == FormatStyle::LK_JavaScript) {
331 GoogleStyle.BreakBeforeTernaryOperators = false;
332 GoogleStyle.MaxEmptyLinesToKeep = 2;
333 GoogleStyle.SpacesInContainerLiterals = false;
334 } else if (Language == FormatStyle::LK_Proto) {
335 GoogleStyle.AllowShortFunctionsOnASingleLine = false;
336 }
337
Daniel Jasperbac016b2012-12-03 18:12:45 +0000338 return GoogleStyle;
339}
340
Stephen Hines651f13c2014-04-23 16:59:28 -0700341FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
342 FormatStyle ChromiumStyle = getGoogleStyle(Language);
Daniel Jasperf1579602013-01-29 16:03:49 +0000343 ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
Daniel Jasper94d6ad72013-04-24 13:46:00 +0000344 ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
Daniel Jasperf11bbb92013-05-16 12:12:21 +0000345 ChromiumStyle.AllowShortLoopsOnASingleLine = false;
Daniel Jasperfaab0d32013-02-27 09:47:53 +0000346 ChromiumStyle.BinPackParameters = false;
Daniel Jasper8ff690a2013-02-06 14:22:40 +0000347 ChromiumStyle.DerivePointerBinding = false;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000348 ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
Daniel Jasper6f5bb2c2013-01-14 16:24:39 +0000349 return ChromiumStyle;
350}
351
Alexander Kornienkofb594862013-05-06 14:11:27 +0000352FormatStyle getMozillaStyle() {
353 FormatStyle MozillaStyle = getLLVMStyle();
354 MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
Stephen Hines651f13c2014-04-23 16:59:28 -0700355 MozillaStyle.Cpp11BracedListStyle = false;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000356 MozillaStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
357 MozillaStyle.DerivePointerBinding = true;
358 MozillaStyle.IndentCaseLabels = true;
Stephen Hines651f13c2014-04-23 16:59:28 -0700359 MozillaStyle.ObjCSpaceAfterProperty = true;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000360 MozillaStyle.ObjCSpaceBeforeProtocolList = false;
361 MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
362 MozillaStyle.PointerBindsToType = true;
Stephen Hines651f13c2014-04-23 16:59:28 -0700363 MozillaStyle.Standard = FormatStyle::LS_Cpp03;
Alexander Kornienkofb594862013-05-06 14:11:27 +0000364 return MozillaStyle;
365}
366
Daniel Jaspere05dc6d2013-07-24 13:10:59 +0000367FormatStyle getWebKitStyle() {
368 FormatStyle Style = getLLVMStyle();
Daniel Jaspereff18b92013-07-31 23:16:02 +0000369 Style.AccessModifierOffset = -4;
Daniel Jasper893ea8d2013-07-31 23:55:15 +0000370 Style.AlignTrailingComments = false;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000371 Style.BreakBeforeBinaryOperators = true;
Daniel Jaspereff18b92013-07-31 23:16:02 +0000372 Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000373 Style.BreakConstructorInitializersBeforeComma = true;
Stephen Hines651f13c2014-04-23 16:59:28 -0700374 Style.Cpp11BracedListStyle = false;
Daniel Jaspereff18b92013-07-31 23:16:02 +0000375 Style.ColumnLimit = 0;
Daniel Jaspere8b10d32013-07-26 16:56:36 +0000376 Style.IndentWidth = 4;
Daniel Jaspereff18b92013-07-31 23:16:02 +0000377 Style.NamespaceIndentation = FormatStyle::NI_Inner;
Stephen Hines651f13c2014-04-23 16:59:28 -0700378 Style.ObjCSpaceAfterProperty = true;
Daniel Jaspere05dc6d2013-07-24 13:10:59 +0000379 Style.PointerBindsToType = true;
Stephen Hines651f13c2014-04-23 16:59:28 -0700380 Style.Standard = FormatStyle::LS_Cpp03;
Daniel Jaspere05dc6d2013-07-24 13:10:59 +0000381 return Style;
382}
383
Stephen Hines651f13c2014-04-23 16:59:28 -0700384FormatStyle getGNUStyle() {
385 FormatStyle Style = getLLVMStyle();
386 Style.BreakBeforeBinaryOperators = true;
387 Style.BreakBeforeBraces = FormatStyle::BS_GNU;
388 Style.BreakBeforeTernaryOperators = true;
389 Style.Cpp11BracedListStyle = false;
390 Style.ColumnLimit = 79;
391 Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
392 Style.Standard = FormatStyle::LS_Cpp03;
393 return Style;
394}
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000395
Stephen Hines651f13c2014-04-23 16:59:28 -0700396bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
397 FormatStyle *Style) {
398 if (Name.equals_lower("llvm")) {
399 *Style = getLLVMStyle();
400 } else if (Name.equals_lower("chromium")) {
401 *Style = getChromiumStyle(Language);
402 } else if (Name.equals_lower("mozilla")) {
403 *Style = getMozillaStyle();
404 } else if (Name.equals_lower("google")) {
405 *Style = getGoogleStyle(Language);
406 } else if (Name.equals_lower("webkit")) {
407 *Style = getWebKitStyle();
408 } else if (Name.equals_lower("gnu")) {
409 *Style = getGNUStyle();
410 } else {
411 return false;
412 }
413
414 Style->Language = Language;
Alexander Kornienko885f87b2013-05-19 00:53:30 +0000415 return true;
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000416}
417
418llvm::error_code parseConfiguration(StringRef Text, FormatStyle *Style) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700419 assert(Style);
420 FormatStyle::LanguageKind Language = Style->Language;
421 assert(Language != FormatStyle::LK_None);
Alexander Kornienko107db3c2013-05-20 15:18:01 +0000422 if (Text.trim().empty())
423 return llvm::make_error_code(llvm::errc::invalid_argument);
Stephen Hines651f13c2014-04-23 16:59:28 -0700424
425 std::vector<FormatStyle> Styles;
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000426 llvm::yaml::Input Input(Text);
Stephen Hines651f13c2014-04-23 16:59:28 -0700427 // DocumentListTraits<vector<FormatStyle>> uses the context to get default
428 // values for the fields, keys for which are missing from the configuration.
429 // Mapping also uses the context to get the language to find the correct
430 // base style.
431 Input.setContext(Style);
432 Input >> Styles;
433 if (Input.error())
434 return Input.error();
435
436 for (unsigned i = 0; i < Styles.size(); ++i) {
437 // Ensures that only the first configuration can skip the Language option.
438 if (Styles[i].Language == FormatStyle::LK_None && i != 0)
439 return llvm::make_error_code(llvm::errc::invalid_argument);
440 // Ensure that each language is configured at most once.
441 for (unsigned j = 0; j < i; ++j) {
442 if (Styles[i].Language == Styles[j].Language) {
443 DEBUG(llvm::dbgs()
444 << "Duplicate languages in the config file on positions " << j
445 << " and " << i << "\n");
446 return llvm::make_error_code(llvm::errc::invalid_argument);
447 }
448 }
449 }
450 // Look for a suitable configuration starting from the end, so we can
451 // find the configuration for the specific language first, and the default
452 // configuration (which can only be at slot 0) after it.
453 for (int i = Styles.size() - 1; i >= 0; --i) {
454 if (Styles[i].Language == Language ||
455 Styles[i].Language == FormatStyle::LK_None) {
456 *Style = Styles[i];
457 Style->Language = Language;
458 return llvm::make_error_code(llvm::errc::success);
459 }
460 }
461 return llvm::make_error_code(llvm::errc::not_supported);
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000462}
463
464std::string configurationAsText(const FormatStyle &Style) {
465 std::string Text;
466 llvm::raw_string_ostream Stream(Text);
467 llvm::yaml::Output Output(Stream);
468 // We use the same mapping method for input and output, so we need a non-const
469 // reference here.
470 FormatStyle NonConstStyle = Style;
471 Output << NonConstStyle;
Alexander Kornienko2b6acb62013-05-13 12:56:35 +0000472 return Stream.str();
Alexander Kornienkod71ec162013-05-07 15:32:14 +0000473}
474
Craig Topper83f81d72013-06-30 22:29:28 +0000475namespace {
476
Daniel Jasper6b2afe42013-08-16 11:20:30 +0000477class NoColumnLimitFormatter {
478public:
Daniel Jasper34f3d052013-08-21 08:39:01 +0000479 NoColumnLimitFormatter(ContinuationIndenter *Indenter) : Indenter(Indenter) {}
Daniel Jasper6b2afe42013-08-16 11:20:30 +0000480
481 /// \brief Formats the line starting at \p State, simply keeping all of the
482 /// input's line breaking decisions.
Daniel Jasper567dcf92013-09-05 09:29:45 +0000483 void format(unsigned FirstIndent, const AnnotatedLine *Line) {
Daniel Jasperb77d7412013-09-06 07:54:20 +0000484 LineState State =
485 Indenter->getInitialState(FirstIndent, Line, /*DryRun=*/false);
Daniel Jasper6b2afe42013-08-16 11:20:30 +0000486 while (State.NextToken != NULL) {
487 bool Newline =
488 Indenter->mustBreak(State) ||
489 (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);
490 Indenter->addTokenToState(State, Newline, /*DryRun=*/false);
491 }
492 }
Daniel Jasper34f3d052013-08-21 08:39:01 +0000493
Daniel Jasper6b2afe42013-08-16 11:20:30 +0000494private:
495 ContinuationIndenter *Indenter;
496};
497
Daniel Jasper4281d732013-11-06 23:12:09 +0000498class LineJoiner {
499public:
500 LineJoiner(const FormatStyle &Style) : Style(Style) {}
501
502 /// \brief Calculates how many lines can be merged into 1 starting at \p I.
503 unsigned
504 tryFitMultipleLinesInOne(unsigned Indent,
Stephen Hines651f13c2014-04-23 16:59:28 -0700505 SmallVectorImpl<AnnotatedLine *>::const_iterator I,
Daniel Jasper4281d732013-11-06 23:12:09 +0000506 SmallVectorImpl<AnnotatedLine *>::const_iterator E) {
507 // We can never merge stuff if there are trailing line comments.
Stephen Hines651f13c2014-04-23 16:59:28 -0700508 const AnnotatedLine *TheLine = *I;
Daniel Jasper4281d732013-11-06 23:12:09 +0000509 if (TheLine->Last->Type == TT_LineComment)
510 return 0;
511
Stephen Hines651f13c2014-04-23 16:59:28 -0700512 if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit)
Daniel Jasper4281d732013-11-06 23:12:09 +0000513 return 0;
514
Daniel Jasperc2e03292013-11-08 17:33:27 +0000515 unsigned Limit =
516 Style.ColumnLimit == 0 ? UINT_MAX : Style.ColumnLimit - Indent;
Daniel Jasper4281d732013-11-06 23:12:09 +0000517 // If we already exceed the column limit, we set 'Limit' to 0. The different
518 // tryMerge..() functions can then decide whether to still do merging.
519 Limit = TheLine->Last->TotalLength > Limit
520 ? 0
521 : Limit - TheLine->Last->TotalLength;
522
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000523 if (I + 1 == E || I[1]->Type == LT_Invalid)
Daniel Jasper4281d732013-11-06 23:12:09 +0000524 return 0;
525
Stephen Hines651f13c2014-04-23 16:59:28 -0700526 if (TheLine->Last->Type == TT_FunctionLBrace &&
527 TheLine->First != TheLine->Last) {
528 return Style.AllowShortFunctionsOnASingleLine
529 ? tryMergeSimpleBlock(I, E, Limit)
530 : 0;
531 }
Daniel Jasper4281d732013-11-06 23:12:09 +0000532 if (TheLine->Last->is(tok::l_brace)) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700533 return Style.BreakBeforeBraces == FormatStyle::BS_Attach
534 ? tryMergeSimpleBlock(I, E, Limit)
535 : 0;
536 }
537 if (I[1]->First->Type == TT_FunctionLBrace &&
538 Style.BreakBeforeBraces != FormatStyle::BS_Attach) {
539 // Check for Limit <= 2 to account for the " {".
540 if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(TheLine)))
541 return 0;
542 Limit -= 2;
543
544 unsigned MergedLines = 0;
545 if (Style.AllowShortFunctionsOnASingleLine) {
546 MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
547 // If we managed to merge the block, count the function header, which is
548 // on a separate line.
549 if (MergedLines > 0)
550 ++MergedLines;
551 }
552 return MergedLines;
553 }
554 if (TheLine->First->is(tok::kw_if)) {
555 return Style.AllowShortIfStatementsOnASingleLine
556 ? tryMergeSimpleControlStatement(I, E, Limit)
557 : 0;
558 }
559 if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) {
560 return Style.AllowShortLoopsOnASingleLine
561 ? tryMergeSimpleControlStatement(I, E, Limit)
562 : 0;
563 }
564 if (TheLine->InPPDirective &&
565 (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {
Daniel Jasper4281d732013-11-06 23:12:09 +0000566 return tryMergeSimplePPDirective(I, E, Limit);
567 }
568 return 0;
569 }
570
571private:
572 unsigned
Stephen Hines651f13c2014-04-23 16:59:28 -0700573 tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
Daniel Jasper4281d732013-11-06 23:12:09 +0000574 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
575 unsigned Limit) {
576 if (Limit == 0)
577 return 0;
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000578 if (!I[1]->InPPDirective || I[1]->First->HasUnescapedNewline)
Daniel Jasper4281d732013-11-06 23:12:09 +0000579 return 0;
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000580 if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline)
Daniel Jasper4281d732013-11-06 23:12:09 +0000581 return 0;
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000582 if (1 + I[1]->Last->TotalLength > Limit)
Daniel Jasper4281d732013-11-06 23:12:09 +0000583 return 0;
584 return 1;
585 }
586
587 unsigned tryMergeSimpleControlStatement(
Stephen Hines651f13c2014-04-23 16:59:28 -0700588 SmallVectorImpl<AnnotatedLine *>::const_iterator I,
Daniel Jasper4281d732013-11-06 23:12:09 +0000589 SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {
590 if (Limit == 0)
591 return 0;
Stephen Hines651f13c2014-04-23 16:59:28 -0700592 if ((Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
593 Style.BreakBeforeBraces == FormatStyle::BS_GNU) &&
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000594 I[1]->First->is(tok::l_brace))
Daniel Jasper4281d732013-11-06 23:12:09 +0000595 return 0;
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000596 if (I[1]->InPPDirective != (*I)->InPPDirective ||
597 (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline))
Daniel Jasper4281d732013-11-06 23:12:09 +0000598 return 0;
Stephen Hines651f13c2014-04-23 16:59:28 -0700599 Limit = limitConsideringMacros(I + 1, E, Limit);
Daniel Jasper4281d732013-11-06 23:12:09 +0000600 AnnotatedLine &Line = **I;
601 if (Line.Last->isNot(tok::r_paren))
602 return 0;
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000603 if (1 + I[1]->Last->TotalLength > Limit)
Daniel Jasper4281d732013-11-06 23:12:09 +0000604 return 0;
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000605 if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for,
Stephen Hines651f13c2014-04-23 16:59:28 -0700606 tok::kw_while) ||
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000607 I[1]->First->Type == TT_LineComment)
Daniel Jasper4281d732013-11-06 23:12:09 +0000608 return 0;
609 // Only inline simple if's (no nested if or else).
610 if (I + 2 != E && Line.First->is(tok::kw_if) &&
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000611 I[2]->First->is(tok::kw_else))
Daniel Jasper4281d732013-11-06 23:12:09 +0000612 return 0;
613 return 1;
614 }
615
616 unsigned
Stephen Hines651f13c2014-04-23 16:59:28 -0700617 tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
Daniel Jasper4281d732013-11-06 23:12:09 +0000618 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
619 unsigned Limit) {
Daniel Jasper4281d732013-11-06 23:12:09 +0000620 // First, check that the current line allows merging. This is the case if
621 // we're not in a control flow statement and the last token is an opening
622 // brace.
623 AnnotatedLine &Line = **I;
624 if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace,
625 tok::kw_else, tok::kw_try, tok::kw_catch,
626 tok::kw_for,
627 // This gets rid of all ObjC @ keywords and methods.
628 tok::at, tok::minus, tok::plus))
629 return 0;
630
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000631 FormatToken *Tok = I[1]->First;
Daniel Jasper4281d732013-11-06 23:12:09 +0000632 if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore &&
633 (Tok->getNextNonComment() == NULL ||
634 Tok->getNextNonComment()->is(tok::semi))) {
635 // We merge empty blocks even if the line exceeds the column limit.
636 Tok->SpacesRequiredBefore = 0;
637 Tok->CanBreakBefore = true;
638 return 1;
639 } else if (Limit != 0 && Line.First->isNot(tok::kw_namespace)) {
640 // Check that we still have three lines and they fit into the limit.
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000641 if (I + 2 == E || I[2]->Type == LT_Invalid)
Daniel Jasper4281d732013-11-06 23:12:09 +0000642 return 0;
Stephen Hines651f13c2014-04-23 16:59:28 -0700643 Limit = limitConsideringMacros(I + 2, E, Limit);
Daniel Jasper4281d732013-11-06 23:12:09 +0000644
645 if (!nextTwoLinesFitInto(I, Limit))
646 return 0;
647
648 // Second, check that the next line does not contain any braces - if it
649 // does, readability declines when putting it into a single line.
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000650 if (I[1]->Last->Type == TT_LineComment || Tok->MustBreakBefore)
Daniel Jasper4281d732013-11-06 23:12:09 +0000651 return 0;
652 do {
653 if (Tok->isOneOf(tok::l_brace, tok::r_brace))
654 return 0;
655 Tok = Tok->Next;
656 } while (Tok != NULL);
657
658 // Last, check that the third line contains a single closing brace.
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000659 Tok = I[2]->First;
Daniel Jasper4281d732013-11-06 23:12:09 +0000660 if (Tok->getNextNonComment() != NULL || Tok->isNot(tok::r_brace) ||
661 Tok->MustBreakBefore)
662 return 0;
663
664 return 2;
665 }
666 return 0;
667 }
668
Stephen Hines651f13c2014-04-23 16:59:28 -0700669 /// Returns the modified column limit for \p I if it is inside a macro and
670 /// needs a trailing '\'.
671 unsigned
672 limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
673 SmallVectorImpl<AnnotatedLine *>::const_iterator E,
674 unsigned Limit) {
675 if (I[0]->InPPDirective && I + 1 != E &&
676 !I[1]->First->HasUnescapedNewline && !I[1]->First->is(tok::eof)) {
677 return Limit < 2 ? 0 : Limit - 2;
678 }
679 return Limit;
680 }
681
Daniel Jasper4281d732013-11-06 23:12:09 +0000682 bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
683 unsigned Limit) {
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000684 return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit;
Daniel Jasper4281d732013-11-06 23:12:09 +0000685 }
686
Stephen Hines651f13c2014-04-23 16:59:28 -0700687 bool containsMustBreak(const AnnotatedLine *Line) {
688 for (const FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) {
689 if (Tok->MustBreakBefore)
690 return true;
691 }
692 return false;
693 }
694
Daniel Jasper4281d732013-11-06 23:12:09 +0000695 const FormatStyle &Style;
696};
697
Daniel Jasperbac016b2012-12-03 18:12:45 +0000698class UnwrappedLineFormatter {
699public:
Stephen Hines651f13c2014-04-23 16:59:28 -0700700 UnwrappedLineFormatter(ContinuationIndenter *Indenter,
Daniel Jasper567dcf92013-09-05 09:29:45 +0000701 WhitespaceManager *Whitespaces,
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000702 const FormatStyle &Style)
Stephen Hines651f13c2014-04-23 16:59:28 -0700703 : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style),
704 Joiner(Style) {}
Daniel Jasperbac016b2012-12-03 18:12:45 +0000705
Daniel Jasper4281d732013-11-06 23:12:09 +0000706 unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,
Stephen Hines651f13c2014-04-23 16:59:28 -0700707 int AdditionalIndent = 0, bool FixBadIndentation = false) {
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000708 assert(!Lines.empty());
709 unsigned Penalty = 0;
710 std::vector<int> IndentForLevel;
711 for (unsigned i = 0, e = Lines[0]->Level; i != e; ++i)
712 IndentForLevel.push_back(Style.IndentWidth * i + AdditionalIndent);
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000713 const AnnotatedLine *PreviousLine = NULL;
Daniel Jasper4281d732013-11-06 23:12:09 +0000714 for (SmallVectorImpl<AnnotatedLine *>::const_iterator I = Lines.begin(),
715 E = Lines.end();
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000716 I != E; ++I) {
717 const AnnotatedLine &TheLine = **I;
718 const FormatToken *FirstTok = TheLine.First;
719 int Offset = getIndentOffset(*FirstTok);
720
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000721 // Determine indent and try to merge multiple unwrapped lines.
Stephen Hines651f13c2014-04-23 16:59:28 -0700722 unsigned Indent;
723 if (TheLine.InPPDirective) {
724 Indent = TheLine.Level * Style.IndentWidth;
725 } else {
726 while (IndentForLevel.size() <= TheLine.Level)
727 IndentForLevel.push_back(-1);
728 IndentForLevel.resize(TheLine.Level + 1);
729 Indent = getIndent(IndentForLevel, TheLine.Level);
730 }
731 unsigned LevelIndent = Indent;
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000732 if (static_cast<int>(Indent) + Offset >= 0)
733 Indent += Offset;
Stephen Hines651f13c2014-04-23 16:59:28 -0700734
735 // Merge multiple lines if possible.
Daniel Jasper4281d732013-11-06 23:12:09 +0000736 unsigned MergedLines = Joiner.tryFitMultipleLinesInOne(Indent, I, E);
Stephen Hines651f13c2014-04-23 16:59:28 -0700737 if (MergedLines > 0 && Style.ColumnLimit == 0) {
738 // Disallow line merging if there is a break at the start of one of the
739 // input lines.
740 for (unsigned i = 0; i < MergedLines; ++i) {
741 if (I[i + 1]->First->NewlinesBefore > 0)
742 MergedLines = 0;
743 }
744 }
Daniel Jasper4281d732013-11-06 23:12:09 +0000745 if (!DryRun) {
746 for (unsigned i = 0; i < MergedLines; ++i) {
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000747 join(*I[i], *I[i + 1]);
Daniel Jasper4281d732013-11-06 23:12:09 +0000748 }
749 }
750 I += MergedLines;
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000751
Stephen Hines651f13c2014-04-23 16:59:28 -0700752 bool FixIndentation =
753 FixBadIndentation && (LevelIndent != FirstTok->OriginalColumn);
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000754 if (TheLine.First->is(tok::eof)) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700755 if (PreviousLine && PreviousLine->Affected && !DryRun) {
756 // Remove the file's trailing whitespace.
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000757 unsigned Newlines = std::min(FirstTok->NewlinesBefore, 1u);
758 Whitespaces->replaceWhitespace(*TheLine.First, Newlines,
759 /*IndentLevel=*/0, /*Spaces=*/0,
760 /*TargetColumn=*/0);
761 }
762 } else if (TheLine.Type != LT_Invalid &&
Stephen Hines651f13c2014-04-23 16:59:28 -0700763 (TheLine.Affected || FixIndentation)) {
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000764 if (FirstTok->WhitespaceRange.isValid()) {
765 if (!DryRun)
766 formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level,
767 Indent, TheLine.InPPDirective);
768 } else {
769 Indent = LevelIndent = FirstTok->OriginalColumn;
770 }
771
772 // If everything fits on a single line, just put it there.
773 unsigned ColumnLimit = Style.ColumnLimit;
774 if (I + 1 != E) {
Bill Wendlingb2ea6952013-11-19 18:42:00 +0000775 AnnotatedLine *NextLine = I[1];
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000776 if (NextLine->InPPDirective && !NextLine->First->HasUnescapedNewline)
777 ColumnLimit = getColumnLimit(TheLine.InPPDirective);
778 }
779
780 if (TheLine.Last->TotalLength + Indent <= ColumnLimit) {
781 LineState State = Indenter->getInitialState(Indent, &TheLine, DryRun);
782 while (State.NextToken != NULL)
783 Indenter->addTokenToState(State, /*Newline=*/false, DryRun);
784 } else if (Style.ColumnLimit == 0) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700785 // FIXME: Implement nested blocks for ColumnLimit = 0.
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000786 NoColumnLimitFormatter Formatter(Indenter);
787 if (!DryRun)
788 Formatter.format(Indent, &TheLine);
789 } else {
790 Penalty += format(TheLine, Indent, DryRun);
791 }
792
Stephen Hines651f13c2014-04-23 16:59:28 -0700793 if (!TheLine.InPPDirective)
794 IndentForLevel[TheLine.Level] = LevelIndent;
795 } else if (TheLine.ChildrenAffected) {
796 format(TheLine.Children, DryRun);
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000797 } else {
798 // Format the first token if necessary, and notify the WhitespaceManager
799 // about the unchanged whitespace.
800 for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {
801 if (Tok == TheLine.First &&
802 (Tok->NewlinesBefore > 0 || Tok->IsFirst)) {
803 unsigned LevelIndent = Tok->OriginalColumn;
804 if (!DryRun) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700805 // Remove trailing whitespace of the previous line.
806 if ((PreviousLine && PreviousLine->Affected) ||
807 TheLine.LeadingEmptyLinesAffected) {
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000808 formatFirstToken(*Tok, PreviousLine, TheLine.Level, LevelIndent,
809 TheLine.InPPDirective);
810 } else {
811 Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);
812 }
813 }
814
815 if (static_cast<int>(LevelIndent) - Offset >= 0)
816 LevelIndent -= Offset;
Stephen Hines651f13c2014-04-23 16:59:28 -0700817 if (Tok->isNot(tok::comment) && !TheLine.InPPDirective)
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000818 IndentForLevel[TheLine.Level] = LevelIndent;
819 } else if (!DryRun) {
820 Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);
821 }
822 }
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000823 }
824 if (!DryRun) {
825 for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {
826 Tok->Finalized = true;
827 }
828 }
829 PreviousLine = *I;
830 }
831 return Penalty;
832 }
833
834private:
835 /// \brief Formats an \c AnnotatedLine and returns the penalty.
Daniel Jasper567dcf92013-09-05 09:29:45 +0000836 ///
837 /// If \p DryRun is \c false, directly applies the changes.
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000838 unsigned format(const AnnotatedLine &Line, unsigned FirstIndent,
839 bool DryRun) {
Daniel Jasperb77d7412013-09-06 07:54:20 +0000840 LineState State = Indenter->getInitialState(FirstIndent, &Line, DryRun);
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000841
Daniel Jasperce3d1a62013-02-08 08:22:00 +0000842 // If the ObjC method declaration does not fit on a line, we should format
843 // it with one arg per line.
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000844 if (State.Line->Type == LT_ObjCMethodDecl)
Daniel Jasperce3d1a62013-02-08 08:22:00 +0000845 State.Stack.back().BreakBeforeParameter = true;
846
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000847 // Find best solution in solution space.
Daniel Jasper567dcf92013-09-05 09:29:45 +0000848 return analyzeSolutionSpace(State, DryRun);
Daniel Jasperbac016b2012-12-03 18:12:45 +0000849 }
850
Manuel Klimek32a2fd72013-02-13 10:46:36 +0000851 /// \brief An edge in the solution space from \c Previous->State to \c State,
852 /// inserting a newline dependent on the \c NewLine.
853 struct StateNode {
854 StateNode(const LineState &State, bool NewLine, StateNode *Previous)
Daniel Jasperf11a7052013-02-21 21:33:55 +0000855 : State(State), NewLine(NewLine), Previous(Previous) {}
Manuel Klimek32a2fd72013-02-13 10:46:36 +0000856 LineState State;
857 bool NewLine;
858 StateNode *Previous;
859 };
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000860
Manuel Klimek32a2fd72013-02-13 10:46:36 +0000861 /// \brief A pair of <penalty, count> that is used to prioritize the BFS on.
862 ///
863 /// In case of equal penalties, we want to prefer states that were inserted
864 /// first. During state generation we make sure that we insert states first
865 /// that break the line as late as possible.
866 typedef std::pair<unsigned, unsigned> OrderedPenalty;
867
868 /// \brief An item in the prioritized BFS search queue. The \c StateNode's
869 /// \c State has the given \c OrderedPenalty.
870 typedef std::pair<OrderedPenalty, StateNode *> QueueItem;
871
872 /// \brief The BFS queue type.
873 typedef std::priority_queue<QueueItem, std::vector<QueueItem>,
874 std::greater<QueueItem> > QueueType;
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000875
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000876 /// \brief Get the offset of the line relatively to the level.
877 ///
878 /// For example, 'public:' labels in classes are offset by 1 or 2
879 /// characters to the left from their level.
880 int getIndentOffset(const FormatToken &RootToken) {
881 if (RootToken.isAccessSpecifier(false) || RootToken.isObjCAccessSpecifier())
882 return Style.AccessModifierOffset;
883 return 0;
884 }
885
886 /// \brief Add a new line and the required indent before the first Token
887 /// of the \c UnwrappedLine if there was no structural parsing error.
888 void formatFirstToken(FormatToken &RootToken,
889 const AnnotatedLine *PreviousLine, unsigned IndentLevel,
890 unsigned Indent, bool InPPDirective) {
891 unsigned Newlines =
892 std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);
893 // Remove empty lines before "}" where applicable.
894 if (RootToken.is(tok::r_brace) &&
895 (!RootToken.Next ||
896 (RootToken.Next->is(tok::semi) && !RootToken.Next->Next)))
897 Newlines = std::min(Newlines, 1u);
898 if (Newlines == 0 && !RootToken.IsFirst)
899 Newlines = 1;
900
Stephen Hines651f13c2014-04-23 16:59:28 -0700901 // Remove empty lines after "{".
902 if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
903 PreviousLine->Last->is(tok::l_brace) &&
904 PreviousLine->First->isNot(tok::kw_namespace))
905 Newlines = 1;
906
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000907 // Insert extra new line before access specifiers.
908 if (PreviousLine && PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) &&
909 RootToken.isAccessSpecifier() && RootToken.NewlinesBefore == 1)
910 ++Newlines;
911
912 // Remove empty lines after access specifiers.
913 if (PreviousLine && PreviousLine->First->isAccessSpecifier())
914 Newlines = std::min(1u, Newlines);
915
Stephen Hines651f13c2014-04-23 16:59:28 -0700916 Whitespaces->replaceWhitespace(RootToken, Newlines, IndentLevel, Indent,
917 Indent, InPPDirective &&
918 !RootToken.HasUnescapedNewline);
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000919 }
920
921 /// \brief Get the indent of \p Level from \p IndentForLevel.
922 ///
923 /// \p IndentForLevel must contain the indent for the level \c l
924 /// at \p IndentForLevel[l], or a value < 0 if the indent for
925 /// that level is unknown.
926 unsigned getIndent(const std::vector<int> IndentForLevel, unsigned Level) {
927 if (IndentForLevel[Level] != -1)
928 return IndentForLevel[Level];
929 if (Level == 0)
930 return 0;
931 return getIndent(IndentForLevel, Level - 1) + Style.IndentWidth;
932 }
933
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000934 void join(AnnotatedLine &A, const AnnotatedLine &B) {
935 assert(!A.Last->Next);
936 assert(!B.First->Previous);
Stephen Hines651f13c2014-04-23 16:59:28 -0700937 if (B.Affected)
938 A.Affected = true;
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000939 A.Last->Next = B.First;
940 B.First->Previous = A.Last;
Daniel Jasperc2e03292013-11-08 17:33:27 +0000941 B.First->CanBreakBefore = true;
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000942 unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore;
943 for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) {
944 Tok->TotalLength += LengthA;
945 A.Last = Tok;
946 }
947 }
948
949 unsigned getColumnLimit(bool InPPDirective) const {
950 // In preprocessor directives reserve two chars for trailing " \"
951 return Style.ColumnLimit - (InPPDirective ? 2 : 0);
952 }
953
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000954 /// \brief Analyze the entire solution space starting from \p InitialState.
Daniel Jasperbac016b2012-12-03 18:12:45 +0000955 ///
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000956 /// This implements a variant of Dijkstra's algorithm on the graph that spans
957 /// the solution space (\c LineStates are the nodes). The algorithm tries to
958 /// find the shortest path (the one with lowest penalty) from \p InitialState
Daniel Jasper567dcf92013-09-05 09:29:45 +0000959 /// to a state where all tokens are placed. Returns the penalty.
960 ///
961 /// If \p DryRun is \c false, directly applies the changes.
962 unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun = false) {
Manuel Klimek32a2fd72013-02-13 10:46:36 +0000963 std::set<LineState> Seen;
964
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000965 // Increasing count of \c StateNode items we have created. This is used to
966 // create a deterministic order independent of the container.
967 unsigned Count = 0;
968 QueueType Queue;
969
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000970 // Insert start element into queue.
Daniel Jasperfc759082013-02-14 14:26:07 +0000971 StateNode *Node =
Manuel Klimek32a2fd72013-02-13 10:46:36 +0000972 new (Allocator.Allocate()) StateNode(InitialState, false, NULL);
973 Queue.push(QueueItem(OrderedPenalty(0, Count), Node));
974 ++Count;
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000975
Daniel Jasper567dcf92013-09-05 09:29:45 +0000976 unsigned Penalty = 0;
977
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000978 // While not empty, take first element and follow edges.
979 while (!Queue.empty()) {
Daniel Jasper567dcf92013-09-05 09:29:45 +0000980 Penalty = Queue.top().first.first;
Daniel Jasperfc759082013-02-14 14:26:07 +0000981 StateNode *Node = Queue.top().second;
Manuel Klimek32a2fd72013-02-13 10:46:36 +0000982 if (Node->State.NextToken == NULL) {
Alexander Kornienkodd256312013-05-10 11:56:10 +0000983 DEBUG(llvm::dbgs() << "\n---\nPenalty for line: " << Penalty << "\n");
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000984 break;
Daniel Jasper01786732013-02-04 07:21:18 +0000985 }
Manuel Klimek32a2fd72013-02-13 10:46:36 +0000986 Queue.pop();
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000987
Daniel Jasper54b4e442013-05-22 05:27:42 +0000988 // Cut off the analysis of certain solutions if the analysis gets too
989 // complex. See description of IgnoreStackForComparison.
990 if (Count > 10000)
991 Node->State.IgnoreStackForComparison = true;
992
Manuel Klimek32a2fd72013-02-13 10:46:36 +0000993 if (!Seen.insert(Node->State).second)
994 // State already examined with lower penalty.
995 continue;
Daniel Jasper68ef0df2013-02-01 11:00:45 +0000996
Manuel Klimekae76f7f2013-10-11 21:25:45 +0000997 FormatDecision LastFormat = Node->State.NextToken->Decision;
998 if (LastFormat == FD_Unformatted || LastFormat == FD_Continue)
Daniel Jasper2a80ad62013-11-05 19:10:03 +0000999 addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue);
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001000 if (LastFormat == FD_Unformatted || LastFormat == FD_Break)
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001001 addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue);
Daniel Jasper68ef0df2013-02-01 11:00:45 +00001002 }
1003
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001004 if (Queue.empty()) {
Daniel Jasper68ef0df2013-02-01 11:00:45 +00001005 // We were unable to find a solution, do nothing.
1006 // FIXME: Add diagnostic?
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001007 DEBUG(llvm::dbgs() << "Could not find a solution.\n");
Daniel Jasper567dcf92013-09-05 09:29:45 +00001008 return 0;
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001009 }
Daniel Jasperbac016b2012-12-03 18:12:45 +00001010
Daniel Jasper68ef0df2013-02-01 11:00:45 +00001011 // Reconstruct the solution.
Daniel Jasper567dcf92013-09-05 09:29:45 +00001012 if (!DryRun)
1013 reconstructPath(InitialState, Queue.top().second);
1014
Alexander Kornienkodd256312013-05-10 11:56:10 +00001015 DEBUG(llvm::dbgs() << "Total number of analyzed states: " << Count << "\n");
1016 DEBUG(llvm::dbgs() << "---\n");
Daniel Jasper567dcf92013-09-05 09:29:45 +00001017
1018 return Penalty;
Manuel Klimek32a2fd72013-02-13 10:46:36 +00001019 }
1020
1021 void reconstructPath(LineState &State, StateNode *Current) {
Manuel Klimek9c333b92013-05-29 15:10:11 +00001022 std::deque<StateNode *> Path;
1023 // We do not need a break before the initial token.
1024 while (Current->Previous) {
1025 Path.push_front(Current);
1026 Current = Current->Previous;
1027 }
1028 for (std::deque<StateNode *>::iterator I = Path.begin(), E = Path.end();
1029 I != E; ++I) {
Daniel Jasper567dcf92013-09-05 09:29:45 +00001030 unsigned Penalty = 0;
1031 formatChildren(State, (*I)->NewLine, /*DryRun=*/false, Penalty);
1032 Penalty += Indenter->addTokenToState(State, (*I)->NewLine, false);
1033
Manuel Klimek9c333b92013-05-29 15:10:11 +00001034 DEBUG({
1035 if ((*I)->NewLine) {
Daniel Jasperd4a03db2013-08-22 15:00:41 +00001036 llvm::dbgs() << "Penalty for placing "
Manuel Klimek9c333b92013-05-29 15:10:11 +00001037 << (*I)->Previous->State.NextToken->Tok.getName() << ": "
Daniel Jasperd4a03db2013-08-22 15:00:41 +00001038 << Penalty << "\n";
Manuel Klimek9c333b92013-05-29 15:10:11 +00001039 }
1040 });
Manuel Klimek9c333b92013-05-29 15:10:11 +00001041 }
Daniel Jasper68ef0df2013-02-01 11:00:45 +00001042 }
1043
Manuel Klimek62a48fb2013-02-13 10:54:19 +00001044 /// \brief Add the following state to the analysis queue \c Queue.
Daniel Jasper68ef0df2013-02-01 11:00:45 +00001045 ///
Manuel Klimek62a48fb2013-02-13 10:54:19 +00001046 /// Assume the current state is \p PreviousNode and has been reached with a
Daniel Jasper68ef0df2013-02-01 11:00:45 +00001047 /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true.
Manuel Klimek62a48fb2013-02-13 10:54:19 +00001048 void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode,
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001049 bool NewLine, unsigned *Count, QueueType *Queue) {
Daniel Jasper6b2afe42013-08-16 11:20:30 +00001050 if (NewLine && !Indenter->canBreak(PreviousNode->State))
Daniel Jasper68ef0df2013-02-01 11:00:45 +00001051 return;
Daniel Jasper6b2afe42013-08-16 11:20:30 +00001052 if (!NewLine && Indenter->mustBreak(PreviousNode->State))
Daniel Jasper68ef0df2013-02-01 11:00:45 +00001053 return;
Manuel Klimek32a2fd72013-02-13 10:46:36 +00001054
1055 StateNode *Node = new (Allocator.Allocate())
1056 StateNode(PreviousNode->State, NewLine, PreviousNode);
Daniel Jasper567dcf92013-09-05 09:29:45 +00001057 if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty))
1058 return;
1059
Daniel Jasper6b2afe42013-08-16 11:20:30 +00001060 Penalty += Indenter->addTokenToState(Node->State, NewLine, true);
Manuel Klimek32a2fd72013-02-13 10:46:36 +00001061
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001062 Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node));
1063 ++(*Count);
Daniel Jasper68ef0df2013-02-01 11:00:45 +00001064 }
Daniel Jasperbac016b2012-12-03 18:12:45 +00001065
Daniel Jasper1a925bc2013-09-05 10:48:50 +00001066 /// \brief If the \p State's next token is an r_brace closing a nested block,
1067 /// format the nested block before it.
Daniel Jasper567dcf92013-09-05 09:29:45 +00001068 ///
1069 /// Returns \c true if all children could be placed successfully and adapts
1070 /// \p Penalty as well as \p State. If \p DryRun is false, also directly
1071 /// creates changes using \c Whitespaces.
1072 ///
1073 /// The crucial idea here is that children always get formatted upon
1074 /// encountering the closing brace right after the nested block. Now, if we
1075 /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is
1076 /// \c false), the entire block has to be kept on the same line (which is only
1077 /// possible if it fits on the line, only contains a single statement, etc.
1078 ///
1079 /// If \p NewLine is true, we format the nested block on separate lines, i.e.
1080 /// break after the "{", format all lines with correct indentation and the put
1081 /// the closing "}" on yet another new line.
1082 ///
1083 /// This enables us to keep the simple structure of the
1084 /// \c UnwrappedLineFormatter, where we only have two options for each token:
1085 /// break or don't break.
1086 bool formatChildren(LineState &State, bool NewLine, bool DryRun,
1087 unsigned &Penalty) {
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001088 FormatToken &Previous = *State.NextToken->Previous;
Daniel Jasper15eef852013-10-20 17:28:32 +00001089 const FormatToken *LBrace = State.NextToken->getPreviousNonComment();
1090 if (!LBrace || LBrace->isNot(tok::l_brace) ||
1091 LBrace->BlockKind != BK_Block || Previous.Children.size() == 0)
Daniel Jasper1a925bc2013-09-05 10:48:50 +00001092 // The previous token does not open a block. Nothing to do. We don't
1093 // assert so that we can simply call this function for all tokens.
Daniel Jasper2f0a0202013-09-06 08:54:24 +00001094 return true;
Daniel Jasper567dcf92013-09-05 09:29:45 +00001095
1096 if (NewLine) {
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001097 int AdditionalIndent = State.Stack.back().Indent -
1098 Previous.Children[0]->Level * Style.IndentWidth;
Stephen Hines651f13c2014-04-23 16:59:28 -07001099 Penalty += format(Previous.Children, DryRun, AdditionalIndent,
1100 /*FixBadIndentation=*/true);
Daniel Jasper567dcf92013-09-05 09:29:45 +00001101 return true;
1102 }
1103
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001104 // Cannot merge multiple statements into a single line.
Daniel Jasper15eef852013-10-20 17:28:32 +00001105 if (Previous.Children.size() > 1)
Stephen Hines651f13c2014-04-23 16:59:28 -07001106 return false;
Daniel Jasper567dcf92013-09-05 09:29:45 +00001107
1108 // We can't put the closing "}" on a line with a trailing comment.
Daniel Jasper15eef852013-10-20 17:28:32 +00001109 if (Previous.Children[0]->Last->isTrailingComment())
Daniel Jasper567dcf92013-09-05 09:29:45 +00001110 return false;
1111
1112 if (!DryRun) {
Alexander Kornienko3d9ffcf2013-09-27 16:14:22 +00001113 Whitespaces->replaceWhitespace(
Daniel Jasper15eef852013-10-20 17:28:32 +00001114 *Previous.Children[0]->First,
Alexander Kornienkof0fc89c2013-10-14 00:46:35 +00001115 /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1,
Alexander Kornienko3d9ffcf2013-09-27 16:14:22 +00001116 /*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective);
Daniel Jasper567dcf92013-09-05 09:29:45 +00001117 }
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001118 Penalty += format(*Previous.Children[0], State.Column + 1, DryRun);
Daniel Jasper567dcf92013-09-05 09:29:45 +00001119
Daniel Jasper15eef852013-10-20 17:28:32 +00001120 State.Column += 1 + Previous.Children[0]->Last->TotalLength;
Daniel Jasper567dcf92013-09-05 09:29:45 +00001121 return true;
1122 }
1123
Daniel Jasper6b2afe42013-08-16 11:20:30 +00001124 ContinuationIndenter *Indenter;
Daniel Jasper567dcf92013-09-05 09:29:45 +00001125 WhitespaceManager *Whitespaces;
Daniel Jasperbac016b2012-12-03 18:12:45 +00001126 FormatStyle Style;
Daniel Jasper4281d732013-11-06 23:12:09 +00001127 LineJoiner Joiner;
Manuel Klimek62a48fb2013-02-13 10:54:19 +00001128
1129 llvm::SpecificBumpPtrAllocator<StateNode> Allocator;
Daniel Jasperbac016b2012-12-03 18:12:45 +00001130};
1131
Manuel Klimek96e888b2013-05-28 11:55:06 +00001132class FormatTokenLexer {
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001133public:
Manuel Klimekc41e8192013-08-29 15:21:40 +00001134 FormatTokenLexer(Lexer &Lex, SourceManager &SourceMgr, FormatStyle &Style,
Alexander Kornienko00895102013-06-05 14:09:10 +00001135 encoding::Encoding Encoding)
Alexander Kornienkoa9f28092013-11-13 14:04:17 +00001136 : FormatTok(NULL), IsFirstToken(true), GreaterStashed(false), Column(0),
Manuel Klimekc41e8192013-08-29 15:21:40 +00001137 TrailingWhitespace(0), Lex(Lex), SourceMgr(SourceMgr), Style(Style),
1138 IdentTable(getFormattingLangOpts()), Encoding(Encoding) {
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001139 Lex.SetKeepWhitespaceMode(true);
Stephen Hines651f13c2014-04-23 16:59:28 -07001140
1141 for (const std::string& ForEachMacro : Style.ForEachMacros)
1142 ForEachMacros.push_back(&IdentTable.get(ForEachMacro));
1143 std::sort(ForEachMacros.begin(), ForEachMacros.end());
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001144 }
1145
Manuel Klimek96e888b2013-05-28 11:55:06 +00001146 ArrayRef<FormatToken *> lex() {
1147 assert(Tokens.empty());
1148 do {
1149 Tokens.push_back(getNextToken());
Stephen Hines651f13c2014-04-23 16:59:28 -07001150 tryMergePreviousTokens();
Manuel Klimek96e888b2013-05-28 11:55:06 +00001151 } while (Tokens.back()->Tok.isNot(tok::eof));
1152 return Tokens;
1153 }
1154
1155 IdentifierTable &getIdentTable() { return IdentTable; }
1156
1157private:
Stephen Hines651f13c2014-04-23 16:59:28 -07001158 void tryMergePreviousTokens() {
1159 if (tryMerge_TMacro())
Alexander Kornienko2c2f7292013-09-16 20:20:49 +00001160 return;
Stephen Hines651f13c2014-04-23 16:59:28 -07001161
1162 if (Style.Language == FormatStyle::LK_JavaScript) {
1163 static tok::TokenKind JSIdentity[] = { tok::equalequal, tok::equal };
1164 static tok::TokenKind JSNotIdentity[] = { tok::exclaimequal, tok::equal };
1165 static tok::TokenKind JSShiftEqual[] = { tok::greater, tok::greater,
1166 tok::greaterequal };
1167 // FIXME: We probably need to change token type to mimic operator with the
1168 // correct priority.
1169 if (tryMergeTokens(JSIdentity))
1170 return;
1171 if (tryMergeTokens(JSNotIdentity))
1172 return;
1173 if (tryMergeTokens(JSShiftEqual))
1174 return;
1175 }
1176 }
1177
1178 bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds) {
1179 if (Tokens.size() < Kinds.size())
1180 return false;
1181
1182 SmallVectorImpl<FormatToken *>::const_iterator First =
1183 Tokens.end() - Kinds.size();
1184 if (!First[0]->is(Kinds[0]))
1185 return false;
1186 unsigned AddLength = 0;
1187 for (unsigned i = 1; i < Kinds.size(); ++i) {
1188 if (!First[i]->is(Kinds[i]) || First[i]->WhitespaceRange.getBegin() !=
1189 First[i]->WhitespaceRange.getEnd())
1190 return false;
1191 AddLength += First[i]->TokenText.size();
1192 }
1193 Tokens.resize(Tokens.size() - Kinds.size() + 1);
1194 First[0]->TokenText = StringRef(First[0]->TokenText.data(),
1195 First[0]->TokenText.size() + AddLength);
1196 First[0]->ColumnWidth += AddLength;
1197 return true;
1198 }
1199
1200 bool tryMerge_TMacro() {
1201 if (Tokens.size() < 4)
1202 return false;
Alexander Kornienko2c2f7292013-09-16 20:20:49 +00001203 FormatToken *Last = Tokens.back();
1204 if (!Last->is(tok::r_paren))
Stephen Hines651f13c2014-04-23 16:59:28 -07001205 return false;
Alexander Kornienko2c2f7292013-09-16 20:20:49 +00001206
1207 FormatToken *String = Tokens[Tokens.size() - 2];
1208 if (!String->is(tok::string_literal) || String->IsMultiline)
Stephen Hines651f13c2014-04-23 16:59:28 -07001209 return false;
Alexander Kornienko2c2f7292013-09-16 20:20:49 +00001210
1211 if (!Tokens[Tokens.size() - 3]->is(tok::l_paren))
Stephen Hines651f13c2014-04-23 16:59:28 -07001212 return false;
Alexander Kornienko2c2f7292013-09-16 20:20:49 +00001213
1214 FormatToken *Macro = Tokens[Tokens.size() - 4];
1215 if (Macro->TokenText != "_T")
Stephen Hines651f13c2014-04-23 16:59:28 -07001216 return false;
Alexander Kornienko2c2f7292013-09-16 20:20:49 +00001217
1218 const char *Start = Macro->TokenText.data();
1219 const char *End = Last->TokenText.data() + Last->TokenText.size();
1220 String->TokenText = StringRef(Start, End - Start);
1221 String->IsFirst = Macro->IsFirst;
1222 String->LastNewlineOffset = Macro->LastNewlineOffset;
1223 String->WhitespaceRange = Macro->WhitespaceRange;
1224 String->OriginalColumn = Macro->OriginalColumn;
1225 String->ColumnWidth = encoding::columnWidthWithTabs(
1226 String->TokenText, String->OriginalColumn, Style.TabWidth, Encoding);
1227
1228 Tokens.pop_back();
1229 Tokens.pop_back();
1230 Tokens.pop_back();
1231 Tokens.back() = String;
Stephen Hines651f13c2014-04-23 16:59:28 -07001232 return true;
Alexander Kornienko2c2f7292013-09-16 20:20:49 +00001233 }
1234
Manuel Klimek96e888b2013-05-28 11:55:06 +00001235 FormatToken *getNextToken() {
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001236 if (GreaterStashed) {
Manuel Klimekdcb3f2a2013-05-28 13:42:28 +00001237 // Create a synthesized second '>' token.
Manuel Klimekc41e8192013-08-29 15:21:40 +00001238 // FIXME: Increment Column and set OriginalColumn.
Manuel Klimekdcb3f2a2013-05-28 13:42:28 +00001239 Token Greater = FormatTok->Tok;
1240 FormatTok = new (Allocator.Allocate()) FormatToken;
1241 FormatTok->Tok = Greater;
Manuel Klimekad3094b2013-05-23 10:56:37 +00001242 SourceLocation GreaterLocation =
Manuel Klimek96e888b2013-05-28 11:55:06 +00001243 FormatTok->Tok.getLocation().getLocWithOffset(1);
1244 FormatTok->WhitespaceRange =
1245 SourceRange(GreaterLocation, GreaterLocation);
Alexander Kornienko54e6c9d2013-06-07 17:45:07 +00001246 FormatTok->TokenText = ">";
Alexander Kornienko83a7dcd2013-09-10 09:38:25 +00001247 FormatTok->ColumnWidth = 1;
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001248 GreaterStashed = false;
1249 return FormatTok;
1250 }
1251
Manuel Klimek96e888b2013-05-28 11:55:06 +00001252 FormatTok = new (Allocator.Allocate()) FormatToken;
Daniel Jasper561211d2013-07-16 20:28:33 +00001253 readRawToken(*FormatTok);
Manuel Klimekde008c02013-05-27 15:23:34 +00001254 SourceLocation WhitespaceStart =
Manuel Klimek96e888b2013-05-28 11:55:06 +00001255 FormatTok->Tok.getLocation().getLocWithOffset(-TrailingWhitespace);
Alexander Kornienkoa9f28092013-11-13 14:04:17 +00001256 FormatTok->IsFirst = IsFirstToken;
1257 IsFirstToken = false;
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001258
1259 // Consume and record whitespace until we find a significant token.
Manuel Klimekde008c02013-05-27 15:23:34 +00001260 unsigned WhitespaceLength = TrailingWhitespace;
Manuel Klimek96e888b2013-05-28 11:55:06 +00001261 while (FormatTok->Tok.is(tok::unknown)) {
Manuel Klimekc41e8192013-08-29 15:21:40 +00001262 for (int i = 0, e = FormatTok->TokenText.size(); i != e; ++i) {
1263 switch (FormatTok->TokenText[i]) {
1264 case '\n':
1265 ++FormatTok->NewlinesBefore;
1266 // FIXME: This is technically incorrect, as it could also
1267 // be a literal backslash at the end of the line.
Alexander Kornienko73d845c2013-09-11 12:25:57 +00001268 if (i == 0 || (FormatTok->TokenText[i - 1] != '\\' &&
1269 (FormatTok->TokenText[i - 1] != '\r' || i == 1 ||
1270 FormatTok->TokenText[i - 2] != '\\')))
Manuel Klimekc41e8192013-08-29 15:21:40 +00001271 FormatTok->HasUnescapedNewline = true;
1272 FormatTok->LastNewlineOffset = WhitespaceLength + i + 1;
1273 Column = 0;
1274 break;
Daniel Jasper1d82b1a2013-10-11 19:45:02 +00001275 case '\r':
1276 case '\f':
1277 case '\v':
1278 Column = 0;
1279 break;
Manuel Klimekc41e8192013-08-29 15:21:40 +00001280 case ' ':
1281 ++Column;
1282 break;
1283 case '\t':
Alexander Kornienko0b62cc32013-09-05 14:08:34 +00001284 Column += Style.TabWidth - Column % Style.TabWidth;
Manuel Klimekc41e8192013-08-29 15:21:40 +00001285 break;
Daniel Jasper1d82b1a2013-10-11 19:45:02 +00001286 case '\\':
1287 ++Column;
1288 if (i + 1 == e || (FormatTok->TokenText[i + 1] != '\r' &&
1289 FormatTok->TokenText[i + 1] != '\n'))
1290 FormatTok->Type = TT_ImplicitStringLiteral;
1291 break;
Manuel Klimekc41e8192013-08-29 15:21:40 +00001292 default:
Daniel Jasper1d82b1a2013-10-11 19:45:02 +00001293 FormatTok->Type = TT_ImplicitStringLiteral;
Manuel Klimekc41e8192013-08-29 15:21:40 +00001294 ++Column;
1295 break;
1296 }
1297 }
1298
Daniel Jasper1d82b1a2013-10-11 19:45:02 +00001299 if (FormatTok->Type == TT_ImplicitStringLiteral)
1300 break;
Manuel Klimek96e888b2013-05-28 11:55:06 +00001301 WhitespaceLength += FormatTok->Tok.getLength();
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001302
Daniel Jasper561211d2013-07-16 20:28:33 +00001303 readRawToken(*FormatTok);
Manuel Klimekd4397b92013-01-04 23:34:14 +00001304 }
Manuel Klimek95419382013-01-07 07:56:50 +00001305
Manuel Klimekd4397b92013-01-04 23:34:14 +00001306 // In case the token starts with escaped newlines, we want to
1307 // take them into account as whitespace - this pattern is quite frequent
1308 // in macro definitions.
Manuel Klimekd4397b92013-01-04 23:34:14 +00001309 // FIXME: Add a more explicit test.
Daniel Jasper561211d2013-07-16 20:28:33 +00001310 while (FormatTok->TokenText.size() > 1 && FormatTok->TokenText[0] == '\\' &&
1311 FormatTok->TokenText[1] == '\n') {
Manuel Klimek96e888b2013-05-28 11:55:06 +00001312 // FIXME: ++FormatTok->NewlinesBefore is missing...
Manuel Klimekad3094b2013-05-23 10:56:37 +00001313 WhitespaceLength += 2;
Manuel Klimekc41e8192013-08-29 15:21:40 +00001314 Column = 0;
Daniel Jasper561211d2013-07-16 20:28:33 +00001315 FormatTok->TokenText = FormatTok->TokenText.substr(2);
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001316 }
Alexander Kornienko83a7dcd2013-09-10 09:38:25 +00001317
1318 FormatTok->WhitespaceRange = SourceRange(
1319 WhitespaceStart, WhitespaceStart.getLocWithOffset(WhitespaceLength));
1320
Manuel Klimekc41e8192013-08-29 15:21:40 +00001321 FormatTok->OriginalColumn = Column;
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001322
Alexander Kornienko54e6c9d2013-06-07 17:45:07 +00001323 TrailingWhitespace = 0;
1324 if (FormatTok->Tok.is(tok::comment)) {
Manuel Klimekc41e8192013-08-29 15:21:40 +00001325 // FIXME: Add the trimmed whitespace to Column.
Daniel Jasper561211d2013-07-16 20:28:33 +00001326 StringRef UntrimmedText = FormatTok->TokenText;
Alexander Kornienko51bb5d92013-09-06 17:24:54 +00001327 FormatTok->TokenText = FormatTok->TokenText.rtrim(" \t\v\f");
Daniel Jasper561211d2013-07-16 20:28:33 +00001328 TrailingWhitespace = UntrimmedText.size() - FormatTok->TokenText.size();
Alexander Kornienko54e6c9d2013-06-07 17:45:07 +00001329 } else if (FormatTok->Tok.is(tok::raw_identifier)) {
Daniel Jasper561211d2013-07-16 20:28:33 +00001330 IdentifierInfo &Info = IdentTable.get(FormatTok->TokenText);
Manuel Klimek96e888b2013-05-28 11:55:06 +00001331 FormatTok->Tok.setIdentifierInfo(&Info);
1332 FormatTok->Tok.setKind(Info.getTokenID());
Alexander Kornienko54e6c9d2013-06-07 17:45:07 +00001333 } else if (FormatTok->Tok.is(tok::greatergreater)) {
Manuel Klimek96e888b2013-05-28 11:55:06 +00001334 FormatTok->Tok.setKind(tok::greater);
Daniel Jasper561211d2013-07-16 20:28:33 +00001335 FormatTok->TokenText = FormatTok->TokenText.substr(0, 1);
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001336 GreaterStashed = true;
1337 }
1338
Alexander Kornienko54e6c9d2013-06-07 17:45:07 +00001339 // Now FormatTok is the next non-whitespace token.
Alexander Kornienko00895102013-06-05 14:09:10 +00001340
Alexander Kornienko83a7dcd2013-09-10 09:38:25 +00001341 StringRef Text = FormatTok->TokenText;
1342 size_t FirstNewlinePos = Text.find('\n');
Alexander Kornienko6f6154c2013-09-10 12:29:48 +00001343 if (FirstNewlinePos == StringRef::npos) {
1344 // FIXME: ColumnWidth actually depends on the start column, we need to
1345 // take this into account when the token is moved.
1346 FormatTok->ColumnWidth =
1347 encoding::columnWidthWithTabs(Text, Column, Style.TabWidth, Encoding);
1348 Column += FormatTok->ColumnWidth;
1349 } else {
Alexander Kornienko83a7dcd2013-09-10 09:38:25 +00001350 FormatTok->IsMultiline = true;
Alexander Kornienko6f6154c2013-09-10 12:29:48 +00001351 // FIXME: ColumnWidth actually depends on the start column, we need to
1352 // take this into account when the token is moved.
1353 FormatTok->ColumnWidth = encoding::columnWidthWithTabs(
1354 Text.substr(0, FirstNewlinePos), Column, Style.TabWidth, Encoding);
1355
Alexander Kornienko83a7dcd2013-09-10 09:38:25 +00001356 // The last line of the token always starts in column 0.
1357 // Thus, the length can be precomputed even in the presence of tabs.
1358 FormatTok->LastLineColumnWidth = encoding::columnWidthWithTabs(
1359 Text.substr(Text.find_last_of('\n') + 1), 0, Style.TabWidth,
1360 Encoding);
Alexander Kornienko6f6154c2013-09-10 12:29:48 +00001361 Column = FormatTok->LastLineColumnWidth;
Alexander Kornienko4b762a92013-09-02 13:58:14 +00001362 }
Alexander Kornienko83a7dcd2013-09-10 09:38:25 +00001363
Stephen Hines651f13c2014-04-23 16:59:28 -07001364 FormatTok->IsForEachMacro =
1365 std::binary_search(ForEachMacros.begin(), ForEachMacros.end(),
1366 FormatTok->Tok.getIdentifierInfo());
1367
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001368 return FormatTok;
1369 }
1370
Manuel Klimek96e888b2013-05-28 11:55:06 +00001371 FormatToken *FormatTok;
Alexander Kornienkoa9f28092013-11-13 14:04:17 +00001372 bool IsFirstToken;
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001373 bool GreaterStashed;
Manuel Klimekc41e8192013-08-29 15:21:40 +00001374 unsigned Column;
Manuel Klimekde008c02013-05-27 15:23:34 +00001375 unsigned TrailingWhitespace;
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001376 Lexer &Lex;
1377 SourceManager &SourceMgr;
Manuel Klimekc41e8192013-08-29 15:21:40 +00001378 FormatStyle &Style;
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001379 IdentifierTable IdentTable;
Alexander Kornienko00895102013-06-05 14:09:10 +00001380 encoding::Encoding Encoding;
Manuel Klimek96e888b2013-05-28 11:55:06 +00001381 llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
1382 SmallVector<FormatToken *, 16> Tokens;
Stephen Hines651f13c2014-04-23 16:59:28 -07001383 SmallVector<IdentifierInfo*, 8> ForEachMacros;
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001384
Daniel Jasper561211d2013-07-16 20:28:33 +00001385 void readRawToken(FormatToken &Tok) {
1386 Lex.LexFromRawLexer(Tok.Tok);
1387 Tok.TokenText = StringRef(SourceMgr.getCharacterData(Tok.Tok.getLocation()),
1388 Tok.Tok.getLength());
Daniel Jasper561211d2013-07-16 20:28:33 +00001389 // For formatting, treat unterminated string literals like normal string
1390 // literals.
Stephen Hines651f13c2014-04-23 16:59:28 -07001391 if (Tok.is(tok::unknown)) {
1392 if (!Tok.TokenText.empty() && Tok.TokenText[0] == '"') {
1393 Tok.Tok.setKind(tok::string_literal);
1394 Tok.IsUnterminatedLiteral = true;
1395 } else if (Style.Language == FormatStyle::LK_JavaScript &&
1396 Tok.TokenText == "''") {
1397 Tok.Tok.setKind(tok::char_constant);
1398 }
Daniel Jasper561211d2013-07-16 20:28:33 +00001399 }
Alexander Kornienko469a21b2012-12-07 16:15:44 +00001400 }
1401};
1402
Stephen Hines651f13c2014-04-23 16:59:28 -07001403static StringRef getLanguageName(FormatStyle::LanguageKind Language) {
1404 switch (Language) {
1405 case FormatStyle::LK_Cpp:
1406 return "C++";
1407 case FormatStyle::LK_JavaScript:
1408 return "JavaScript";
1409 case FormatStyle::LK_Proto:
1410 return "Proto";
1411 default:
1412 return "Unknown";
1413 }
1414}
1415
Daniel Jasperbac016b2012-12-03 18:12:45 +00001416class Formatter : public UnwrappedLineConsumer {
1417public:
Daniel Jaspercaf42a32013-05-15 08:14:19 +00001418 Formatter(const FormatStyle &Style, Lexer &Lex, SourceManager &SourceMgr,
Daniel Jasperbac016b2012-12-03 18:12:45 +00001419 const std::vector<CharSourceRange> &Ranges)
Daniel Jaspercaf42a32013-05-15 08:14:19 +00001420 : Style(Style), Lex(Lex), SourceMgr(SourceMgr),
Alexander Kornienko73d845c2013-09-11 12:25:57 +00001421 Whitespaces(SourceMgr, Style, inputUsesCRLF(Lex.getBuffer())),
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001422 Ranges(Ranges.begin(), Ranges.end()), UnwrappedLines(1),
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001423 Encoding(encoding::detectEncoding(Lex.getBuffer())) {
Daniel Jasper9637dda2013-07-15 14:33:14 +00001424 DEBUG(llvm::dbgs() << "File encoding: "
1425 << (Encoding == encoding::Encoding_UTF8 ? "UTF8"
1426 : "unknown")
1427 << "\n");
Stephen Hines651f13c2014-04-23 16:59:28 -07001428 DEBUG(llvm::dbgs() << "Language: " << getLanguageName(Style.Language)
1429 << "\n");
Alexander Kornienko00895102013-06-05 14:09:10 +00001430 }
Daniel Jasperbac016b2012-12-03 18:12:45 +00001431
Alexander Kornienkoe74de282013-03-13 14:41:29 +00001432 tooling::Replacements format() {
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001433 tooling::Replacements Result;
Manuel Klimekc41e8192013-08-29 15:21:40 +00001434 FormatTokenLexer Tokens(Lex, SourceMgr, Style, Encoding);
Manuel Klimek96e888b2013-05-28 11:55:06 +00001435
1436 UnwrappedLineParser Parser(Style, Tokens.lex(), *this);
Manuel Klimek67d080d2013-04-12 14:13:36 +00001437 bool StructuralError = Parser.parse();
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001438 assert(UnwrappedLines.rbegin()->empty());
1439 for (unsigned Run = 0, RunE = UnwrappedLines.size(); Run + 1 != RunE;
1440 ++Run) {
1441 DEBUG(llvm::dbgs() << "Run " << Run << "...\n");
1442 SmallVector<AnnotatedLine *, 16> AnnotatedLines;
1443 for (unsigned i = 0, e = UnwrappedLines[Run].size(); i != e; ++i) {
1444 AnnotatedLines.push_back(new AnnotatedLine(UnwrappedLines[Run][i]));
1445 }
1446 tooling::Replacements RunResult =
1447 format(AnnotatedLines, StructuralError, Tokens);
1448 DEBUG({
1449 llvm::dbgs() << "Replacements for run " << Run << ":\n";
1450 for (tooling::Replacements::iterator I = RunResult.begin(),
1451 E = RunResult.end();
1452 I != E; ++I) {
1453 llvm::dbgs() << I->toString() << "\n";
1454 }
1455 });
1456 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1457 delete AnnotatedLines[i];
1458 }
1459 Result.insert(RunResult.begin(), RunResult.end());
1460 Whitespaces.reset();
1461 }
1462 return Result;
1463 }
1464
1465 tooling::Replacements format(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1466 bool StructuralError, FormatTokenLexer &Tokens) {
Alexander Kornienko00895102013-06-05 14:09:10 +00001467 TokenAnnotator Annotator(Style, Tokens.getIdentTable().get("in"));
Alexander Kornienkoe74de282013-03-13 14:41:29 +00001468 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
Daniel Jasper567dcf92013-09-05 09:29:45 +00001469 Annotator.annotate(*AnnotatedLines[i]);
Alexander Kornienkoe74de282013-03-13 14:41:29 +00001470 }
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001471 deriveLocalStyle(AnnotatedLines);
Alexander Kornienkoe74de282013-03-13 14:41:29 +00001472 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
Daniel Jasper567dcf92013-09-05 09:29:45 +00001473 Annotator.calculateFormattingInformation(*AnnotatedLines[i]);
Alexander Kornienkoe74de282013-03-13 14:41:29 +00001474 }
Stephen Hines651f13c2014-04-23 16:59:28 -07001475 computeAffectedLines(AnnotatedLines.begin(), AnnotatedLines.end());
Daniel Jasper5999f762013-04-09 17:46:55 +00001476
Daniel Jasperb77d7412013-09-06 07:54:20 +00001477 Annotator.setCommentLineLevels(AnnotatedLines);
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001478 ContinuationIndenter Indenter(Style, SourceMgr, Whitespaces, Encoding,
1479 BinPackInconclusiveFunctions);
Stephen Hines651f13c2014-04-23 16:59:28 -07001480 UnwrappedLineFormatter Formatter(&Indenter, &Whitespaces, Style);
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001481 Formatter.format(AnnotatedLines, /*DryRun=*/false);
Alexander Kornienkoe74de282013-03-13 14:41:29 +00001482 return Whitespaces.generateReplacements();
1483 }
1484
1485private:
Stephen Hines651f13c2014-04-23 16:59:28 -07001486 // Determines which lines are affected by the SourceRanges given as input.
1487 // Returns \c true if at least one line between I and E or one of their
1488 // children is affected.
1489 bool computeAffectedLines(SmallVectorImpl<AnnotatedLine *>::iterator I,
1490 SmallVectorImpl<AnnotatedLine *>::iterator E) {
1491 bool SomeLineAffected = false;
1492 const AnnotatedLine *PreviousLine = NULL;
1493 while (I != E) {
1494 AnnotatedLine *Line = *I;
1495 Line->LeadingEmptyLinesAffected = affectsLeadingEmptyLines(*Line->First);
1496
1497 // If a line is part of a preprocessor directive, it needs to be formatted
1498 // if any token within the directive is affected.
1499 if (Line->InPPDirective) {
1500 FormatToken *Last = Line->Last;
1501 SmallVectorImpl<AnnotatedLine *>::iterator PPEnd = I + 1;
1502 while (PPEnd != E && !(*PPEnd)->First->HasUnescapedNewline) {
1503 Last = (*PPEnd)->Last;
1504 ++PPEnd;
1505 }
1506
1507 if (affectsTokenRange(*Line->First, *Last,
1508 /*IncludeLeadingNewlines=*/false)) {
1509 SomeLineAffected = true;
1510 markAllAsAffected(I, PPEnd);
1511 }
1512 I = PPEnd;
1513 continue;
1514 }
1515
1516 if (nonPPLineAffected(Line, PreviousLine))
1517 SomeLineAffected = true;
1518
1519 PreviousLine = Line;
1520 ++I;
1521 }
1522 return SomeLineAffected;
1523 }
1524
1525 // Determines whether 'Line' is affected by the SourceRanges given as input.
1526 // Returns \c true if line or one if its children is affected.
1527 bool nonPPLineAffected(AnnotatedLine *Line,
1528 const AnnotatedLine *PreviousLine) {
1529 bool SomeLineAffected = false;
1530 Line->ChildrenAffected =
1531 computeAffectedLines(Line->Children.begin(), Line->Children.end());
1532 if (Line->ChildrenAffected)
1533 SomeLineAffected = true;
1534
1535 // Stores whether one of the line's tokens is directly affected.
1536 bool SomeTokenAffected = false;
1537 // Stores whether we need to look at the leading newlines of the next token
1538 // in order to determine whether it was affected.
1539 bool IncludeLeadingNewlines = false;
1540
1541 // Stores whether the first child line of any of this line's tokens is
1542 // affected.
1543 bool SomeFirstChildAffected = false;
1544
1545 for (FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) {
1546 // Determine whether 'Tok' was affected.
1547 if (affectsTokenRange(*Tok, *Tok, IncludeLeadingNewlines))
1548 SomeTokenAffected = true;
1549
1550 // Determine whether the first child of 'Tok' was affected.
1551 if (!Tok->Children.empty() && Tok->Children.front()->Affected)
1552 SomeFirstChildAffected = true;
1553
1554 IncludeLeadingNewlines = Tok->Children.empty();
1555 }
1556
1557 // Was this line moved, i.e. has it previously been on the same line as an
1558 // affected line?
1559 bool LineMoved = PreviousLine && PreviousLine->Affected &&
1560 Line->First->NewlinesBefore == 0;
1561
1562 bool IsContinuedComment = Line->First->is(tok::comment) &&
1563 Line->First->Next == NULL &&
1564 Line->First->NewlinesBefore < 2 && PreviousLine &&
1565 PreviousLine->Affected &&
1566 PreviousLine->Last->is(tok::comment);
1567
1568 if (SomeTokenAffected || SomeFirstChildAffected || LineMoved ||
1569 IsContinuedComment) {
1570 Line->Affected = true;
1571 SomeLineAffected = true;
1572 }
1573 return SomeLineAffected;
1574 }
1575
1576 // Marks all lines between I and E as well as all their children as affected.
1577 void markAllAsAffected(SmallVectorImpl<AnnotatedLine *>::iterator I,
1578 SmallVectorImpl<AnnotatedLine *>::iterator E) {
1579 while (I != E) {
1580 (*I)->Affected = true;
1581 markAllAsAffected((*I)->Children.begin(), (*I)->Children.end());
1582 ++I;
1583 }
1584 }
1585
1586 // Returns true if the range from 'First' to 'Last' intersects with one of the
1587 // input ranges.
1588 bool affectsTokenRange(const FormatToken &First, const FormatToken &Last,
1589 bool IncludeLeadingNewlines) {
1590 SourceLocation Start = First.WhitespaceRange.getBegin();
1591 if (!IncludeLeadingNewlines)
1592 Start = Start.getLocWithOffset(First.LastNewlineOffset);
1593 SourceLocation End = Last.getStartOfNonWhitespace();
1594 if (Last.TokenText.size() > 0)
1595 End = End.getLocWithOffset(Last.TokenText.size() - 1);
1596 CharSourceRange Range = CharSourceRange::getCharRange(Start, End);
1597 return affectsCharSourceRange(Range);
1598 }
1599
1600 // Returns true if one of the input ranges intersect the leading empty lines
1601 // before 'Tok'.
1602 bool affectsLeadingEmptyLines(const FormatToken &Tok) {
1603 CharSourceRange EmptyLineRange = CharSourceRange::getCharRange(
1604 Tok.WhitespaceRange.getBegin(),
1605 Tok.WhitespaceRange.getBegin().getLocWithOffset(Tok.LastNewlineOffset));
1606 return affectsCharSourceRange(EmptyLineRange);
1607 }
1608
1609 // Returns true if 'Range' intersects with one of the input ranges.
1610 bool affectsCharSourceRange(const CharSourceRange &Range) {
1611 for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(),
1612 E = Ranges.end();
1613 I != E; ++I) {
1614 if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), I->getBegin()) &&
1615 !SourceMgr.isBeforeInTranslationUnit(I->getEnd(), Range.getBegin()))
1616 return true;
1617 }
1618 return false;
1619 }
1620
Alexander Kornienko73d845c2013-09-11 12:25:57 +00001621 static bool inputUsesCRLF(StringRef Text) {
1622 return Text.count('\r') * 2 > Text.count('\n');
1623 }
1624
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001625 void
1626 deriveLocalStyle(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
Daniel Jasper8ff690a2013-02-06 14:22:40 +00001627 unsigned CountBoundToVariable = 0;
1628 unsigned CountBoundToType = 0;
1629 bool HasCpp03IncompatibleFormat = false;
Daniel Jasperc7bd68f2013-07-10 14:02:49 +00001630 bool HasBinPackedFunction = false;
1631 bool HasOnePerLineFunction = false;
Daniel Jasper8ff690a2013-02-06 14:22:40 +00001632 for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
Daniel Jasper567dcf92013-09-05 09:29:45 +00001633 if (!AnnotatedLines[i]->First->Next)
Daniel Jasper8ff690a2013-02-06 14:22:40 +00001634 continue;
Daniel Jasper567dcf92013-09-05 09:29:45 +00001635 FormatToken *Tok = AnnotatedLines[i]->First->Next;
Manuel Klimekb3987012013-05-29 14:47:47 +00001636 while (Tok->Next) {
Daniel Jasper8ff690a2013-02-06 14:22:40 +00001637 if (Tok->Type == TT_PointerOrReference) {
Manuel Klimekb3987012013-05-29 14:47:47 +00001638 bool SpacesBefore =
1639 Tok->WhitespaceRange.getBegin() != Tok->WhitespaceRange.getEnd();
1640 bool SpacesAfter = Tok->Next->WhitespaceRange.getBegin() !=
1641 Tok->Next->WhitespaceRange.getEnd();
Daniel Jasper8ff690a2013-02-06 14:22:40 +00001642 if (SpacesBefore && !SpacesAfter)
1643 ++CountBoundToVariable;
1644 else if (!SpacesBefore && SpacesAfter)
1645 ++CountBoundToType;
1646 }
1647
Daniel Jasper78a4e612013-10-12 05:16:06 +00001648 if (Tok->WhitespaceRange.getBegin() == Tok->WhitespaceRange.getEnd()) {
1649 if (Tok->is(tok::coloncolon) &&
1650 Tok->Previous->Type == TT_TemplateOpener)
1651 HasCpp03IncompatibleFormat = true;
1652 if (Tok->Type == TT_TemplateCloser &&
1653 Tok->Previous->Type == TT_TemplateCloser)
1654 HasCpp03IncompatibleFormat = true;
1655 }
Daniel Jasperc7bd68f2013-07-10 14:02:49 +00001656
1657 if (Tok->PackingKind == PPK_BinPacked)
1658 HasBinPackedFunction = true;
1659 if (Tok->PackingKind == PPK_OnePerLine)
1660 HasOnePerLineFunction = true;
1661
Manuel Klimekb3987012013-05-29 14:47:47 +00001662 Tok = Tok->Next;
Daniel Jasper8ff690a2013-02-06 14:22:40 +00001663 }
1664 }
1665 if (Style.DerivePointerBinding) {
1666 if (CountBoundToType > CountBoundToVariable)
1667 Style.PointerBindsToType = true;
1668 else if (CountBoundToType < CountBoundToVariable)
1669 Style.PointerBindsToType = false;
1670 }
1671 if (Style.Standard == FormatStyle::LS_Auto) {
1672 Style.Standard = HasCpp03IncompatibleFormat ? FormatStyle::LS_Cpp11
1673 : FormatStyle::LS_Cpp03;
1674 }
Daniel Jasperc7bd68f2013-07-10 14:02:49 +00001675 BinPackInconclusiveFunctions =
1676 HasBinPackedFunction || !HasOnePerLineFunction;
Daniel Jasper8ff690a2013-02-06 14:22:40 +00001677 }
1678
Stephen Hines651f13c2014-04-23 16:59:28 -07001679 void consumeUnwrappedLine(const UnwrappedLine &TheLine) override {
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001680 assert(!UnwrappedLines.empty());
1681 UnwrappedLines.back().push_back(TheLine);
1682 }
1683
Stephen Hines651f13c2014-04-23 16:59:28 -07001684 void finishRun() override {
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001685 UnwrappedLines.push_back(SmallVector<UnwrappedLine, 16>());
Daniel Jasperbac016b2012-12-03 18:12:45 +00001686 }
1687
1688 FormatStyle Style;
1689 Lexer &Lex;
1690 SourceManager &SourceMgr;
Daniel Jasperdcc2a622013-01-18 08:44:07 +00001691 WhitespaceManager Whitespaces;
Daniel Jasper2a80ad62013-11-05 19:10:03 +00001692 SmallVector<CharSourceRange, 8> Ranges;
Manuel Klimekae76f7f2013-10-11 21:25:45 +00001693 SmallVector<SmallVector<UnwrappedLine, 16>, 2> UnwrappedLines;
Alexander Kornienko00895102013-06-05 14:09:10 +00001694
1695 encoding::Encoding Encoding;
Daniel Jasperc7bd68f2013-07-10 14:02:49 +00001696 bool BinPackInconclusiveFunctions;
Daniel Jasperbac016b2012-12-03 18:12:45 +00001697};
1698
Craig Topper83f81d72013-06-30 22:29:28 +00001699} // end anonymous namespace
1700
Alexander Kornienko70ce7882013-04-15 14:28:00 +00001701tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
1702 SourceManager &SourceMgr,
Daniel Jaspercaf42a32013-05-15 08:14:19 +00001703 std::vector<CharSourceRange> Ranges) {
1704 Formatter formatter(Style, Lex, SourceMgr, Ranges);
Daniel Jasperbac016b2012-12-03 18:12:45 +00001705 return formatter.format();
1706}
1707
Daniel Jasper8a999452013-05-16 10:40:07 +00001708tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
1709 std::vector<tooling::Range> Ranges,
1710 StringRef FileName) {
1711 FileManager Files((FileSystemOptions()));
1712 DiagnosticsEngine Diagnostics(
1713 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
1714 new DiagnosticOptions);
1715 SourceManager SourceMgr(Diagnostics, Files);
1716 llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(Code, FileName);
1717 const clang::FileEntry *Entry =
1718 Files.getVirtualFile(FileName, Buf->getBufferSize(), 0);
1719 SourceMgr.overrideFileContents(Entry, Buf);
1720 FileID ID =
1721 SourceMgr.createFileID(Entry, SourceLocation(), clang::SrcMgr::C_User);
Alexander Kornienkoa1753f42013-06-28 12:51:24 +00001722 Lexer Lex(ID, SourceMgr.getBuffer(ID), SourceMgr,
1723 getFormattingLangOpts(Style.Standard));
Daniel Jasper8a999452013-05-16 10:40:07 +00001724 SourceLocation StartOfFile = SourceMgr.getLocForStartOfFile(ID);
1725 std::vector<CharSourceRange> CharRanges;
1726 for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
1727 SourceLocation Start = StartOfFile.getLocWithOffset(Ranges[i].getOffset());
1728 SourceLocation End = Start.getLocWithOffset(Ranges[i].getLength());
1729 CharRanges.push_back(CharSourceRange::getCharRange(Start, End));
1730 }
1731 return reformat(Style, Lex, SourceMgr, CharRanges);
1732}
1733
Alexander Kornienkoa1753f42013-06-28 12:51:24 +00001734LangOptions getFormattingLangOpts(FormatStyle::LanguageStandard Standard) {
Daniel Jasper46ef8522013-01-10 13:08:12 +00001735 LangOptions LangOpts;
1736 LangOpts.CPlusPlus = 1;
Alexander Kornienkoa1753f42013-06-28 12:51:24 +00001737 LangOpts.CPlusPlus11 = Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
Daniel Jasperb64eca02013-03-22 10:01:29 +00001738 LangOpts.LineComment = 1;
Daniel Jasper46ef8522013-01-10 13:08:12 +00001739 LangOpts.Bool = 1;
1740 LangOpts.ObjC1 = 1;
1741 LangOpts.ObjC2 = 1;
1742 return LangOpts;
1743}
1744
Edwin Vanef4e12c82013-09-30 13:31:48 +00001745const char *StyleOptionHelpDescription =
1746 "Coding style, currently supports:\n"
1747 " LLVM, Google, Chromium, Mozilla, WebKit.\n"
1748 "Use -style=file to load style configuration from\n"
1749 ".clang-format file located in one of the parent\n"
1750 "directories of the source file (or current\n"
1751 "directory for stdin).\n"
1752 "Use -style=\"{key: value, ...}\" to set specific\n"
1753 "parameters, e.g.:\n"
1754 " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
1755
Stephen Hines651f13c2014-04-23 16:59:28 -07001756static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
1757 if (FileName.endswith_lower(".js")) {
1758 return FormatStyle::LK_JavaScript;
1759 } else if (FileName.endswith_lower(".proto") ||
1760 FileName.endswith_lower(".protodevel")) {
1761 return FormatStyle::LK_Proto;
1762 }
1763 return FormatStyle::LK_Cpp;
1764}
1765
1766FormatStyle getStyle(StringRef StyleName, StringRef FileName,
1767 StringRef FallbackStyle) {
1768 FormatStyle Style = getLLVMStyle();
1769 Style.Language = getLanguageByFileName(FileName);
1770 if (!getPredefinedStyle(FallbackStyle, Style.Language, &Style)) {
1771 llvm::errs() << "Invalid fallback style \"" << FallbackStyle
1772 << "\" using LLVM style\n";
1773 return Style;
1774 }
Edwin Vanef4e12c82013-09-30 13:31:48 +00001775
1776 if (StyleName.startswith("{")) {
1777 // Parse YAML/JSON style from the command line.
1778 if (llvm::error_code ec = parseConfiguration(StyleName, &Style)) {
Alexander Kornienkof0fc89c2013-10-14 00:46:35 +00001779 llvm::errs() << "Error parsing -style: " << ec.message() << ", using "
1780 << FallbackStyle << " style\n";
Edwin Vanef4e12c82013-09-30 13:31:48 +00001781 }
1782 return Style;
1783 }
1784
1785 if (!StyleName.equals_lower("file")) {
Stephen Hines651f13c2014-04-23 16:59:28 -07001786 if (!getPredefinedStyle(StyleName, Style.Language, &Style))
Edwin Vanef4e12c82013-09-30 13:31:48 +00001787 llvm::errs() << "Invalid value for -style, using " << FallbackStyle
1788 << " style\n";
1789 return Style;
1790 }
1791
Stephen Hines651f13c2014-04-23 16:59:28 -07001792 // Look for .clang-format/_clang-format file in the file's parent directories.
1793 SmallString<128> UnsuitableConfigFiles;
Edwin Vanef4e12c82013-09-30 13:31:48 +00001794 SmallString<128> Path(FileName);
1795 llvm::sys::fs::make_absolute(Path);
Alexander Kornienkof0fc89c2013-10-14 00:46:35 +00001796 for (StringRef Directory = Path; !Directory.empty();
Edwin Vanef4e12c82013-09-30 13:31:48 +00001797 Directory = llvm::sys::path::parent_path(Directory)) {
1798 if (!llvm::sys::fs::is_directory(Directory))
1799 continue;
1800 SmallString<128> ConfigFile(Directory);
1801
1802 llvm::sys::path::append(ConfigFile, ".clang-format");
1803 DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
1804 bool IsFile = false;
1805 // Ignore errors from is_regular_file: we only need to know if we can read
1806 // the file or not.
1807 llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
1808
1809 if (!IsFile) {
1810 // Try _clang-format too, since dotfiles are not commonly used on Windows.
1811 ConfigFile = Directory;
1812 llvm::sys::path::append(ConfigFile, "_clang-format");
1813 DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
1814 llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
1815 }
1816
1817 if (IsFile) {
Stephen Hines651f13c2014-04-23 16:59:28 -07001818 std::unique_ptr<llvm::MemoryBuffer> Text;
Rafael Espindola28ce23a2013-10-25 19:00:49 +00001819 if (llvm::error_code ec =
1820 llvm::MemoryBuffer::getFile(ConfigFile.c_str(), Text)) {
Edwin Vanef4e12c82013-09-30 13:31:48 +00001821 llvm::errs() << ec.message() << "\n";
Stephen Hines651f13c2014-04-23 16:59:28 -07001822 break;
Edwin Vanef4e12c82013-09-30 13:31:48 +00001823 }
1824 if (llvm::error_code ec = parseConfiguration(Text->getBuffer(), &Style)) {
Stephen Hines651f13c2014-04-23 16:59:28 -07001825 if (ec == llvm::errc::not_supported) {
1826 if (!UnsuitableConfigFiles.empty())
1827 UnsuitableConfigFiles.append(", ");
1828 UnsuitableConfigFiles.append(ConfigFile);
1829 continue;
1830 }
Edwin Vanef4e12c82013-09-30 13:31:48 +00001831 llvm::errs() << "Error reading " << ConfigFile << ": " << ec.message()
1832 << "\n";
Stephen Hines651f13c2014-04-23 16:59:28 -07001833 break;
Edwin Vanef4e12c82013-09-30 13:31:48 +00001834 }
1835 DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n");
1836 return Style;
1837 }
1838 }
1839 llvm::errs() << "Can't find usable .clang-format, using " << FallbackStyle
1840 << " style\n";
Stephen Hines651f13c2014-04-23 16:59:28 -07001841 if (!UnsuitableConfigFiles.empty()) {
1842 llvm::errs() << "Configuration file(s) do(es) not support "
1843 << getLanguageName(Style.Language) << ": "
1844 << UnsuitableConfigFiles << "\n";
1845 }
Edwin Vanef4e12c82013-09-30 13:31:48 +00001846 return Style;
1847}
1848
Daniel Jaspercd162382013-01-07 13:26:07 +00001849} // namespace format
1850} // namespace clang