Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions clang/lib/Format/ContinuationIndenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
}
if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) ||
(Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) &&
State.Line->First->isNot(TT_AttributeSquare) && Style.isCpp() &&
State.Line->First->isNot(TT_AttributeLSquare) && Style.isCpp() &&
// FIXME: This is a temporary workaround for the case where clang-format
// sets BreakBeforeParameter to avoid bin packing and this creates a
// completely unnecessary line break after a template type that isn't
Expand Down Expand Up @@ -1369,7 +1369,8 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
}
if (Current.is(TT_LambdaArrow) &&
Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) {
tok::kw_consteval, tok::kw_static,
TT_AttributeRSquare)) {
return ContinuationIndent;
}
if ((Current.isOneOf(tok::r_brace, tok::r_square) ||
Expand Down Expand Up @@ -1494,9 +1495,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
Current.isNot(tok::l_paren) &&
!Current.endsSequence(TT_StartOfName, TT_AttributeMacro,
TT_PointerOrReference)) ||
PreviousNonComment->isOneOf(
TT_AttributeRParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
PreviousNonComment->isOneOf(TT_AttributeRParen, TT_AttributeRSquare,
TT_FunctionAnnotationRParen,
TT_JavaAnnotation,
TT_LeadingJavaAnnotation))) ||
(!Style.IndentWrappedFunctionNames &&
NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
return std::max(CurrentState.LastSpace, CurrentState.Indent);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Format/DefinitionBlockSeparator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ void DefinitionBlockSeparator::separateBlocks(
}
}

if (Style.isCSharp() && OperateLine->First->is(TT_AttributeSquare))
if (Style.isCSharp() && OperateLine->First->is(TT_AttributeLSquare))
return true;
return false;
};
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Format/FormatToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ namespace format {
TYPE(ArraySubscriptLSquare) \
TYPE(AttributeColon) \
TYPE(AttributeLParen) \
TYPE(AttributeLSquare) \
TYPE(AttributeMacro) \
TYPE(AttributeRParen) \
TYPE(AttributeSquare) \
TYPE(AttributeRSquare) \
TYPE(BinaryOperator) \
TYPE(BitFieldColon) \
TYPE(BlockComment) \
Expand Down
59 changes: 29 additions & 30 deletions clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,10 +531,6 @@ class AnnotatingParser {
OpeningParen.Previous->is(TT_LeadingJavaAnnotation)) {
CurrentToken->setType(TT_LeadingJavaAnnotation);
}
if (OpeningParen.Previous &&
OpeningParen.Previous->is(TT_AttributeSquare)) {
CurrentToken->setType(TT_AttributeSquare);
}

if (!HasMultipleLines)
OpeningParen.setPackingKind(PPK_Inconclusive);
Expand Down Expand Up @@ -722,9 +718,11 @@ class AnnotatingParser {
} else if (InsideInlineASM) {
Left->setType(TT_InlineASMSymbolicNameLSquare);
} else if (IsCpp11AttributeSpecifier) {
Left->setType(TT_AttributeSquare);
if (!IsInnerSquare && Left->Previous)
Left->Previous->EndsCppAttributeGroup = false;
if (!IsInnerSquare) {
Left->setType(TT_AttributeLSquare);
if (Left->Previous)
Left->Previous->EndsCppAttributeGroup = false;
}
} else if (Style.isJavaScript() && Parent &&
Contexts.back().ContextKind == tok::l_brace &&
Parent->isOneOf(tok::l_brace, tok::comma)) {
Expand All @@ -733,7 +731,7 @@ class AnnotatingParser {
Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
Left->setType(TT_DesignatedInitializerLSquare);
} else if (IsCSharpAttributeSpecifier) {
Left->setType(TT_AttributeSquare);
Left->setType(TT_AttributeLSquare);
} else if (CurrentToken->is(tok::r_square) && Parent &&
Parent->is(TT_TemplateCloser)) {
Left->setType(TT_ArraySubscriptLSquare);
Expand Down Expand Up @@ -797,13 +795,12 @@ class AnnotatingParser {

while (CurrentToken) {
if (CurrentToken->is(tok::r_square)) {
if (IsCpp11AttributeSpecifier) {
CurrentToken->setType(TT_AttributeSquare);
if (!IsInnerSquare)
CurrentToken->EndsCppAttributeGroup = true;
if (IsCpp11AttributeSpecifier && !IsInnerSquare) {
CurrentToken->setType(TT_AttributeRSquare);
CurrentToken->EndsCppAttributeGroup = true;
}
if (IsCSharpAttributeSpecifier) {
CurrentToken->setType(TT_AttributeSquare);
CurrentToken->setType(TT_AttributeRSquare);
} else if (((CurrentToken->Next &&
CurrentToken->Next->is(tok::l_paren)) ||
(CurrentToken->Previous &&
Expand Down Expand Up @@ -1297,7 +1294,7 @@ class AnnotatingParser {
bool consumeToken() {
if (IsCpp) {
const auto *Prev = CurrentToken->getPreviousNonComment();
if (Prev && Prev->is(tok::r_square) && Prev->is(TT_AttributeSquare) &&
if (Prev && Prev->is(TT_AttributeRSquare) &&
CurrentToken->isOneOf(tok::kw_if, tok::kw_switch, tok::kw_case,
tok::kw_default, tok::kw_for, tok::kw_while) &&
mustBreakAfterAttributes(*CurrentToken, Style)) {
Expand Down Expand Up @@ -2850,7 +2847,7 @@ class AnnotatingParser {
T = Tok->Previous;
continue;
}
} else if (T->is(TT_AttributeSquare)) {
} else if (T->is(TT_AttributeRSquare)) {
// Handle `x = (foo *[[clang::foo]])&v;`:
if (T->MatchingParen && T->MatchingParen->Previous) {
T = T->MatchingParen->Previous;
Expand Down Expand Up @@ -3656,7 +3653,7 @@ static FormatToken *getFunctionName(const AnnotatedLine &Line,
for (FormatToken *Tok = Line.getFirstNonComment(), *Name = nullptr; Tok;
Tok = Tok->getNextNonComment()) {
// Skip C++11 attributes both before and after the function name.
if (Tok->is(tok::l_square) && Tok->is(TT_AttributeSquare)) {
if (Tok->is(TT_AttributeLSquare)) {
Tok = Tok->MatchingParen;
if (!Tok)
break;
Expand Down Expand Up @@ -4328,7 +4325,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
return 35;
if (Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
TT_ArrayInitializerLSquare,
TT_DesignatedInitializerLSquare, TT_AttributeSquare)) {
TT_DesignatedInitializerLSquare, TT_AttributeLSquare)) {
return 500;
}
}
Expand Down Expand Up @@ -4808,7 +4805,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (Right.is(tok::l_square) &&
Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
TT_DesignatedInitializerLSquare,
TT_StructuredBindingLSquare, TT_AttributeSquare) &&
TT_StructuredBindingLSquare, TT_AttributeLSquare) &&
Left.isNoneOf(tok::numeric_constant, TT_DictLiteral) &&
!(Left.isNot(tok::r_square) && Style.SpaceBeforeSquareBrackets &&
Right.is(TT_ArraySubscriptLSquare))) {
Expand All @@ -4826,7 +4823,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,

// Space between template and attribute.
// e.g. template <typename T> [[nodiscard]] ...
if (Left.is(TT_TemplateCloser) && Right.is(TT_AttributeSquare))
if (Left.is(TT_TemplateCloser) && Right.is(TT_AttributeLSquare))
return true;
// Space before parentheses common for all languages
if (Right.is(tok::l_paren)) {
Expand All @@ -4841,10 +4838,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
return Style.SpaceBeforeParensOptions.AfterRequiresInExpression ||
spaceRequiredBeforeParens(Right);
}
if (Left.is(TT_AttributeRParen) ||
(Left.is(tok::r_square) && Left.is(TT_AttributeSquare))) {
if (Left.isOneOf(TT_AttributeRParen, TT_AttributeRSquare))
return true;
}
if (Left.is(TT_ForEachMacro)) {
return Style.SpaceBeforeParensOptions.AfterForeachMacros ||
spaceRequiredBeforeParens(Right);
Expand Down Expand Up @@ -5662,16 +5657,14 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
}

// Break after C# [...] and before public/protected/private/internal.
if (Left.is(TT_AttributeSquare) && Left.is(tok::r_square) &&
if (Left.is(TT_AttributeRSquare) &&
(Right.isAccessSpecifier(/*ColonRequired=*/false) ||
Right.is(Keywords.kw_internal))) {
return true;
}
// Break between ] and [ but only when there are really 2 attributes.
if (Left.is(TT_AttributeSquare) && Right.is(TT_AttributeSquare) &&
Left.is(tok::r_square) && Right.is(tok::l_square)) {
if (Left.is(TT_AttributeRSquare) && Right.is(TT_AttributeLSquare))
return true;
}
} else if (Style.isJavaScript()) {
// FIXME: This might apply to other languages and token kinds.
if (Right.is(tok::string_literal) && Left.is(tok::plus) && BeforeLeft &&
Expand Down Expand Up @@ -6411,8 +6404,10 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
if (Right.isAttribute())
return true;

if (Right.is(tok::l_square) && Right.is(TT_AttributeSquare))
return Left.isNot(TT_AttributeSquare);
if (Right.is(TT_AttributeLSquare)) {
assert(Left.isNot(tok::l_square));
return true;
}

if (Left.is(tok::identifier) && Right.is(tok::string_literal))
return true;
Expand Down Expand Up @@ -6453,8 +6448,12 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
Left.getPrecedence() == prec::Assignment)) {
return true;
}
if ((Left.is(TT_AttributeSquare) && Right.is(tok::l_square)) ||
(Left.is(tok::r_square) && Right.is(TT_AttributeSquare))) {
if (Left.is(TT_AttributeLSquare) && Right.is(tok::l_square)) {
assert(Right.isNot(TT_AttributeLSquare));
return false;
}
if (Left.is(tok::r_square) && Right.is(TT_AttributeRSquare)) {
assert(Left.isNot(TT_AttributeRSquare));
return false;
}

Expand Down
23 changes: 23 additions & 0 deletions clang/unittests/Format/TokenAnnotatorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4232,6 +4232,29 @@ TEST_F(TokenAnnotatorTest, QtProperty) {
EXPECT_TOKEN(Tokens[12], tok::identifier, TT_QtProperty);
}

TEST_F(TokenAnnotatorTest, AttributeSquares) {
auto Tokens = annotate("[[maybe_unused]] const int i;");
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_AttributeLSquare);
EXPECT_TOKEN(Tokens[1], tok::l_square, TT_Unknown);
EXPECT_TOKEN(Tokens[3], tok::r_square, TT_Unknown);
EXPECT_TOKEN(Tokens[4], tok::r_square, TT_AttributeRSquare);
EXPECT_TRUE(Tokens[4]->EndsCppAttributeGroup);

Tokens = annotate("[[foo([[]])]] [[maybe_unused]] int j;");
ASSERT_EQ(Tokens.size(), 20u) << Tokens;
EXPECT_TOKEN(Tokens[0], tok::l_square, TT_AttributeLSquare);
EXPECT_TOKEN(Tokens[1], tok::l_square, TT_Unknown);
EXPECT_TOKEN(Tokens[9], tok::r_square, TT_Unknown);
EXPECT_TOKEN(Tokens[10], tok::r_square, TT_AttributeRSquare);
EXPECT_FALSE(Tokens[10]->EndsCppAttributeGroup);
EXPECT_TOKEN(Tokens[11], tok::l_square, TT_AttributeLSquare);
EXPECT_TOKEN(Tokens[12], tok::l_square, TT_Unknown);
EXPECT_TOKEN(Tokens[14], tok::r_square, TT_Unknown);
EXPECT_TOKEN(Tokens[15], tok::r_square, TT_AttributeRSquare);
EXPECT_TRUE(Tokens[15]->EndsCppAttributeGroup);
}

} // namespace
} // namespace format
} // namespace clang