From: Daniel Jasper Date: Tue, 17 Jun 2014 12:40:34 +0000 (+0000) Subject: clang-format: Introduce style with spaces on both sides of */&. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=553d4878da8855a12d03a97e2ce39b97e2a0a068;p=platform%2Fupstream%2Fllvm.git clang-format: Introduce style with spaces on both sides of */&. Patch by Janusz Sobczak (slightly extended). This fixes llvm.org/19929. llvm-svn: 211098 --- diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 0483bd7..fefeff3 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -211,9 +211,12 @@ the configuration (without a prefix: ``Auto``). 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 @@ -314,8 +317,18 @@ the configuration (without a prefix: ``Auto``). 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. diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 23f65fe..0dfd7f0 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -85,12 +85,22 @@ struct FormatStyle { /// \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; @@ -373,7 +383,7 @@ struct FormatStyle { ColumnLimit == R.ColumnLimit && ConstructorInitializerAllOnOneLineOrOnePerLine == R.ConstructorInitializerAllOnOneLineOrOnePerLine && - DerivePointerBinding == R.DerivePointerBinding && + DerivePointerAlignment == R.DerivePointerAlignment && ExperimentalAutoDetectBinPacking == R.ExperimentalAutoDetectBinPacking && IndentCaseLabels == R.IndentCaseLabels && @@ -391,7 +401,7 @@ struct FormatStyle { 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 && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 913c622..5cbad82 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -97,6 +97,20 @@ struct ScalarEnumerationTraits { }; template <> +struct ScalarEnumerationTraits { + 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 { static void enumeration(IO &IO, FormatStyle::SpaceBeforeParensOptions &Value) { @@ -173,7 +187,7 @@ template <> struct MappingTraits { 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); @@ -193,7 +207,7 @@ template <> struct MappingTraits { 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); @@ -221,6 +235,8 @@ template <> struct MappingTraits { 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); @@ -306,7 +322,7 @@ FormatStyle getLLVMStyle() { 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"); @@ -320,7 +336,7 @@ FormatStyle getLLVMStyle() { 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; @@ -355,13 +371,13 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { 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; @@ -387,7 +403,7 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) { ChromiumStyle.AllowShortIfStatementsOnASingleLine = false; ChromiumStyle.AllowShortLoopsOnASingleLine = false; ChromiumStyle.BinPackParameters = false; - ChromiumStyle.DerivePointerBinding = false; + ChromiumStyle.DerivePointerAlignment = false; ChromiumStyle.Standard = FormatStyle::LS_Cpp03; return ChromiumStyle; } @@ -397,12 +413,12 @@ FormatStyle getMozillaStyle() { 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; } @@ -419,7 +435,7 @@ FormatStyle getWebKitStyle() { 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; } @@ -1906,11 +1922,11 @@ private: 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 diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index f92a8f0..dd1c681 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1460,14 +1460,14 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, 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)) diff --git a/clang/test/Format/style-on-command-line.cpp b/clang/test/Format/style-on-command-line.cpp index a0a39cb..007022e 100644 --- a/clang/test/Format/style-on-command-line.cpp +++ b/clang/test/Format/style-on-command-line.cpp @@ -12,6 +12,8 @@ // 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;$}} @@ -25,6 +27,8 @@ void f() { // 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; } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index ecccc70..13954fa 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -4587,7 +4587,7 @@ TEST_F(FormatTest, UnderstandsPointersToMembers) { " aaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb);\n" "}"); FormatStyle Style = getLLVMStyle(); - Style.PointerBindsToType = true; + Style.PointerAlignment = FormatStyle::PAS_Left; verifyFormat("typedef bool* (Class::*Member)() const;", Style); } @@ -4823,7 +4823,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { 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));"); @@ -4857,6 +4857,22 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { // FIXME: We cannot handle this case yet; we might be able to figure out that // foo d > v; doesn't make sense. verifyFormat("foo d > v;"); + + FormatStyle PointerMiddle = getLLVMStyle(); + PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle; + verifyFormat("delete *x;", PointerMiddle); + verifyFormat("int * x;", PointerMiddle); + verifyFormat("template 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 a;", PointerMiddle); + verifyFormat("A a;", PointerMiddle); + verifyFormat("A a;", PointerMiddle); + verifyFormat("A a;", PointerMiddle); + verifyFormat("A = new SomeType * [Length]();", PointerMiddle); + verifyFormat("A = new SomeType * [Length];", PointerMiddle); + verifyFormat("T ** t = new T *;", PointerMiddle); } TEST_F(FormatTest, UnderstandsAttributes) { @@ -4871,7 +4887,7 @@ TEST_F(FormatTest, UnderstandsEllipsis) { verifyFormat("template void Foo(Ts *... ts) {}"); FormatStyle PointersLeft = getLLVMStyle(); - PointersLeft.PointerBindsToType = true; + PointersLeft.PointerAlignment = FormatStyle::PAS_Left; verifyFormat("template void Foo(Ts*... ts) {}", PointersLeft); } @@ -8071,12 +8087,11 @@ TEST_F(FormatTest, ParsesConfiguration) { 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); @@ -8101,6 +8116,11 @@ TEST_F(FormatTest, ParsesConfiguration) { 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);