summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/docs/ClangFormatStyleOptions.rst18
-rw-r--r--clang/include/clang/Format/Format.h5
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp12
-rw-r--r--clang/lib/Format/Format.cpp4
-rw-r--r--clang/unittests/Format/FormatTest.cpp63
-rw-r--r--clang/unittests/Format/FormatTestJava.cpp2
6 files changed, 96 insertions, 8 deletions
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index cef3f247640..af9181ace0e 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -150,10 +150,24 @@ the configuration (without a prefix: ``Auto``).
**AccessModifierOffset** (``int``)
The extra indent or outdent of access modifiers, e.g. ``public:``.
+**AlignAfterOpenBracket** (``bool``)
+ If ``true``, horizontally aligns arguments after an open bracket.
+
+ This applies to round brackets (parentheses), angle brackets and square
+ brackets. This will result in formattings like
+ \code
+ someLongFunction(argument1,
+ argument2);
+ \endcode
+
**AlignEscapedNewlinesLeft** (``bool``)
If ``true``, aligns escaped newlines as far left as possible.
Otherwise puts them into the right-most column.
+**AlignOperands** (``bool``)
+ If ``true``, horizontally align operands of binary and ternary
+ expressions.
+
**AlignTrailingComments** (``bool``)
If ``true``, aligns trailing comments.
@@ -179,6 +193,8 @@ the configuration (without a prefix: ``Auto``).
Never merge functions into a single line.
* ``SFS_Inline`` (in configuration: ``Inline``)
Only merge functions defined inside a class.
+ * ``SFS_Empty`` (in configuration: ``Empty``)
+ Only merge empty functions.
* ``SFS_All`` (in configuration: ``All``)
Merge all functions fitting on a single line.
@@ -292,7 +308,7 @@ the configuration (without a prefix: ``Auto``).
**DerivePointerAlignment** (``bool``)
If ``true``, analyze the formatted file for the most common
- alignment of & and \*. ``PointerAlignment`` is then used only as fallback.
+ alignment of & and *. ``PointerAlignment`` is then used only as fallback.
**DisableFormat** (``bool``)
Disables formatting at all.
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 41e69857314..60c54abd1a9 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -240,6 +240,10 @@ struct FormatStyle {
/// \endcode
bool AlignAfterOpenBracket;
+ /// \brief If \c true, horizontally align operands of binary and ternary
+ /// expressions.
+ bool AlignOperands;
+
/// \brief If \c true, aligns trailing comments.
bool AlignTrailingComments;
@@ -407,6 +411,7 @@ struct FormatStyle {
bool operator==(const FormatStyle &R) const {
return AccessModifierOffset == R.AccessModifierOffset &&
AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
+ AlignOperands == R.AlignOperands &&
AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft &&
AlignTrailingComments == R.AlignTrailingComments &&
AllowAllParametersOfDeclarationOnNextLine ==
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 53381703513..e053d4c1aac 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -178,9 +178,6 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
// expression itself as otherwise, the line breaks seem superfluous.
// We need special cases for ">>" which we have split into two ">" while
// lexing in order to make template parsing easier.
- //
- // FIXME: We'll need something similar for styles that break before binary
- // operators.
bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
Previous.getPrecedence() == prec::Equality) &&
Previous.Previous &&
@@ -193,8 +190,13 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
Previous.getPrecedence() != prec::Assignment &&
State.Stack.back().BreakBeforeParameter)
return true;
+ } else {
+ if (Current.is(TT_BinaryOperator) && Previous.EndsBinaryExpression &&
+ State.Stack.back().BreakBeforeParameter)
+ return true;
}
+
// Same as above, but for the first "<<" operator.
if (Current.is(tok::lessless) && Current.isNot(TT_OverloadedOperator) &&
State.Stack.back().BreakBeforeParameter &&
@@ -712,7 +714,8 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
// is special cased.
bool SkipFirstExtraIndent =
(Previous && (Previous->opensScope() || Previous->is(tok::kw_return) ||
- Previous->getPrecedence() == prec::Assignment ||
+ (Previous->getPrecedence() == prec::Assignment &&
+ Style.AlignOperands) ||
Previous->is(TT_ObjCMethodExpr)));
for (SmallVectorImpl<prec::Level>::const_reverse_iterator
I = Current.FakeLParens.rbegin(),
@@ -725,6 +728,7 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
// a builder type call after 'return' or, if the alignment after opening
// brackets is disabled.
if (!Current.isTrailingComment() &&
+ (Style.AlignOperands || *I < prec::Assignment) &&
(!Previous || Previous->isNot(tok::kw_return) ||
(Style.Language != FormatStyle::LK_Java && *I > 0)) &&
(Style.AlignAfterOpenBracket || *I != prec::Comma ||
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 9fbab27bb51..cf8e5d32ae5 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -173,6 +173,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft);
+ IO.mapOptional("AlignOperands", Style.AlignOperands);
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
Style.AllowAllParametersOfDeclarationOnNextLine);
@@ -327,6 +328,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.AccessModifierOffset = -2;
LLVMStyle.AlignEscapedNewlinesLeft = false;
LLVMStyle.AlignAfterOpenBracket = true;
+ LLVMStyle.AlignOperands = true;
LLVMStyle.AlignTrailingComments = true;
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
@@ -415,6 +417,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
if (Language == FormatStyle::LK_Java) {
GoogleStyle.AlignAfterOpenBracket = false;
+ GoogleStyle.AlignOperands = false;
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
GoogleStyle.ColumnLimit = 100;
@@ -468,6 +471,7 @@ FormatStyle getWebKitStyle() {
FormatStyle Style = getLLVMStyle();
Style.AccessModifierOffset = -4;
Style.AlignAfterOpenBracket = false;
+ Style.AlignOperands = false;
Style.AlignTrailingComments = false;
Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index cdc1c9e4a35..148c2f98ff7 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -3289,6 +3289,10 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) {
" // comment\n"
" + b;",
Style);
+ verifyFormat("int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " + cc;",
+ Style);
// Forced by comments.
verifyFormat(
@@ -3309,13 +3313,39 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) {
Style);
}
+TEST_F(FormatTest, NoOperandAlignment) {
+ FormatStyle Style = getLLVMStyle();
+ Style.AlignOperands = false;
+ Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
+ verifyFormat(
+ "bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " > ccccccccccccccccccccccccccccccccccccccccc;",
+ Style);
+
+ verifyFormat("int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " + cc;",
+ Style);
+ verifyFormat("int a = aa\n"
+ " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
+ " * cccccccccccccccccccccccccccccccccccc;",
+ Style);
+}
+
TEST_F(FormatTest, BreakingBeforeNonAssigmentOperators) {
FormatStyle Style = getLLVMStyle();
Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
- " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", Style);
-
+ " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;",
+ Style);
}
TEST_F(FormatTest, ConstructorInitializers) {
@@ -4083,6 +4113,28 @@ TEST_F(FormatTest, AlignsAfterOpenBracket) {
Style);
}
+TEST_F(FormatTest, ParenthesesAndOperandAlignment) {
+ FormatStyle Style = getLLVMStyleWithColumns(40);
+ verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n"
+ " bbbbbbbbbbbbbbbbbbbbbb);",
+ Style);
+ Style.AlignAfterOpenBracket = true;
+ Style.AlignOperands = false;
+ verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n"
+ " bbbbbbbbbbbbbbbbbbbbbb);",
+ Style);
+ Style.AlignAfterOpenBracket = false;
+ Style.AlignOperands = true;
+ verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n"
+ " bbbbbbbbbbbbbbbbbbbbbb);",
+ Style);
+ Style.AlignAfterOpenBracket = false;
+ Style.AlignOperands = false;
+ verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n"
+ " bbbbbbbbbbbbbbbbbbbbbb);",
+ Style);
+}
+
TEST_F(FormatTest, BreaksConditionalExpressions) {
verifyFormat(
"aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
@@ -8579,7 +8631,9 @@ TEST_F(FormatTest, GetsCorrectBasedOnStyle) {
TEST_F(FormatTest, ParsesConfigurationBools) {
FormatStyle Style = {};
Style.Language = FormatStyle::LK_Cpp;
+ CHECK_PARSE_BOOL(AlignAfterOpenBracket);
CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft);
+ CHECK_PARSE_BOOL(AlignOperands);
CHECK_PARSE_BOOL(AlignTrailingComments);
CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine);
@@ -9187,6 +9241,11 @@ TEST_F(FormatTest, FormatsWithWebKitStyle) {
"double b; // align comments.",
Style);
+ // Do not align operands.
+ EXPECT_EQ("ASSERT(aaaa\n"
+ " || bbbb);",
+ format("ASSERT ( aaaa\n||bbbb);", Style));
+
// Accept input's line breaks.
EXPECT_EQ("if (aaaaaaaaaaaaaaa\n"
" || bbbbbbbbbbbbbbb) {\n"
diff --git a/clang/unittests/Format/FormatTestJava.cpp b/clang/unittests/Format/FormatTestJava.cpp
index 95d19618046..ad80d1377a9 100644
--- a/clang/unittests/Format/FormatTestJava.cpp
+++ b/clang/unittests/Format/FormatTestJava.cpp
@@ -291,7 +291,7 @@ TEST_F(FormatTestJava, Generics) {
TEST_F(FormatTestJava, StringConcatenation) {
verifyFormat("String someString = \"abc\"\n"
- " + \"cde\";");
+ " + \"cde\";");
}
TEST_F(FormatTestJava, TryCatchFinally) {
OpenPOWER on IntegriCloud