aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format/TokenAnnotator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format/TokenAnnotator.cpp')
-rwxr-xr-x[-rw-r--r--]clang/lib/Format/TokenAnnotator.cpp263
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;