the parentheses of a function call with that name. If there is no name,
a zero-length name is assumed.
-**DerivePointerBinding** (``bool``)
- If ``true``, analyze the formatted file for the most common binding
- and use ``PointerBindsToType`` only as fallback.
+**DerivePointerAlignment** (``bool``)
+ If ``true``, analyze the formatted file for the most common
+ alignment of & and *. ``PointerAlignment`` is then used only as fallback.
+
+**DisableFormat** (``bool``)
+ Disables formatting at all.
**ExperimentalAutoDetectBinPacking** (``bool``)
If ``true``, clang-format detects whether function calls and
Penalty for putting the return type of a function onto its own
line.
-**PointerBindsToType** (``bool``)
- Set whether & and * bind to the type as opposed to the variable.
+**PointerAlignment** (``PointerAlignmentStyle``)
+ Pointer and reference alignment style.
+
+ Possible values:
+
+ * ``PAS_Left`` (in configuration: ``Left``)
+ Align pointer to the left.
+ * ``PAS_Right`` (in configuration: ``Right``)
+ Align pointer to the right.
+ * ``PAS_Middle`` (in configuration: ``Middle``)
+ Align pointer in the middle.
+
**SpaceBeforeAssignmentOperators** (``bool``)
If ``false``, spaces will be removed before assignment operators.
/// \brief The penalty for breaking a function call after "call(".
unsigned PenaltyBreakBeforeFirstCallParameter;
- /// \brief Set whether & and * bind to the type as opposed to the variable.
- bool PointerBindsToType;
+ /// \brief The & and * alignment style.
+ enum PointerAlignmentStyle {
+ /// Align pointer to the left.
+ PAS_Left,
+ /// Align pointer to the right.
+ PAS_Right,
+ /// Align pointer in the middle.
+ PAS_Middle
+ };
+
+ /// Pointer and reference alignment style.
+ PointerAlignmentStyle PointerAlignment;
- /// \brief If \c true, analyze the formatted file for the most common binding
- /// and use \c PointerBindsToType only as fallback.
- bool DerivePointerBinding;
+ /// \brief If \c true, analyze the formatted file for the most common
+ /// alignment of & and *. \c PointerAlignment is then used only as fallback.
+ bool DerivePointerAlignment;
/// \brief The extra indent or outdent of access modifiers, e.g. \c public:.
int AccessModifierOffset;
ColumnLimit == R.ColumnLimit &&
ConstructorInitializerAllOnOneLineOrOnePerLine ==
R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
- DerivePointerBinding == R.DerivePointerBinding &&
+ DerivePointerAlignment == R.DerivePointerAlignment &&
ExperimentalAutoDetectBinPacking ==
R.ExperimentalAutoDetectBinPacking &&
IndentCaseLabels == R.IndentCaseLabels &&
PenaltyBreakString == R.PenaltyBreakString &&
PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
- PointerBindsToType == R.PointerBindsToType &&
+ PointerAlignment == R.PointerAlignment &&
SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
Cpp11BracedListStyle == R.Cpp11BracedListStyle &&
Standard == R.Standard && TabWidth == R.TabWidth &&
}
};
+template <>
+struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
+ static void enumeration(IO &IO,
+ FormatStyle::PointerAlignmentStyle &Value) {
+ IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
+ IO.enumCase(Value, "Left", FormatStyle::PAS_Left);
+ IO.enumCase(Value, "Right", FormatStyle::PAS_Right);
+
+ // For backward compability.
+ IO.enumCase(Value, "true", FormatStyle::PAS_Left);
+ IO.enumCase(Value, "false", FormatStyle::PAS_Right);
+ }
+};
+
template <>
struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
static void enumeration(IO &IO,
IO.mapOptional("ColumnLimit", Style.ColumnLimit);
IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
- IO.mapOptional("DerivePointerBinding", Style.DerivePointerBinding);
+ IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
IO.mapOptional("ExperimentalAutoDetectBinPacking",
Style.ExperimentalAutoDetectBinPacking);
IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
Style.PenaltyReturnTypeOnItsOwnLine);
- IO.mapOptional("PointerBindsToType", Style.PointerBindsToType);
+ IO.mapOptional("PointerAlignment", Style.PointerAlignment);
IO.mapOptional("SpacesBeforeTrailingComments",
Style.SpacesBeforeTrailingComments);
IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
if (!IO.outputting()) {
IO.mapOptional("SpaceAfterControlStatementKeyword",
Style.SpaceBeforeParens);
+ IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
+ IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
}
IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
IO.mapOptional("DisableFormat", Style.DisableFormat);
LLVMStyle.ConstructorInitializerIndentWidth = 4;
LLVMStyle.ContinuationIndentWidth = 4;
LLVMStyle.Cpp11BracedListStyle = true;
- LLVMStyle.DerivePointerBinding = false;
+ LLVMStyle.DerivePointerAlignment = false;
LLVMStyle.ExperimentalAutoDetectBinPacking = false;
LLVMStyle.ForEachMacros.push_back("foreach");
LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
LLVMStyle.ObjCSpaceAfterProperty = false;
LLVMStyle.ObjCSpaceBeforeProtocolList = true;
- LLVMStyle.PointerBindsToType = false;
+ LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
LLVMStyle.SpacesBeforeTrailingComments = 1;
LLVMStyle.Standard = FormatStyle::LS_Cpp11;
LLVMStyle.UseTab = FormatStyle::UT_Never;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
GoogleStyle.AlwaysBreakTemplateDeclarations = true;
GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
- GoogleStyle.DerivePointerBinding = true;
+ GoogleStyle.DerivePointerAlignment = true;
GoogleStyle.IndentCaseLabels = true;
GoogleStyle.IndentFunctionDeclarationAfterType = true;
GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
GoogleStyle.ObjCSpaceAfterProperty = false;
GoogleStyle.ObjCSpaceBeforeProtocolList = false;
- GoogleStyle.PointerBindsToType = true;
+ GoogleStyle.PointerAlignment = FormatStyle::PAS_Left;
GoogleStyle.SpacesBeforeTrailingComments = 2;
GoogleStyle.Standard = FormatStyle::LS_Auto;
ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
ChromiumStyle.BinPackParameters = false;
- ChromiumStyle.DerivePointerBinding = false;
+ ChromiumStyle.DerivePointerAlignment = false;
ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
return ChromiumStyle;
}
MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
MozillaStyle.Cpp11BracedListStyle = false;
MozillaStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
- MozillaStyle.DerivePointerBinding = true;
+ MozillaStyle.DerivePointerAlignment = true;
MozillaStyle.IndentCaseLabels = true;
MozillaStyle.ObjCSpaceAfterProperty = true;
MozillaStyle.ObjCSpaceBeforeProtocolList = false;
MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
- MozillaStyle.PointerBindsToType = true;
+ MozillaStyle.PointerAlignment = FormatStyle::PAS_Left;
MozillaStyle.Standard = FormatStyle::LS_Cpp03;
return MozillaStyle;
}
Style.IndentWidth = 4;
Style.NamespaceIndentation = FormatStyle::NI_Inner;
Style.ObjCSpaceAfterProperty = true;
- Style.PointerBindsToType = true;
+ Style.PointerAlignment = FormatStyle::PAS_Left;
Style.Standard = FormatStyle::LS_Cpp03;
return Style;
}
Tok = Tok->Next;
}
}
- if (Style.DerivePointerBinding) {
+ if (Style.DerivePointerAlignment) {
if (CountBoundToType > CountBoundToVariable)
- Style.PointerBindsToType = true;
+ Style.PointerAlignment = FormatStyle::PAS_Left;
else if (CountBoundToType < CountBoundToVariable)
- Style.PointerBindsToType = false;
+ Style.PointerAlignment = FormatStyle::PAS_Right;
}
if (Style.Standard == FormatStyle::LS_Auto) {
Style.Standard = HasCpp03IncompatibleFormat ? FormatStyle::LS_Cpp11
if (Right.Type == TT_PointerOrReference)
return Left.Tok.isLiteral() ||
((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) &&
- !Style.PointerBindsToType);
+ Style.PointerAlignment != FormatStyle::PAS_Left);
if (Right.Type == TT_FunctionTypeLParen && Left.isNot(tok::l_paren) &&
- (Left.Type != TT_PointerOrReference || Style.PointerBindsToType))
+ (Left.Type != TT_PointerOrReference || Style.PointerAlignment != FormatStyle::PAS_Right))
return true;
if (Left.Type == TT_PointerOrReference)
return Right.Tok.isLiteral() || Right.Type == TT_BlockComment ||
((Right.Type != TT_PointerOrReference) &&
- Right.isNot(tok::l_paren) && Style.PointerBindsToType &&
+ Right.isNot(tok::l_paren) && Style.PointerAlignment != FormatStyle::PAS_Right &&
Left.Previous &&
!Left.Previous->isOneOf(tok::l_paren, tok::coloncolon));
if (Right.is(tok::star) && Left.is(tok::l_paren))
// RUN: [ ! -e %T/_clang-format ] || rm %T/_clang-format
// RUN: printf "BasedOnStyle: google\nIndentWidth: 6\n" > %T/_clang-format
// RUN: clang-format -style=file %t.cpp 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK7 %s
+// RUN: clang-format -style="{BasedOnStyle: LLVM, PointerBindsToType: true}" %t.cpp | FileCheck -strict-whitespace -check-prefix=CHECK8 %s
+// RUN: clang-format -style="{BasedOnStyle: WebKit, PointerBindsToType: false}" %t.cpp | FileCheck -strict-whitespace -check-prefix=CHECK9 %s
void f() {
// CHECK1: {{^ int\* i;$}}
// CHECK2: {{^ int \*i;$}}
// CHECK6: {{^Can't find usable .clang-format, using webkit style$}}
// CHECK6: {{^ int\* i;$}}
// CHECK7: {{^ int\* i;$}}
+// CHECK8: {{^ int\* i;$}}
+// CHECK9: {{^ int \*i;$}}
int*i;
int j;
}
" aaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb);\n"
"}");
FormatStyle Style = getLLVMStyle();
- Style.PointerBindsToType = true;
+ Style.PointerAlignment = FormatStyle::PAS_Left;
verifyFormat("typedef bool* (Class::*Member)() const;", Style);
}
verifyGoogleFormat("T** t = new T*();");
FormatStyle PointerLeft = getLLVMStyle();
- PointerLeft.PointerBindsToType = true;
+ PointerLeft.PointerAlignment = FormatStyle::PAS_Left;
verifyFormat("delete *x;", PointerLeft);
verifyFormat("STATIC_ASSERT((a & b) == 0);");
verifyFormat("STATIC_ASSERT(0 == (a & b));");
// FIXME: We cannot handle this case yet; we might be able to figure out that
// foo<x> d > v; doesn't make sense.
verifyFormat("foo<a < b && c> d > v;");
+
+ FormatStyle PointerMiddle = getLLVMStyle();
+ PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle;
+ verifyFormat("delete *x;", PointerMiddle);
+ verifyFormat("int * x;", PointerMiddle);
+ verifyFormat("template <int * y> f() {}", PointerMiddle);
+ verifyFormat("int * f(int * a) {}", PointerMiddle);
+ verifyFormat("int main(int argc, char ** argv) {}", PointerMiddle);
+ verifyFormat("Test::Test(int b) : a(b * b) {}", PointerMiddle);
+ verifyFormat("A<int *> a;", PointerMiddle);
+ verifyFormat("A<int **> a;", PointerMiddle);
+ verifyFormat("A<int *, int *> a;", PointerMiddle);
+ verifyFormat("A<int * []> a;", PointerMiddle);
+ verifyFormat("A = new SomeType * [Length]();", PointerMiddle);
+ verifyFormat("A = new SomeType * [Length];", PointerMiddle);
+ verifyFormat("T ** t = new T *;", PointerMiddle);
}
TEST_F(FormatTest, UnderstandsAttributes) {
verifyFormat("template <class... Ts> void Foo(Ts *... ts) {}");
FormatStyle PointersLeft = getLLVMStyle();
- PointersLeft.PointerBindsToType = true;
+ PointersLeft.PointerAlignment = FormatStyle::PAS_Left;
verifyFormat("template <class... Ts> void Foo(Ts*... ts) {}", PointersLeft);
}
CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma);
CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine);
- CHECK_PARSE_BOOL(DerivePointerBinding);
+ CHECK_PARSE_BOOL(DerivePointerAlignment);
CHECK_PARSE_BOOL(IndentCaseLabels);
CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
- CHECK_PARSE_BOOL(PointerBindsToType);
CHECK_PARSE_BOOL(Cpp11BracedListStyle);
CHECK_PARSE_BOOL(IndentFunctionDeclarationAfterType);
CHECK_PARSE_BOOL(SpacesInParentheses);
CHECK_PARSE("IndentWidth: 32", IndentWidth, 32u);
CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u);
+ Style.PointerAlignment = FormatStyle::PAS_Middle;
+ CHECK_PARSE("PointerAlignment: Left", PointerAlignment, FormatStyle::PAS_Left);
+ CHECK_PARSE("PointerAlignment: Right", PointerAlignment, FormatStyle::PAS_Right);
+ CHECK_PARSE("PointerAlignment: Middle", PointerAlignment, FormatStyle::PAS_Middle);
+
Style.Standard = FormatStyle::LS_Auto;
CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03);
CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Cpp11);