Index: clang/lib/Format/UnwrappedLineParser.h =================================================================== --- clang/lib/Format/UnwrappedLineParser.h +++ clang/lib/Format/UnwrappedLineParser.h @@ -92,16 +92,18 @@ void reset(); void parseFile(); bool precededByCommentOrPPDirective() const; - bool parseLevel(const FormatToken *OpeningBrace, bool CanContainBracedList, - IfStmtKind *IfKind = nullptr, - TokenType NextLBracesType = TT_Unknown); + void parseLevel(const FormatToken *OpeningBrace = nullptr, + bool CanContainBracedList = true, + TokenType NextLBracesType = TT_Unknown, + IfStmtKind *IfKind = nullptr, bool *SimpleBlock = nullptr); bool mightFitOnOneLine(UnwrappedLine &Line, const FormatToken *OpeningBrace = nullptr) const; - IfStmtKind parseBlock(bool MustBeDeclaration = false, unsigned AddLevels = 1u, - bool MunchSemi = true, bool KeepBraces = true, - bool UnindentWhitesmithsBraces = false, - bool CanContainBracedList = true, - TokenType NextLBracesType = TT_Unknown); + void parseBlock(bool MustBeDeclaration = false, unsigned AddLevels = 1u, + bool MunchSemi = true, bool KeepBraces = true, + IfStmtKind *IfKind = nullptr, + bool UnindentWhitesmithsBraces = false, + bool CanContainBracedList = true, + TokenType NextLBracesType = TT_Unknown); void parseChildBlock(bool CanContainBracedList = true, TokenType NextLBracesType = TT_Unknown); void parsePPDirective(); @@ -112,8 +114,8 @@ void parsePPEndIf(); void parsePPUnknown(); void readTokenWithJavaScriptASI(); - void parseStructuralElement(IfStmtKind *IfKind = nullptr, - bool IsTopLevel = false, + void parseStructuralElement(bool IsTopLevel = false); + void parseStructuralElement(IfStmtKind *IfKind, bool IsTopLevel = false, TokenType NextLBracesType = TT_Unknown, bool *HasDoWhile = nullptr, bool *HasLabel = nullptr); Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -395,7 +395,7 @@ if (Style.Language == FormatStyle::LK_TextProto) parseBracedList(); else - parseLevel(/*OpeningBrace=*/nullptr, /*CanContainBracedList=*/true); + parseLevel(); // Make sure to format the remaining tokens. // // LK_TextProto is special since its top-level is parsed as the body of a @@ -469,21 +469,26 @@ /// \param CanContainBracedList If the content can contain (at any level) a /// braced list. /// \param NextLBracesType The type for left brace found in this level. -/// \returns true if a simple block of if/else/for/while, or false otherwise. +/// \param IfKind The if statement kind in the level. +/// \param SimpleBlock Whether the level is a simple block of if/else/for/while. /// (A simple block has a single statement.) -bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace, +void UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace, bool CanContainBracedList, - IfStmtKind *IfKind, - TokenType NextLBracesType) { + TokenType NextLBracesType, + IfStmtKind *IfKind, bool *SimpleBlock) { + if (SimpleBlock) + *SimpleBlock = false; + auto NextLevelLBracesType = NextLBracesType == TT_CompoundRequirementLBrace ? TT_BracedListLBrace : TT_Unknown; const bool IsPrecededByCommentOrPPDirective = - !Style.RemoveBracesLLVM || precededByCommentOrPPDirective(); + !SimpleBlock || precededByCommentOrPPDirective(); bool HasDoWhile = false; bool HasLabel = false; unsigned StatementCount = 0; bool SwitchLabelEncountered = false; + do { if (FormatTok->getType() == TT_AttributeMacro) { nextToken(); @@ -524,7 +529,7 @@ continue; } parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u, - /*MunchSemi=*/true, /*KeepBraces=*/true, + /*MunchSemi=*/true, /*KeepBraces=*/true, /*IfKind=*/nullptr, /*UnindentWhitesmithsBraces=*/false, CanContainBracedList, NextLBracesType); ++StatementCount; @@ -533,17 +538,19 @@ break; case tok::r_brace: if (OpeningBrace) { - if (!Style.RemoveBracesLLVM || + if (!SimpleBlock || !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) { - return false; + return; } if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || HasLabel || HasDoWhile || IsPrecededByCommentOrPPDirective || precededByCommentOrPPDirective()) { - return false; + return; } const FormatToken *Next = Tokens->peekNextToken(); - return Next->isNot(tok::comment) || Next->NewlinesBefore > 0; + if (Next->isNot(tok::comment) || Next->NewlinesBefore > 0) + *SimpleBlock = true; + return; } nextToken(); addUnwrappedLine(); @@ -593,7 +600,6 @@ break; } } while (!eof()); - return false; } void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { @@ -815,10 +821,12 @@ return Line.Level * Style.IndentWidth + Length <= ColumnLimit; } -UnwrappedLineParser::IfStmtKind UnwrappedLineParser::parseBlock( - bool MustBeDeclaration, unsigned AddLevels, bool MunchSemi, bool KeepBraces, - bool UnindentWhitesmithsBraces, bool CanContainBracedList, - TokenType NextLBracesType) { +void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels, + bool MunchSemi, bool KeepBraces, + IfStmtKind *IfKind, + bool UnindentWhitesmithsBraces, + bool CanContainBracedList, + TokenType NextLBracesType) { assert(FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) && "'{' or macro block token expected"); FormatToken *Tok = FormatTok; @@ -859,18 +867,18 @@ if (AddLevels > 0u && Style.BreakBeforeBraces != FormatStyle::BS_Whitesmiths) Line->Level += AddLevels; - IfStmtKind IfKind = IfStmtKind::NotIf; - const bool SimpleBlock = - parseLevel(Tok, CanContainBracedList, &IfKind, NextLBracesType); + bool SimpleBlock; + parseLevel(Tok, CanContainBracedList, NextLBracesType, IfKind, + Style.RemoveBracesLLVM ? &SimpleBlock : nullptr); if (eof()) - return IfKind; + return; if (MacroBlock ? !FormatTok->is(TT_MacroBlockEnd) : !FormatTok->is(tok::r_brace)) { Line->Level = InitialLevel; FormatTok->setBlockKind(BK_Block); - return IfKind; + return; } auto RemoveBraces = [=]() mutable { @@ -935,8 +943,6 @@ CurrentLines->size() - 1; } } - - return IfKind; } static bool isGoogScope(const UnwrappedLine &Line) { @@ -1010,8 +1016,7 @@ ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, /*MustBeDeclaration=*/false); Line->Level += SkipIndent ? 0 : 1; - parseLevel(OpeningBrace, CanContainBracedList, /*IfKind=*/nullptr, - NextLBracesType); + parseLevel(OpeningBrace, CanContainBracedList, NextLBracesType); flushComments(isOnNewLine(*FormatTok)); Line->Level -= SkipIndent ? 0 : 1; } @@ -1414,6 +1419,10 @@ } } +void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) { + parseStructuralElement(/*IfKind=*/nullptr, IsTopLevel); +} + void UnwrappedLineParser::parseStructuralElement(IfStmtKind *IfKind, bool IsTopLevel, TokenType NextLBracesType, @@ -2562,8 +2571,8 @@ FormatTok->setFinalizedType(TT_ControlStatementLBrace); IfLeftBrace = FormatTok; CompoundStatementIndenter Indenter(this, Style, Line->Level); - IfBlockKind = parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u, - /*MunchSemi=*/true, KeepIfBraces); + parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u, + /*MunchSemi=*/true, KeepIfBraces, &IfBlockKind); if (Style.BraceWrapping.BeforeElse) addUnwrappedLine(); else @@ -2595,9 +2604,9 @@ FormatTok->setFinalizedType(TT_ElseLBrace); ElseLeftBrace = FormatTok; CompoundStatementIndenter Indenter(this, Style, Line->Level); - const IfStmtKind ElseBlockKind = - parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u, - /*MunchSemi=*/true, KeepElseBraces); + IfStmtKind ElseBlockKind; + parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u, + /*MunchSemi=*/true, KeepElseBraces, &ElseBlockKind); if ((ElseBlockKind == IfStmtKind::IfOnly || ElseBlockKind == IfStmtKind::IfElseIf) && FormatTok->is(tok::kw_else)) { @@ -2796,7 +2805,8 @@ ++Line->Level; parseBlock(/*MustBeDeclaration=*/true, AddLevels, /*MunchSemi=*/true, - /*KeepBraces=*/true, ManageWhitesmithsBraces); + /*KeepBraces=*/true, /*IfKind=*/nullptr, + ManageWhitesmithsBraces); // Munch the semicolon after a namespace. This is more common than one would // think. Putting the semicolon into its own line is very ugly. @@ -3611,7 +3621,7 @@ } // Parse the class body after the enum's ";" if any. - parseLevel(OpeningBrace, /*CanContainBracedList=*/true); + parseLevel(OpeningBrace); nextToken(); --Line->Level; addUnwrappedLine();