From 5ad390d27f8f7cb6628bc2c32beba4d25bc2718b Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Tue, 28 May 2013 11:30:49 +0000 Subject: [PATCH] Initial support for designated initializers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182767 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/Format.cpp | 10 +++++++--- lib/Format/TokenAnnotator.cpp | 22 ++++++++++++++-------- lib/Format/TokenAnnotator.h | 1 + unittests/Format/FormatTest.cpp | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index f244792e52..acc74496eb 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -502,7 +502,8 @@ private: } else if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess != 0) { State.Column = State.Stack.back().FirstLessLess; - } else if (Current.isOneOf(tok::period, tok::arrow)) { + } else if (Current.isOneOf(tok::period, tok::arrow) && + Current.Type != TT_DesignatedInitializerPeriod) { if (State.Stack.back().CallContinuation == 0) { State.Column = ContinuationIndent; State.Stack.back().CallContinuation = State.Column; @@ -559,7 +560,8 @@ private: } State.Stack.back().LastSpace = State.Column; - if (Current.isOneOf(tok::arrow, tok::period)) + if (Current.isOneOf(tok::arrow, tok::period) && + Current.Type != TT_DesignatedInitializerPeriod) State.Stack.back().LastSpace += Current.FormatTok.TokenLength; State.StartOfLineLevel = State.ParenLevel; State.LowestLevelOnLine = State.ParenLevel; @@ -734,7 +736,9 @@ private: bool AvoidBinPacking; if (Current.is(tok::l_brace)) { NewIndent = Style.IndentWidth + LastSpace; - AvoidBinPacking = false; + const AnnotatedToken *NextNoComment = Current.getNextNoneComment(); + AvoidBinPacking = NextNoComment && + NextNoComment->Type == TT_DesignatedInitializerPeriod; } else { NewIndent = 4 + std::max(LastSpace, State.Stack.back().StartOfFunctionCall); diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 2cc4a9471e..ed39a573f6 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -685,6 +685,11 @@ private: default: break; } + } else if (Current.is(tok::period)) { + AnnotatedToken *PreviousNoComment= Current.getPreviousNoneComment(); + if (PreviousNoComment && + PreviousNoComment->isOneOf(tok::comma, tok::l_brace)) + Current.Type = TT_DesignatedInitializerPeriod; } } } @@ -963,6 +968,11 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, const AnnotatedToken &Left = *Tok.Parent; const AnnotatedToken &Right = Tok; + if (Left.is(tok::semi)) + return 0; + if (Left.is(tok::comma)) + return 1; + if (Right.Type == TT_StartOfName) { if (Line.First.is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt) return 3; @@ -983,7 +993,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, Left.Type == TT_InheritanceColon) return 2; - if (Right.isOneOf(tok::arrow, tok::period)) { + if (Right.isOneOf(tok::arrow, tok::period) && + Right.Type != TT_DesignatedInitializerPeriod) { if (Line.Type == LT_BuilderTypeCall) return prec::PointerToMember; if (Left.isOneOf(tok::r_paren, tok::r_square) && Left.MatchingParen && @@ -1000,11 +1011,6 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, if (Line.First.is(tok::kw_for) && Left.is(tok::equal)) return 4; - if (Left.is(tok::semi)) - return 0; - if (Left.is(tok::comma)) - return 1; - // In Objective-C method expressions, prefer breaking before "param:" over // breaking after it. if (Right.Type == TT_ObjCSelectorName) @@ -1087,8 +1093,6 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return Right.Type == TT_ObjCArrayLiteral; if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr) return false; - if (Left.is(tok::period) || Right.is(tok::period)) - return false; if (Left.is(tok::colon)) return Left.Type != TT_ObjCMethodExpr; if (Right.is(tok::colon)) @@ -1116,6 +1120,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return false; if (Right.is(tok::ellipsis)) return false; + if (Left.is(tok::period) || Right.is(tok::period)) + return false; return true; } diff --git a/lib/Format/TokenAnnotator.h b/lib/Format/TokenAnnotator.h index 81d660d947..37704ad6a7 100644 --- a/lib/Format/TokenAnnotator.h +++ b/lib/Format/TokenAnnotator.h @@ -33,6 +33,7 @@ enum TokenType { TT_CastRParen, TT_ConditionalExpr, TT_CtorInitializerColon, + TT_DesignatedInitializerPeriod, TT_ImplicitStringLiteral, TT_InlineASMColon, TT_InheritanceColon, diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 2af1dd75a5..3bdf59ab9e 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -1456,6 +1456,24 @@ TEST_F(FormatTest, StaticInitializers) { getLLVMStyleWithColumns(40)); } +TEST_F(FormatTest, DesignatedInitializers) { + verifyFormat("const struct A a = { .a = 1, .b = 2 };"); + verifyFormat("const struct A a = { .aaaaaaaaaa = 1,\n" + " .bbbbbbbbbb = 2,\n" + " .cccccccccc = 3,\n" + " .dddddddddd = 4,\n" + " .eeeeeeeeee = 5 };"); + verifyFormat("const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = {\n" + " .aaaaaaaaaaaaaaaaaaaaaaaaaaa = 1,\n" + " .bbbbbbbbbbbbbbbbbbbbbbbbbbb = 2,\n" + " .ccccccccccccccccccccccccccc = 3,\n" + " .ddddddddddddddddddddddddddd = 4,\n" + " .eeeeeeeeeeeeeeeeeeeeeeeeeee = 5\n" + "};"); + + verifyGoogleFormat("const struct A a = {.a = 1, .b = 2};"); +} + TEST_F(FormatTest, NestedStaticInitializers) { verifyFormat("static A x = { { {} } };\n"); verifyFormat("static A x = { { { init1, init2, init3, init4 },\n" -- 2.40.0