From 5b49f47835e89ffc6dbf8468322febe66ebb6ecf Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Wed, 23 Jan 2013 12:10:53 +0000 Subject: [PATCH] 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. llvm-svn: 173256 --- clang/lib/Format/Format.cpp | 30 ++++++---- clang/unittests/Format/FormatTest.cpp | 108 ++++++++++++++++++---------------- 2 files changed, 75 insertions(+), 63 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 36bf53d..2d9bd2c 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1237,7 +1237,7 @@ public: 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 @@ public: } 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 @@ private: } if (!Current.Children.empty()) - determineTokenTypes(Current.Children[0], IsRHS); + determineTokenTypes(Current.Children[0], IsExpression); } bool isBinaryOperator(const AnnotatedToken &Tok) { @@ -1338,7 +1345,8 @@ private: } /// \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 @@ private: // 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/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 44f91c7..3a1cfb2 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -100,6 +100,11 @@ protected: 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, UnderstandsNewAndDelete) { 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;"); - - verifyFormat("InvalidRegions[*R] = 0;"); - - verifyFormat("A a;"); - verifyFormat("A a;"); - verifyFormat("A a;"); - verifyFormat("A 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;"); + + verifyIndependentOfContext("InvalidRegions[*R] = 0;"); + + verifyIndependentOfContext("A a;"); + verifyIndependentOfContext("A a;"); + verifyIndependentOfContext("A a;"); + verifyIndependentOfContext("A a;"); verifyFormat( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" @@ -1333,28 +1337,28 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyGoogleFormat("Type* t = const_cast(&*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]();"); } -- 2.7.4