If the approach is not right, I'll try to rework the fix with your feedback.
Problem:
========
FormatStyle Spaces = getLLVMStyle();
verifyFormat("Deleted &operator=(const Deleted &)& = default;");
Spaces.SpacesInParentheses= true;
verifyFormat("Deleted( const Deleted & )& = default;", Spaces); // Fail
"Deleted(const Deleted &)& = default;"
Spaces.SpacesInCStyleCastParentheses = true;
Spaces.SpacesInParentheses= false;
verifyFormat("Deleted(const Deleted &)& = default;", Spaces); // Fail "Deleted(
const Deleted & )& = default;"
Solution:
=======
The cast seemed too eager: There does not seem to be a reason for a binary
operator to follow a C-cast.
The type of the function reference qualification seems to make sense as
TT_PointerOrReference:
-Extend in the case of to handle the '&&' case "Deleted(const Deleted &)&& =
default;"
-Extend to handle the case without '=' for '*', '&' and '&&' case
"Deleted(const Deleted &)&;"
Ensure no spaces between parenthesis and the reference qualification:
"Deleted &operator=(const Deleted &)&;" can be detected with
TT_OverloadedOperatorLParen
"SomeType MemberFunction(const Deleted &)&;" can be detected with
TT_FunctionDeclarationName
But "Deleted(const Deleted &)&;" cannot be detected with existing mechanisms:
- Introduce TT_FunctionLParen to recognize Function parentheses.
TT_FunctionLParen assume that an 'identifier(' necessarily represent a function
declaration or function call including constructors.
It could also happen for functional C-cast, but it seem safe to assume they
should be treated as function.
This changeset is already quite big for me, so I did not try to ensure
TT_FunctionDeclarationName is always followed by TT_FunctionLParen.
As TT_FunctionDeclarationName, TT_FunctionLParen is currently a best effort
guess. It could be added in a separate changeset with a new set of tests.
Tests:
=====
The set of unit tests is not quite minimal, it needs:
- To cover LLVM, Google, SpacesInCStyleCastParentheses, SpacesInParentheses.
- Both ref-qualifications : '&' and '&&'
- Operator, function, and constructor.
Additional test:
Verify clang-format output is unchanged for the 3 modified files FormatToken.h,
TokenAnnotator.cpp, FormatTest.cpp
http://reviews.llvm.org/D7813
Files:
lib/Format/FormatToken.h
lib/Format/TokenAnnotator.cpp
unittests/Format/FormatTest.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/Format/FormatToken.h
===================================================================
--- lib/Format/FormatToken.h
+++ lib/Format/FormatToken.h
@@ -43,6 +43,7 @@
TT_DictLiteral,
TT_FunctionDeclarationName,
TT_FunctionLBrace,
+ TT_FunctionLParen,
TT_FunctionTypeLParen,
TT_ImplicitStringLiteral,
TT_InheritanceColon,
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -460,6 +460,8 @@
return false;
break;
case tok::l_paren:
+ if (Tok->Previous && Tok->Previous->is(tok::identifier))
+ Tok->Type = TT_FunctionLParen;
if (!parseParens())
return false;
if (Line.MustBeDeclaration && Contexts.size() == 1 &&
@@ -766,8 +768,8 @@
break;
}
if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator) &&
- Previous->isOneOf(tok::star, tok::amp) && Previous->Previous &&
- Previous->Previous->isNot(tok::equal))
+ Previous->isOneOf(tok::star, tok::amp, tok::ampamp) &&
+ Previous->Previous && Previous->Previous->isNot(tok::equal))
Previous->Type = TT_PointerOrReference;
}
}
@@ -802,6 +804,9 @@
} else if (Current.is(tok::semi) || Current.is(tok::exclaim)) {
// This should be the condition or increment in a for-loop.
Contexts.back().IsExpression = true;
+ if (Current.is(tok::semi) && Line.MustBeDeclaration && Current.Previous &&
+ Current.Previous->isOneOf(tok::star, tok::amp, tok::ampamp))
+ Current.Previous->Type = TT_PointerOrReference;
}
}
@@ -972,8 +977,7 @@
bool IsSizeOfOrAlignOf =
LeftOfParens && LeftOfParens->isOneOf(tok::kw_sizeof, tok::kw_alignof);
if (ParensAreType && !ParensCouldEndDecl && !IsSizeOfOrAlignOf &&
- ((Contexts.size() > 1 && Contexts[Contexts.size() - 2].IsExpression) ||
- (Tok.Next && Tok.Next->isBinaryOperator())))
+ (Contexts.size() > 1 && Contexts[Contexts.size() - 2].IsExpression))
IsCast = true;
else if (Tok.Next && Tok.Next->isNot(tok::string_literal) &&
(Tok.Next->Tok.isLiteral() ||
@@ -1663,9 +1667,12 @@
if (Left.is(tok::l_square) && Right.is(tok::amp))
return false;
if (Right.is(TT_PointerOrReference))
- return Left.Tok.isLiteral() ||
- (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
- Style.PointerAlignment != FormatStyle::PAS_Left);
+ return !(Left.is(tok::r_paren) && Left.MatchingParen &&
+ Left.MatchingParen->isOneOf(TT_OverloadedOperatorLParen,
+ TT_FunctionLParen)) &&
+ (Left.Tok.isLiteral() ||
+ (!Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
+ Style.PointerAlignment != FormatStyle::PAS_Left));
if (Right.is(TT_FunctionTypeLParen) && Left.isNot(tok::l_paren) &&
(!Left.is(TT_PointerOrReference) ||
Style.PointerAlignment != FormatStyle::PAS_Right))
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -5164,17 +5164,52 @@
verifyFormat("using A::operator+;");
- verifyFormat("Deleted &operator=(const Deleted &)& = default;");
- verifyFormat("Deleted &operator=(const Deleted &)&& = delete;");
- verifyGoogleFormat("Deleted& operator=(const Deleted&)& = default;");
- verifyGoogleFormat("Deleted& operator=(const Deleted&)&& = delete;");
-
verifyFormat("string // break\n"
"operator()() & {}");
verifyFormat("string // break\n"
"operator()() && {}");
}
+TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
+ verifyFormat("Deleted(const Deleted &)& = default;");
+ verifyFormat("Deleted(const Deleted &)&& = delete;");
+ verifyFormat("Deleted &operator=(const Deleted &)& = default;");
+ verifyFormat("Deleted &operator=(const Deleted &)&& = delete;");
+ verifyFormat("SomeType MemberFunction(const Deleted &)& = delete;");
+ verifyFormat("SomeType MemberFunction(const Deleted &)&& = delete;");
+ verifyFormat("Deleted(const Deleted &)&;");
+ verifyFormat("Deleted(const Deleted &)&&;");
+ verifyFormat("Deleted &operator=(const Deleted &)&;");
+ verifyFormat("Deleted &operator=(const Deleted &)&&;");
+ verifyFormat("SomeType MemberFunction(const Deleted &)&;");
+ verifyFormat("SomeType MemberFunction(const Deleted &)&&;");
+
+ verifyGoogleFormat("Deleted(const Deleted&)& = default;");
+ verifyGoogleFormat("Deleted& operator=(const Deleted&)& = default;");
+ verifyGoogleFormat("SomeType MemberFunction(const Deleted&)& = delete;");
+ verifyGoogleFormat("Deleted(const Deleted&)&;");
+ verifyGoogleFormat("Deleted& operator=(const Deleted&)&;");
+ verifyGoogleFormat("SomeType MemberFunction(const Deleted&)&;");
+
+ FormatStyle Spaces = getLLVMStyle();
+ Spaces.SpacesInCStyleCastParentheses = true;
+ verifyFormat("Deleted(const Deleted &)& = default;", Spaces);
+ verifyFormat("Deleted &operator=(const Deleted &)& = default;", Spaces);
+ verifyFormat("SomeType MemberFunction(const Deleted &)& = delete;", Spaces);
+ verifyFormat("Deleted(const Deleted &)&;", Spaces);
+ verifyFormat("Deleted &operator=(const Deleted &)&;", Spaces);
+ verifyFormat("SomeType MemberFunction(const Deleted &)&;", Spaces);
+
+ Spaces.SpacesInCStyleCastParentheses = false;
+ Spaces.SpacesInParentheses = true;
+ verifyFormat("Deleted( const Deleted & )& = default;", Spaces);
+ verifyFormat("Deleted &operator=( const Deleted & )& = default;", Spaces);
+ verifyFormat("SomeType MemberFunction( const Deleted & )& = delete;", Spaces);
+ verifyFormat("Deleted( const Deleted & )&;", Spaces);
+ verifyFormat("Deleted &operator=( const Deleted & )&;", Spaces);
+ verifyFormat("SomeType MemberFunction( const Deleted & )&;", Spaces);
+}
+
TEST_F(FormatTest, UnderstandsNewAndDelete) {
verifyFormat("void f() {\n"
" A *a = new A;\n"
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits