diff options
Diffstat (limited to 'clang/lib/Format/TokenAnnotator.cpp')
-rwxr-xr-x[-rw-r--r--] | clang/lib/Format/TokenAnnotator.cpp | 263 |
1 files changed, 185 insertions, 78 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7f8e35126512..34c291ecc492 100644..100755 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -27,7 +27,7 @@ namespace format { namespace { /// Returns \c true if the token can be used as an identifier in -/// an Objective-C \c @selector, \c false otherwise. +/// an Objective-C \c \@selector, \c false otherwise. /// /// Because getFormattingLangOpts() always lexes source code as /// Objective-C++, C++ keywords like \c new and \c delete are @@ -56,6 +56,13 @@ static bool isLambdaParameterList(const FormatToken *Left) { Left->Previous->MatchingParen->is(TT_LambdaLSquare); } +/// Returns \c true if the token is followed by a boolean condition, \c false +/// otherwise. +static bool isKeywordWithCondition(const FormatToken &Tok) { + return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch, + tok::kw_constexpr, tok::kw_catch); +} + /// A parser that gathers additional information about tokens. /// /// The \c TokenAnnotator tries to match parenthesis and square brakets and @@ -108,6 +115,12 @@ private: while (CurrentToken) { if (CurrentToken->is(tok::greater)) { + // Try to do a better job at looking for ">>" within the condition of + // a statement. + if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) && + Left->ParentBracket != tok::less && + isKeywordWithCondition(*Line.First)) + return false; Left->MatchingParen = CurrentToken; CurrentToken->MatchingParen = Left; // In TT_Proto, we must distignuish between: @@ -185,6 +198,8 @@ private: if (!CurrentToken) return false; FormatToken *Left = CurrentToken->Previous; + assert(Left && "Unknown previous token"); + FormatToken *PrevNonComment = Left->getPreviousNonComment(); Left->ParentBracket = Contexts.back().ContextKind; ScopedContextCreator ContextCreator(*this, tok::l_paren, 1); @@ -216,9 +231,8 @@ private: // export type X = (...); Contexts.back().IsExpression = false; } else if (Left->Previous && - (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype, - tok::kw_while, tok::l_paren, - tok::comma) || + (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_while, + tok::l_paren, tok::comma) || Left->Previous->isIf() || Left->Previous->is(TT_BinaryOperator))) { // static_assert, if and while usually contain expressions. @@ -242,8 +256,6 @@ private: } else if (Contexts[Contexts.size() - 2].CaretFound) { // This is the parameter list of an ObjC block. Contexts.back().IsExpression = false; - } else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) { - Left->setType(TT_AttributeParen); } else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) { // The first argument to a foreach macro is a declaration. Contexts.back().IsForEachMacro = true; @@ -257,6 +269,21 @@ private: Contexts.back().IsExpression = !IsForOrCatch; } + // Infer the role of the l_paren based on the previous token if we haven't + // detected one one yet. + if (PrevNonComment && Left->is(TT_Unknown)) { + if (PrevNonComment->is(tok::kw___attribute)) { + Left->setType(TT_AttributeParen); + } else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype, + tok::kw_typeof, tok::kw__Atomic, + tok::kw___underlying_type)) { + Left->setType(TT_TypeDeclarationParen); + // decltype() and typeof() usually contain expressions. + if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof)) + Contexts.back().IsExpression = true; + } + } + if (StartsObjCMethodExpr) { Contexts.back().ColonIsObjCMethodExpr = true; Left->setType(TT_ObjCMethodExpr); @@ -335,6 +362,8 @@ private: if (Left->is(TT_AttributeParen)) CurrentToken->setType(TT_AttributeParen); + if (Left->is(TT_TypeDeclarationParen)) + CurrentToken->setType(TT_TypeDeclarationParen); if (Left->Previous && Left->Previous->is(TT_JavaAnnotation)) CurrentToken->setType(TT_JavaAnnotation); if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation)) @@ -343,11 +372,11 @@ private: CurrentToken->setType(TT_AttributeSquare); if (!HasMultipleLines) - Left->PackingKind = PPK_Inconclusive; + Left->setPackingKind(PPK_Inconclusive); else if (HasMultipleParametersOnALine) - Left->PackingKind = PPK_BinPacked; + Left->setPackingKind(PPK_BinPacked); else - Left->PackingKind = PPK_OnePerLine; + Left->setPackingKind(PPK_OnePerLine); next(); return true; @@ -704,7 +733,7 @@ private: ScopedContextCreator ContextCreator(*this, tok::l_brace, 1); Contexts.back().ColonIsDictLiteral = true; - if (Left->BlockKind == BK_BracedInit) + if (Left->is(BK_BracedInit)) Contexts.back().IsExpression = true; if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous && Left->Previous->is(TT_JsTypeColon)) @@ -751,7 +780,7 @@ private: // For ObjC methods, the number of parameters is calculated differently as // method declarations have a different structure (the parameters are not // inside a bracket scope). - if (Current->is(tok::l_brace) && Current->BlockKind == BK_Block) + if (Current->is(tok::l_brace) && Current->is(BK_Block)) ++Left->BlockParameterCount; if (Current->is(tok::comma)) { ++Left->ParameterCount; @@ -867,7 +896,8 @@ private: } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) { Tok->setType(TT_BitFieldColon); } else if (Contexts.size() == 1 && - !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) { + !Line.First->isOneOf(tok::kw_enum, tok::kw_case, + tok::kw_default)) { FormatToken *Prev = Tok->getPreviousNonComment(); if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept)) Tok->setType(TT_CtorInitializerColon); @@ -940,9 +970,9 @@ private: return false; if (Line.MustBeDeclaration && Contexts.size() == 1 && !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) && - (!Tok->Previous || - !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute, - TT_LeadingJavaAnnotation))) + !Tok->is(TT_TypeDeclarationParen) && + (!Tok->Previous || !Tok->Previous->isOneOf(tok::kw___attribute, + TT_LeadingJavaAnnotation))) Line.MightBeFunctionDecl = true; break; case tok::l_square: @@ -1333,11 +1363,13 @@ private: // Reset token type in case we have already looked at it and then // recovered from an error (e.g. failure to find the matching >). if (!CurrentToken->isOneOf( - TT_LambdaLSquare, TT_LambdaLBrace, TT_ForEachMacro, - TT_TypenameMacro, TT_FunctionLBrace, TT_ImplicitStringLiteral, - TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow, TT_NamespaceMacro, - TT_OverloadedOperator, TT_RegexLiteral, TT_TemplateString, - TT_ObjCStringLiteral, TT_UntouchableMacroFunc)) + TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, + TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace, + TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_JsFatArrow, + TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator, + TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral, + TT_UntouchableMacroFunc, TT_ConstraintJunctions, + TT_StatementAttributeLikeMacro)) CurrentToken->setType(TT_Unknown); CurrentToken->Role.reset(); CurrentToken->MatchingParen = nullptr; @@ -1591,7 +1623,11 @@ private: !Current.Previous->is(tok::kw_operator)) { // not auto operator->() -> xxx; Current.setType(TT_TrailingReturnArrow); - + } else if (Current.is(tok::arrow) && Current.Previous && + Current.Previous->is(tok::r_brace)) { + // Concept implicit conversion contraint needs to be treated like + // a trailing return type ... } -> <type>. + Current.setType(TT_TrailingReturnArrow); } else if (isDeductionGuide(Current)) { // Deduction guides trailing arrow " A(...) -> A<T>;". Current.setType(TT_TrailingReturnArrow); @@ -1692,8 +1728,8 @@ private: // colon after this, this is the only place which annotates the identifier // as a selector.) Current.setType(TT_SelectorName); - } else if (Current.isOneOf(tok::identifier, tok::kw_const, - tok::kw_noexcept) && + } else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept, + tok::kw_requires) && Current.Previous && !Current.Previous->isOneOf(tok::equal, tok::at) && Line.MightBeFunctionDecl && Contexts.size() == 1) { @@ -1753,9 +1789,8 @@ private: PreviousNotConst->MatchingParen->Previous->isNot(tok::period) && PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template); - if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen && - PreviousNotConst->MatchingParen->Previous && - PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype)) + if (PreviousNotConst->is(tok::r_paren) && + PreviousNotConst->is(TT_TypeDeclarationParen)) return true; return (!IsPPKeyword && @@ -1810,8 +1845,8 @@ private: // Functions which end with decorations like volatile, noexcept are unlikely // to be casts. if (Tok.Next->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const, - tok::kw_throw, tok::arrow, Keywords.kw_override, - Keywords.kw_final) || + tok::kw_requires, tok::kw_throw, tok::arrow, + Keywords.kw_override, Keywords.kw_final) || isCpp11AttributeSpecifier(*Tok.Next)) return false; @@ -1827,10 +1862,38 @@ private: return true; // Heuristically try to determine whether the parentheses contain a type. + auto IsQualifiedPointerOrReference = [](FormatToken *T) { + // This is used to handle cases such as x = (foo *const)&y; + assert(!T->isSimpleTypeSpecifier() && "Should have already been checked"); + // Strip trailing qualifiers such as const or volatile when checking + // whether the parens could be a cast to a pointer/reference type. + while (T) { + if (T->is(TT_AttributeParen)) { + // Handle `x = (foo *__attribute__((foo)))&v;`: + if (T->MatchingParen && T->MatchingParen->Previous && + T->MatchingParen->Previous->is(tok::kw___attribute)) { + T = T->MatchingParen->Previous->Previous; + continue; + } + } else if (T->is(TT_AttributeSquare)) { + // Handle `x = (foo *[[clang::foo]])&v;`: + if (T->MatchingParen && T->MatchingParen->Previous) { + T = T->MatchingParen->Previous; + continue; + } + } else if (T->canBePointerOrReferenceQualifier()) { + T = T->Previous; + continue; + } + break; + } + return T && T->is(TT_PointerOrReference); + }; bool ParensAreType = !Tok.Previous || - Tok.Previous->isOneOf(TT_PointerOrReference, TT_TemplateCloser) || - Tok.Previous->isSimpleTypeSpecifier(); + Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) || + Tok.Previous->isSimpleTypeSpecifier() || + IsQualifiedPointerOrReference(Tok.Previous); bool ParensCouldEndDecl = Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater); if (ParensAreType && !ParensCouldEndDecl) @@ -1854,6 +1917,13 @@ private: if (Tok.Next->isOneOf(tok::identifier, tok::kw_this)) return true; + if (Tok.Next->is(tok::l_paren) && + !(Tok.Previous && Tok.Previous->is(tok::identifier) && + Tok.Previous->Previous && + Tok.Previous->Previous->isOneOf(tok::arrowstar, tok::arrow, + tok::star))) + return true; + if (!Tok.Next->Next) return false; @@ -1890,18 +1960,22 @@ private: const FormatToken *NextToken = Tok.getNextNonComment(); if (!NextToken || - NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const, - tok::kw_noexcept) || + NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_noexcept) || + NextToken->canBePointerOrReferenceQualifier() || (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) return TT_PointerOrReference; if (PrevToken->is(tok::coloncolon)) return TT_PointerOrReference; + if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen)) + return TT_PointerOrReference; + if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace, tok::comma, tok::semi, tok::kw_return, tok::colon, - tok::equal, tok::kw_delete, tok::kw_sizeof, - tok::kw_throw) || + tok::kw_co_return, tok::kw_co_await, + tok::kw_co_yield, tok::equal, tok::kw_delete, + tok::kw_sizeof, tok::kw_throw) || PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr, TT_UnaryOperator, TT_CastRParen)) return TT_UnaryOperator; @@ -1913,15 +1987,6 @@ private: if (NextToken->isOneOf(tok::comma, tok::semi)) return TT_PointerOrReference; - if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen) { - FormatToken *TokenBeforeMatchingParen = - PrevToken->MatchingParen->getPreviousNonComment(); - if (TokenBeforeMatchingParen && - TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype, - TT_TypenameMacro)) - return TT_PointerOrReference; - } - if (PrevToken->Tok.isLiteral() || PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true, tok::kw_false, tok::r_brace) || @@ -2367,6 +2432,8 @@ static bool isFunctionDeclarationName(const FormatToken &Current, return true; for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen; Tok = Tok->Next) { + if (Tok->is(TT_TypeDeclarationParen)) + return true; if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) { Tok = Tok->MatchingParen; continue; @@ -2420,7 +2487,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) { if (isFunctionDeclarationName(*Current, Line)) Current->setType(TT_FunctionDeclarationName); if (Current->is(TT_LineComment)) { - if (Current->Previous->BlockKind == BK_BracedInit && + if (Current->Previous->is(BK_BracedInit) && Current->Previous->opensScope()) Current->SpacesRequiredBefore = (Style.Cpp11BracedListStyle && !Style.SpacesInParentheses) ? 0 : 1; @@ -2681,7 +2748,11 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, if (Left.is(TT_TemplateOpener)) return 100; if (Left.opensScope()) { - if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign) + // If we aren't aligning after opening parens/braces we can always break + // here unless the style does not want us to place all arguments on the + // next line. + if (Style.AlignAfterOpenBracket == FormatStyle::BAS_DontAlign && + (Left.ParameterCount <= 1 || Style.AllowAllArgumentsOnNextLine)) return 0; if (Left.is(tok::l_brace) && !Style.Cpp11BracedListStyle) return 19; @@ -2733,13 +2804,6 @@ bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const { Right.ParameterCount > 0); } -/// Returns \c true if the token is followed by a boolean condition, \c false -/// otherwise. -static bool isKeywordWithCondition(const FormatToken &Tok) { - return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch, - tok::kw_constexpr, tok::kw_catch); -} - bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left, const FormatToken &Right) { @@ -2755,8 +2819,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Left.isOneOf(tok::hashhash, tok::hash)) return Right.is(tok::hash); if ((Left.is(tok::l_paren) && Right.is(tok::r_paren)) || - (Left.is(tok::l_brace) && Left.BlockKind != BK_Block && - Right.is(tok::r_brace) && Right.BlockKind != BK_Block)) + (Left.is(tok::l_brace) && Left.isNot(BK_Block) && + Right.is(tok::r_brace) && Right.isNot(BK_Block))) return Style.SpaceInEmptyParentheses; if (Style.SpacesInConditionalStatement) { if (Left.is(tok::l_paren) && Left.Previous && @@ -2767,6 +2831,14 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, isKeywordWithCondition(*Right.MatchingParen->Previous)) return true; } + + // requires ( or requires( + if (Right.is(tok::l_paren) && Left.is(tok::kw_requires)) + return spaceRequiredBeforeParens(Right); + // requires clause Concept1<T> && Concept2<T> + if (Left.is(TT_ConstraintJunctions) && Right.is(tok::identifier)) + return true; + if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) return (Right.is(TT_CastRParen) || (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen))) @@ -2815,11 +2887,16 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return true; FormatToken *TokenBeforeMatchingParen = Left.MatchingParen->getPreviousNonComment(); - if (!TokenBeforeMatchingParen || - !TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype, - TT_TypenameMacro)) + if (!TokenBeforeMatchingParen || !Left.is(TT_TypeDeclarationParen)) return true; } + // Add a space if the previous token is a pointer qualifer or the closing + // parenthesis of __attribute__(()) expression and the style requires spaces + // after pointer qualifiers. + if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_After || + Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) && + (Left.is(TT_AttributeParen) || Left.canBePointerOrReferenceQualifier())) + return true; return (Left.Tok.isLiteral() || (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) && (Style.PointerAlignment != FormatStyle::PAS_Left || @@ -2832,11 +2909,17 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, (Style.PointerAlignment != FormatStyle::PAS_Right && !Line.IsMultiVariableDeclStmt))) return true; - if (Left.is(TT_PointerOrReference)) + if (Left.is(TT_PointerOrReference)) { + // Add a space if the next token is a pointer qualifer and the style + // requires spaces before pointer qualifiers. + if ((Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Before || + Style.SpaceAroundPointerQualifiers == FormatStyle::SAPQ_Both) && + Right.canBePointerOrReferenceQualifier()) + return true; return Right.Tok.isLiteral() || Right.is(TT_BlockComment) || (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) && !Right.is(TT_StartOfName)) || - (Right.is(tok::l_brace) && Right.BlockKind == BK_Block) || + (Right.is(tok::l_brace) && Right.is(BK_Block)) || (!Right.isOneOf(TT_PointerOrReference, TT_ArraySubscriptLSquare, tok::l_paren) && (Style.PointerAlignment != FormatStyle::PAS_Right && @@ -2844,6 +2927,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, Left.Previous && !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon, tok::l_square)); + } // Ensure right pointer alignement with ellipsis e.g. int *...P if (Left.is(tok::ellipsis) && Left.Previous && Left.Previous->isOneOf(tok::star, tok::amp, tok::ampamp)) @@ -2921,9 +3005,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, return false; if (Left.is(tok::l_brace) && Right.is(tok::r_brace)) return !Left.Children.empty(); // No spaces in "{}". - if ((Left.is(tok::l_brace) && Left.BlockKind != BK_Block) || + if ((Left.is(tok::l_brace) && Left.isNot(BK_Block)) || (Right.is(tok::r_brace) && Right.MatchingParen && - Right.MatchingParen->BlockKind != BK_Block)) + Right.MatchingParen->isNot(BK_Block))) return Style.Cpp11BracedListStyle ? Style.SpacesInParentheses : true; if (Left.is(TT_BlockComment)) // No whitespace in x(/*foo=*/1), except for JavaScript. @@ -2967,7 +3051,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, tok::r_paren) || Left.isSimpleTypeSpecifier()) && Right.is(tok::l_brace) && Right.getNextNonComment() && - Right.BlockKind != BK_Block) + Right.isNot(BK_Block)) return false; if (Left.is(tok::period) || Right.is(tok::period)) return false; @@ -3009,7 +3093,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Style.isCpp()) { if (Left.is(tok::kw_operator)) return Right.is(tok::coloncolon); - if (Right.is(tok::l_brace) && Right.BlockKind == BK_BracedInit && + if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) && !Left.opensScope() && Style.SpaceBeforeCpp11BracedList) return true; } else if (Style.Language == FormatStyle::LK_Proto || @@ -3115,6 +3199,16 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, Keywords.kw_lock)) return Style.SpaceBeforeParens == FormatStyle::SBPO_ControlStatements || spaceRequiredBeforeParens(Right); + + // space between method modifier and opening parenthesis of a tuple return + // type + if (Left.isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected, + tok::kw_virtual, tok::kw_extern, tok::kw_static, + Keywords.kw_internal, Keywords.kw_abstract, + Keywords.kw_sealed, Keywords.kw_override, + Keywords.kw_async, Keywords.kw_unsafe) && + Right.is(tok::l_paren)) + return true; } else if (Style.Language == FormatStyle::LK_JavaScript) { if (Left.is(TT_JsFatArrow)) return true; @@ -3251,9 +3345,13 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Right.is(TT_RangeBasedForLoopColon) && !Style.SpaceBeforeRangeBasedForLoopColon) return false; + if (Left.is(TT_BitFieldColon)) + return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both || + Style.BitFieldColonSpacing == FormatStyle::BFCS_After; if (Right.is(tok::colon)) { - if (Line.First->isOneOf(tok::kw_case, tok::kw_default) || - !Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi)) + if (Line.First->isOneOf(tok::kw_default, tok::kw_case)) + return Style.SpaceBeforeCaseColon; + if (!Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi)) return false; if (Right.is(TT_ObjCMethodExpr)) return false; @@ -3267,6 +3365,9 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, return false; if (Right.is(TT_CSharpNamedArgumentColon)) return false; + if (Right.is(TT_BitFieldColon)) + return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both || + Style.BitFieldColonSpacing == FormatStyle::BFCS_Before; return true; } if (Left.is(TT_UnaryOperator)) { @@ -3356,7 +3457,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, // Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style. static bool isAllmanBrace(const FormatToken &Tok) { - return Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block && + return Tok.is(tok::l_brace) && Tok.is(BK_Block) && !Tok.isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral); } @@ -3392,7 +3493,7 @@ static bool isOneChildWithoutMustBreakBefore(const FormatToken &Tok) { return true; } static bool isAllmanLambdaBrace(const FormatToken &Tok) { - return (Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block && + return (Tok.is(tok::l_brace) && Tok.is(BK_Block) && !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral)); } @@ -3492,7 +3593,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) || (Style.Language == FormatStyle::LK_JavaScript && Left.is(tok::l_paren))) && - Left.BlockKind != BK_Block && Left.MatchingParen) + Left.isNot(BK_Block) && Left.MatchingParen) BeforeClosingBrace = Left.MatchingParen->Previous; else if (Right.MatchingParen && (Right.MatchingParen->isOneOf(tok::l_brace, @@ -3506,8 +3607,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, } if (Right.is(tok::comment)) - return Left.BlockKind != BK_BracedInit && - Left.isNot(TT_CtorInitializerColon) && + return Left.isNot(BK_BracedInit) && Left.isNot(TT_CtorInitializerColon) && (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline); if (Left.isTrailingComment()) return true; @@ -3517,11 +3617,17 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, Right.Previous->is(tok::string_literal) && Right.Next->is(tok::string_literal)) return true; + // Can break after template<> declaration if (Right.Previous->ClosesTemplateDeclaration && Right.Previous->MatchingParen && - Right.Previous->MatchingParen->NestingLevel == 0 && - Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Yes) - return true; + Right.Previous->MatchingParen->NestingLevel == 0) { + // Put concepts on the next line e.g. + // template<typename T> + // concept ... + if (Right.is(tok::kw_concept)) + return Style.BreakBeforeConceptDeclarations; + return (Style.AlwaysBreakTemplateDeclarations == FormatStyle::BTDS_Yes); + } if (Right.is(TT_CtorInitializerComma) && Style.BreakConstructorInitializers == FormatStyle::BCIS_BeforeComma && !Style.ConstructorInitializerAllOnOneLineOrOnePerLine) @@ -3816,7 +3922,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, // The first comment in a braced lists is always interpreted as belonging to // the first list element. Otherwise, it should be placed outside of the // list. - return Left.BlockKind == BK_BracedInit || + return Left.is(BK_BracedInit) || (Left.is(TT_CtorInitializerColon) && Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon); if (Left.is(tok::question) && Right.is(tok::colon)) @@ -3900,7 +4006,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, if (Left.is(tok::equal) && Right.is(tok::l_brace) && !Style.Cpp11BracedListStyle) return false; - if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen)) + if (Left.is(tok::l_paren) && + Left.isOneOf(TT_AttributeParen, TT_TypeDeclarationParen)) return false; if (Left.is(tok::l_paren) && Left.Previous && (Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen))) @@ -3917,7 +4024,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, // We only break before r_brace if there was a corresponding break before // the l_brace, which is tracked by BreakBeforeClosingBrace. if (Right.is(tok::r_brace)) - return Right.MatchingParen && Right.MatchingParen->BlockKind == BK_Block; + return Right.MatchingParen && Right.MatchingParen->is(BK_Block); // Allow breaking after a trailing annotation, e.g. after a method // declaration. @@ -4002,9 +4109,9 @@ void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) { << " T=" << getTokenTypeName(Tok->getType()) << " S=" << Tok->SpacesRequiredBefore << " F=" << Tok->Finalized << " B=" << Tok->BlockParameterCount - << " BK=" << Tok->BlockKind << " P=" << Tok->SplitPenalty + << " BK=" << Tok->getBlockKind() << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName() << " L=" << Tok->TotalLength - << " PPK=" << Tok->PackingKind << " FakeLParens="; + << " PPK=" << Tok->getPackingKind() << " FakeLParens="; for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i) llvm::errs() << Tok->FakeLParens[i] << "/"; llvm::errs() << " FakeRParens=" << Tok->FakeRParens; |