From: Daniel Jasper Date: Tue, 16 Jul 2013 18:22:10 +0000 (+0000) Subject: Revamp the formatting of C++11 braced init lists. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b5dc3f4f53981b681a565cdf1d49f18e817541ff;p=clang Revamp the formatting of C++11 braced init lists. The fundamental concept is: Format as if the braced init list was a function call (with parentheses replaced by braces). If there is no name/type before the opening brace (e.g. if the braced list is nested), assume a zero-length identifier just before the opening brace. This behavior is gated on a new style flag, which for now replaces the SpacesInBracedLists style flag. Activate this style flag for Google style to reflect recent style guide changes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186433 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index 0bfcc74175..a6998bc7ff 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -146,8 +146,20 @@ struct FormatStyle { /// \brief The brace breaking style to use. BraceBreakingStyle BreakBeforeBraces; - /// \brief If \c true, format { 1 }, otherwise {1}. - bool SpacesInBracedLists; + /// \brief If \c true, format braced lists as best suited for C++11 braced + /// lists. + /// + /// Important differences: + /// - No spaces inside the braced list. + /// - No line break before the closing brace. + /// - Indentation with the continuation indent, not with the block indent. + /// + /// Fundamentally, C++11 braced lists are formatted exactly like function + /// calls would be formatted in their place. If the braced list follows a name + /// (e.g. a type or variable name), clang-format formats as if the "{}" were + /// the parentheses of a function call with that name. If there is no name, + /// a zero-length name is assumed. + bool Cpp11BracedListStyle; /// \brief If \c true, indent when breaking function declarations which /// are not also definitions after the type. @@ -183,7 +195,7 @@ struct FormatStyle { PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine && PointerBindsToType == R.PointerBindsToType && SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments && - SpacesInBracedLists == R.SpacesInBracedLists && + Cpp11BracedListStyle == R.Cpp11BracedListStyle && Standard == R.Standard && UseTab == R.UseTab && IndentFunctionDeclarationAfterType == R.IndentFunctionDeclarationAfterType; diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 7904853689..27dd162d66 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -110,7 +110,7 @@ template <> struct MappingTraits { IO.mapOptional("PointerBindsToType", Style.PointerBindsToType); IO.mapOptional("SpacesBeforeTrailingComments", Style.SpacesBeforeTrailingComments); - IO.mapOptional("SpacesInBracedLists", Style.SpacesInBracedLists); + IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle); IO.mapOptional("Standard", Style.Standard); IO.mapOptional("IndentWidth", Style.IndentWidth); IO.mapOptional("UseTab", Style.UseTab); @@ -151,7 +151,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.ObjCSpaceBeforeProtocolList = true; LLVMStyle.PointerBindsToType = false; LLVMStyle.SpacesBeforeTrailingComments = 1; - LLVMStyle.SpacesInBracedLists = true; + LLVMStyle.Cpp11BracedListStyle = false; LLVMStyle.Standard = FormatStyle::LS_Cpp03; LLVMStyle.IndentWidth = 2; LLVMStyle.UseTab = false; @@ -183,7 +183,7 @@ FormatStyle getGoogleStyle() { GoogleStyle.ObjCSpaceBeforeProtocolList = false; GoogleStyle.PointerBindsToType = true; GoogleStyle.SpacesBeforeTrailingComments = 2; - GoogleStyle.SpacesInBracedLists = false; + GoogleStyle.Cpp11BracedListStyle = true; GoogleStyle.Standard = FormatStyle::LS_Auto; GoogleStyle.IndentWidth = 2; GoogleStyle.UseTab = false; @@ -815,7 +815,8 @@ private: unsigned LastSpace = State.Stack.back().LastSpace; bool AvoidBinPacking; if (Current.is(tok::l_brace)) { - NewIndent = Style.IndentWidth + LastSpace; + NewIndent = + LastSpace + (Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth); const FormatToken *NextNoComment = Current.getNextNonComment(); AvoidBinPacking = NextNoComment && NextNoComment->Type == TT_DesignatedInitializerPeriod; @@ -1139,8 +1140,9 @@ private: const FormatToken &Previous = *Current.Previous; if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon) return true; - if (Current.is(tok::r_brace) && State.Stack.back().BreakBeforeClosingBrace) - return true; + if (!Style.Cpp11BracedListStyle && Current.is(tok::r_brace) && + State.Stack.back().BreakBeforeClosingBrace) + return true; if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection) return true; if ((Previous.isOneOf(tok::comma, tok::semi) || Current.is(tok::question) || diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 2d1c1e3f4a..7a2364c0b9 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -1167,7 +1167,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) return false; // No spaces in "{}". if (Left.is(tok::l_brace) || Right.is(tok::r_brace)) - return Style.SpacesInBracedLists; + return !Style.Cpp11BracedListStyle; if (Right.Type == TT_UnaryOperator) return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) && (Left.isNot(tok::colon) || Left.Type != TT_ObjCMethodExpr); diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 747a140846..aa2a70987b 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -1637,10 +1637,9 @@ TEST_F(FormatTest, NestedStaticInitializers) { " { kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL }\n" "};"); verifyGoogleFormat("SomeType Status::global_reps[3] = {\n" - " {kGlobalRef, OK_CODE, NULL, NULL, NULL},\n" - " {kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL},\n" - " {kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL}\n" - "};"); + " {kGlobalRef, OK_CODE, NULL, NULL, NULL},\n" + " {kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL},\n" + " {kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL}};"); verifyFormat( "CGRect cg_rect = { { rect.fLeft, rect.fTop },\n" " { rect.fRight - rect.fLeft, rect.fBottom - rect.fTop" @@ -1659,11 +1658,11 @@ TEST_F(FormatTest, NestedStaticInitializers) { " 333333333333333333333333333333 } },\n" " { { 1, 2, 3 } }, { { 1, 2, 3 } } };"); verifyGoogleFormat( - "SomeArrayOfSomeType a = {{{1, 2, 3}}, {{1, 2, 3}},\n" - " {{111111111111111111111111111111,\n" - " 222222222222222222222222222222,\n" - " 333333333333333333333333333333}},\n" - " {{1, 2, 3}}, {{1, 2, 3}}};"); + "SomeArrayOfSomeType a = {\n" + " {{1, 2, 3}}, {{1, 2, 3}},\n" + " {{111111111111111111111111111111, 222222222222222222222222222222,\n" + " 333333333333333333333333333333}},\n" + " {{1, 2, 3}}, {{1, 2, 3}}};"); // FIXME: We might at some point want to handle this similar to parameter // lists, where we have an option to put each on a single line. @@ -3902,7 +3901,7 @@ TEST_F(FormatTest, LayoutCxx11ConstructorBraceInitializers) { " });"); FormatStyle NoSpaces = getLLVMStyle(); - NoSpaces.SpacesInBracedLists = false; + NoSpaces.Cpp11BracedListStyle = true; verifyFormat("vector x{1, 2, 3, 4};", NoSpaces); verifyFormat("vector x{{}, {}, {}, {}};", NoSpaces); verifyFormat("f({1, 2});", NoSpaces); @@ -5307,7 +5306,7 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE_BOOL(IndentCaseLabels); CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList); CHECK_PARSE_BOOL(PointerBindsToType); - CHECK_PARSE_BOOL(SpacesInBracedLists); + CHECK_PARSE_BOOL(Cpp11BracedListStyle); CHECK_PARSE_BOOL(UseTab); CHECK_PARSE_BOOL(IndentFunctionDeclarationAfterType);