Fix another regression for pointer types.
Before: if (int * a = &b) ...
After: if (int *a = &b) ...
Also changed all the existing tests to test the expressions in question
both in a declaration and in an expression context.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173256 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 36bf53d..2d9bd2c 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -1237,7 +1237,7 @@
if (Line.Type == LT_Invalid)
return;
- determineTokenTypes(Line.First, /*IsRHS=*/false);
+ determineTokenTypes(Line.First, /*IsExpression=*/ false);
if (Line.First.Type == TT_ObjCMethodSpecifier)
Line.Type = LT_ObjCMethodDecl;
@@ -1256,16 +1256,23 @@
}
private:
- void determineTokenTypes(AnnotatedToken &Current, bool IsRHS) {
- if (getPrecedence(Current) == prec::Assignment ||
- Current.is(tok::kw_return) || Current.is(tok::kw_throw))
- IsRHS = true;
- if (Current.is(tok::l_paren) && !Line.MustBeDeclaration)
- IsRHS = true;
+ void determineTokenTypes(AnnotatedToken &Current, bool IsExpression) {
+ if (getPrecedence(Current) == prec::Assignment) {
+ IsExpression = true;
+ AnnotatedToken *Previous = Current.Parent;
+ while (Previous != NULL) {
+ if (Previous->Type == TT_BinaryOperator)
+ Previous->Type = TT_PointerOrReference;
+ Previous = Previous->Parent;
+ }
+ }
+ if (Current.is(tok::kw_return) || Current.is(tok::kw_throw) ||
+ (Current.is(tok::l_paren) && !Line.MustBeDeclaration))
+ IsExpression = true;
if (Current.Type == TT_Unknown) {
if (Current.is(tok::star) || Current.is(tok::amp)) {
- Current.Type = determineStarAmpUsage(Current, IsRHS);
+ Current.Type = determineStarAmpUsage(Current, IsExpression);
} else if (Current.is(tok::minus) || Current.is(tok::plus) ||
Current.is(tok::caret)) {
Current.Type = determinePlusMinusCaretUsage(Current);
@@ -1308,7 +1315,7 @@
}
if (!Current.Children.empty())
- determineTokenTypes(Current.Children[0], IsRHS);
+ determineTokenTypes(Current.Children[0], IsExpression);
}
bool isBinaryOperator(const AnnotatedToken &Tok) {
@@ -1338,7 +1345,8 @@
}
/// \brief Return the type of the given token assuming it is * or &.
- TokenType determineStarAmpUsage(const AnnotatedToken &Tok, bool IsRHS) {
+ TokenType determineStarAmpUsage(const AnnotatedToken &Tok,
+ bool IsExpression) {
const AnnotatedToken *PrevToken = getPreviousToken(Tok);
if (PrevToken == NULL)
return TT_UnaryOperator;
@@ -1372,7 +1380,7 @@
// It is very unlikely that we are going to find a pointer or reference type
// definition on the RHS of an assignment.
- if (IsRHS)
+ if (IsExpression)
return TT_BinaryOperator;
return TT_PointerOrReference;
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 44f91c7..3a1cfb2 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -100,6 +100,11 @@
void verifyGoogleFormat(llvm::StringRef Code) {
verifyFormat(Code, getGoogleStyle());
}
+
+ void verifyIndependentOfContext(llvm::StringRef text) {
+ verifyFormat(text);
+ verifyFormat(llvm::Twine("void f() { " + text + " }").str());
+ }
};
TEST_F(FormatTest, MessUp) {
@@ -1276,45 +1281,44 @@
TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("int *f(int *a) {}");
- verifyFormat("f(a, *a);");
- verifyFormat("f(*a);");
- verifyFormat("int a = b * 10;");
- verifyFormat("int a = 10 * b;");
- verifyFormat("int a = b * c;");
- verifyFormat("int a += b * c;");
- verifyFormat("int a -= b * c;");
- verifyFormat("int a *= b * c;");
- verifyFormat("int a /= b * c;");
- verifyFormat("int a = *b;");
- verifyFormat("int a = *b * c;");
- verifyFormat("int a = b * *c;");
- verifyFormat("void f() { int *a = b * c; }");
verifyFormat("int main(int argc, char **argv) {}");
- verifyFormat("return 10 * b;");
- verifyFormat("return *b * *c;");
- verifyFormat("return a & ~b;");
- verifyFormat("f(b ? *c : *d);");
- verifyFormat("int a = b ? *c : *d;");
- verifyFormat("*b = a;");
- verifyFormat("a * ~b;");
- verifyFormat("a * !b;");
- verifyFormat("a * +b;");
- verifyFormat("a * -b;");
- verifyFormat("a * ++b;");
- verifyFormat("a * --b;");
- verifyFormat("a[4] * b;");
- verifyFormat("f() * b;");
- verifyFormat("a * [self dostuff];");
- verifyFormat("a * (a + b);");
- verifyFormat("(a *)(a + b);");
- verifyFormat("int *pa = (int *)&a;");
+ verifyIndependentOfContext("f(a, *a);");
+ verifyIndependentOfContext("f(*a);");
+ verifyIndependentOfContext("int a = b * 10;");
+ verifyIndependentOfContext("int a = 10 * b;");
+ verifyIndependentOfContext("int a = b * c;");
+ verifyIndependentOfContext("int a += b * c;");
+ verifyIndependentOfContext("int a -= b * c;");
+ verifyIndependentOfContext("int a *= b * c;");
+ verifyIndependentOfContext("int a /= b * c;");
+ verifyIndependentOfContext("int a = *b;");
+ verifyIndependentOfContext("int a = *b * c;");
+ verifyIndependentOfContext("int a = b * *c;");
+ verifyIndependentOfContext("return 10 * b;");
+ verifyIndependentOfContext("return *b * *c;");
+ verifyIndependentOfContext("return a & ~b;");
+ verifyIndependentOfContext("f(b ? *c : *d);");
+ verifyIndependentOfContext("int a = b ? *c : *d;");
+ verifyIndependentOfContext("*b = a;");
+ verifyIndependentOfContext("a * ~b;");
+ verifyIndependentOfContext("a * !b;");
+ verifyIndependentOfContext("a * +b;");
+ verifyIndependentOfContext("a * -b;");
+ verifyIndependentOfContext("a * ++b;");
+ verifyIndependentOfContext("a * --b;");
+ verifyIndependentOfContext("a[4] * b;");
+ verifyIndependentOfContext("f() * b;");
+ verifyIndependentOfContext("a * [self dostuff];");
+ verifyIndependentOfContext("a * (a + b);");
+ verifyIndependentOfContext("(a *)(a + b);");
+ verifyIndependentOfContext("int *pa = (int *)&a;");
- verifyFormat("InvalidRegions[*R] = 0;");
+ verifyIndependentOfContext("InvalidRegions[*R] = 0;");
- verifyFormat("A<int *> a;");
- verifyFormat("A<int **> a;");
- verifyFormat("A<int *, int *> a;");
- verifyFormat("A<int **, int **> a;");
+ verifyIndependentOfContext("A<int *> a;");
+ verifyIndependentOfContext("A<int **> a;");
+ verifyIndependentOfContext("A<int *, int *> a;");
+ verifyIndependentOfContext("A<int **, int **> a;");
verifyFormat(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
@@ -1333,28 +1337,28 @@
verifyGoogleFormat("Type* t = const_cast<T*>(&*x);");
verifyGoogleFormat("Type* t = x++ * y;");
- verifyFormat("a = *(x + y);");
- verifyFormat("a = &(x + y);");
- verifyFormat("*(x + y).call();");
- verifyFormat("&(x + y)->call();");
- verifyFormat("&(*I).first");
+ verifyIndependentOfContext("a = *(x + y);");
+ verifyIndependentOfContext("a = &(x + y);");
+ verifyIndependentOfContext("*(x + y).call();");
+ verifyIndependentOfContext("&(x + y)->call();");
+ verifyIndependentOfContext("&(*I).first");
- verifyFormat("f(b * /* confusing comment */ ++c);");
+ verifyIndependentOfContext("f(b * /* confusing comment */ ++c);");
verifyFormat(
"int *MyValues = {\n"
" *A, // Operator detection might be confused by the '{'\n"
" *BB // Operator detection might be confused by previous comment\n"
"};");
- verifyFormat("if (int *a = &b)");
- verifyFormat("if (int &a = *b)");
- verifyFormat("if (a & b[i])");
- verifyFormat("if (a::b::c::d & b[i])");
- verifyFormat("if (*b[i])");
- verifyFormat("if (int *a = (&b))");
- verifyFormat("while (int *a = &b)");
+ verifyIndependentOfContext("if (int *a = &b)");
+ verifyIndependentOfContext("if (int &a = *b)");
+ verifyIndependentOfContext("if (a & b[i])");
+ verifyIndependentOfContext("if (a::b::c::d & b[i])");
+ verifyIndependentOfContext("if (*b[i])");
+ verifyIndependentOfContext("if (int *a = (&b))");
+ verifyIndependentOfContext("while (int *a = &b)");
- verifyFormat("A = new SomeType *[Length]();");
+ verifyIndependentOfContext("A = new SomeType *[Length]();");
verifyGoogleFormat("A = new SomeType* [Length]();");
}