forked from OSchip/llvm-project
clang-format: Fix C99 designated initializers corner cases
Summary: This fixes the missing space before the designated initializer when `Cpp11BracedListStyle=false` : const struct A a = { .a = 1, .b = 2 }; ^ Also, wrapping between opening brace and designated array initializers used to have an excessive penalty (like breaking between an expression and the subscript operator), leading to unexpected wrapping: const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = {[1] = aaaaaaaaaaaaaaaaaaaaaaaaaaa, [2] = bbbbbbbbbbbbbbbbbbbbbbbbbbb}; instead of: const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = { [1] = aaaaaaaaaaaaaaaaaaaaaaaaaaa, [2] = bbbbbbbbbbbbbbbbbbbbbbbbbbb}; Finally, designated array initializers are not binpacked, just like designated member initializers. Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits, krasimir, klimek Differential Revision: https://reviews.llvm.org/D33491 llvm-svn: 305696
This commit is contained in:
parent
4f1e047a6d
commit
5f07f443be
|
@ -1050,7 +1050,9 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
|
|||
(Current.is(TT_ArrayInitializerLSquare) && EndsInComma) ||
|
||||
Current.is(TT_DictLiteral) ||
|
||||
Style.Language == FormatStyle::LK_Proto || !Style.BinPackArguments ||
|
||||
(NextNoComment && NextNoComment->is(TT_DesignatedInitializerPeriod));
|
||||
(NextNoComment &&
|
||||
NextNoComment->isOneOf(TT_DesignatedInitializerPeriod,
|
||||
TT_DesignatedInitializerLSquare));
|
||||
if (Current.ParameterCount > 1)
|
||||
NestedBlockIndent = std::max(NestedBlockIndent, State.Column + 1);
|
||||
} else {
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace format {
|
|||
TYPE(ConflictStart) \
|
||||
TYPE(CtorInitializerColon) \
|
||||
TYPE(CtorInitializerComma) \
|
||||
TYPE(DesignatedInitializerLSquare) \
|
||||
TYPE(DesignatedInitializerPeriod) \
|
||||
TYPE(DictLiteral) \
|
||||
TYPE(ForEachMacro) \
|
||||
|
|
|
@ -340,6 +340,9 @@ private:
|
|||
Contexts.back().ContextKind == tok::l_brace &&
|
||||
Parent->isOneOf(tok::l_brace, tok::comma)) {
|
||||
Left->Type = TT_JsComputedPropertyName;
|
||||
} else if (Style.isCpp() && Contexts.back().ContextKind == tok::l_brace &&
|
||||
Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
|
||||
Left->Type = TT_DesignatedInitializerLSquare;
|
||||
} else if (CurrentToken->is(tok::r_square) && Parent &&
|
||||
Parent->is(TT_TemplateCloser)) {
|
||||
Left->Type = TT_ArraySubscriptLSquare;
|
||||
|
@ -392,7 +395,8 @@ private:
|
|||
if (CurrentToken->isOneOf(tok::r_paren, tok::r_brace))
|
||||
return false;
|
||||
if (CurrentToken->is(tok::colon)) {
|
||||
if (Left->is(TT_ArraySubscriptLSquare)) {
|
||||
if (Left->isOneOf(TT_ArraySubscriptLSquare,
|
||||
TT_DesignatedInitializerLSquare)) {
|
||||
Left->Type = TT_ObjCMethodExpr;
|
||||
StartsObjCMethodExpr = true;
|
||||
Contexts.back().ColonIsObjCMethodExpr = true;
|
||||
|
@ -1975,7 +1979,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
|
|||
if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
|
||||
return 35;
|
||||
if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
|
||||
TT_ArrayInitializerLSquare))
|
||||
TT_ArrayInitializerLSquare,
|
||||
TT_DesignatedInitializerLSquare))
|
||||
return 500;
|
||||
}
|
||||
|
||||
|
@ -2196,7 +2201,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
|
|||
(Style.SpacesInSquareBrackets &&
|
||||
Right.MatchingParen->is(TT_ArraySubscriptLSquare)));
|
||||
if (Right.is(tok::l_square) &&
|
||||
!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare) &&
|
||||
!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
|
||||
TT_DesignatedInitializerLSquare) &&
|
||||
!Left.isOneOf(tok::numeric_constant, TT_DictLiteral))
|
||||
return false;
|
||||
if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
|
||||
|
@ -2396,8 +2402,9 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
|
|||
if (Left.is(tok::greater) && Right.is(tok::greater))
|
||||
return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
|
||||
(Style.Standard != FormatStyle::LS_Cpp11 || Style.SpacesInAngles);
|
||||
if (Right.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
|
||||
Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar))
|
||||
if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
|
||||
Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
|
||||
(Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod)))
|
||||
return false;
|
||||
if (!Style.SpaceBeforeAssignmentOperators &&
|
||||
Right.getPrecedence() == prec::Assignment)
|
||||
|
|
|
@ -1704,6 +1704,19 @@ TEST_F(FormatTest, DesignatedInitializers) {
|
|||
" .eeeeeeeeeeeeeeeeeeeeeeeeeee = 5};");
|
||||
|
||||
verifyGoogleFormat("const struct A a = {.a = 1, .b = 2};");
|
||||
|
||||
verifyFormat("const struct A a = {[0] = 1, [1] = 2};");
|
||||
verifyFormat("const struct A a = {[1] = aaaaaaaaaa,\n"
|
||||
" [2] = bbbbbbbbbb,\n"
|
||||
" [3] = cccccccccc,\n"
|
||||
" [4] = dddddddddd,\n"
|
||||
" [5] = eeeeeeeeee};");
|
||||
verifyFormat("const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = {\n"
|
||||
" [1] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
|
||||
" [2] = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
|
||||
" [3] = cccccccccccccccccccccccccccccccccccccc,\n"
|
||||
" [4] = dddddddddddddddddddddddddddddddddddddd,\n"
|
||||
" [5] = eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee};");
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, NestedStaticInitializers) {
|
||||
|
@ -6010,6 +6023,8 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
|
|||
" T member = {arg1, arg2};\n"
|
||||
"};");
|
||||
verifyFormat("vector<int> foo = {::SomeGlobalFunction()};");
|
||||
verifyFormat("const struct A a = {.a = 1, .b = 2};");
|
||||
verifyFormat("const struct A a = {[0] = 1, [1] = 2};");
|
||||
verifyFormat("static_assert(std::is_integral<int>{} + 0, \"\");");
|
||||
verifyFormat("int a = std::is_integral<int>{} + 0;");
|
||||
|
||||
|
@ -6175,6 +6190,8 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
|
|||
" aaaaaaa,\n"
|
||||
" a};");
|
||||
verifyFormat("vector<int> foo = { ::SomeGlobalFunction() };", ExtraSpaces);
|
||||
verifyFormat("const struct A a = { .a = 1, .b = 2 };", ExtraSpaces);
|
||||
verifyFormat("const struct A a = { [0] = 1, [1] = 2 };", ExtraSpaces);
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, FormatsBracedListsInColumnLayout) {
|
||||
|
|
Loading…
Reference in New Issue