forked from OSchip/llvm-project
Added some heuristics to identify c style casting
Before: void f() { my_int a = (my_int) * b; } void f() { return P ? (my_int) * P : (my_int)0; } After: void f() { my_int a = (my_int)*b; } void f() { return P ? (my_int)*P : (my_int)0; } Differential Revision: http://reviews.llvm.org/D3576 llvm-svn: 207964
This commit is contained in:
parent
6af073b636
commit
76f98f8047
|
@ -756,6 +756,7 @@ private:
|
|||
else
|
||||
Current.Type = TT_BlockComment;
|
||||
} else if (Current.is(tok::r_paren)) {
|
||||
// FIXME: Pull cast detection into its own function.
|
||||
FormatToken *LeftOfParens = NULL;
|
||||
if (Current.MatchingParen)
|
||||
LeftOfParens = Current.MatchingParen->getPreviousNonComment();
|
||||
|
@ -776,19 +777,42 @@ private:
|
|||
Contexts[Contexts.size() - 2].IsExpression) ||
|
||||
(Current.Next && Current.Next->isBinaryOperator())))
|
||||
IsCast = true;
|
||||
if (Current.Next && Current.Next->isNot(tok::string_literal) &&
|
||||
(Current.Next->Tok.isLiteral() ||
|
||||
Current.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
|
||||
else if (Current.Next && Current.Next->isNot(tok::string_literal) &&
|
||||
(Current.Next->Tok.isLiteral() ||
|
||||
Current.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
|
||||
IsCast = true;
|
||||
// If there is an identifier after the (), it is likely a cast, unless
|
||||
// there is also an identifier before the ().
|
||||
if (LeftOfParens && (LeftOfParens->Tok.getIdentifierInfo() == NULL ||
|
||||
LeftOfParens->is(tok::kw_return)) &&
|
||||
LeftOfParens->Type != TT_OverloadedOperator &&
|
||||
LeftOfParens->isNot(tok::at) &&
|
||||
LeftOfParens->Type != TT_TemplateCloser && Current.Next &&
|
||||
Current.Next->is(tok::identifier))
|
||||
IsCast = true;
|
||||
else if (LeftOfParens &&
|
||||
(LeftOfParens->Tok.getIdentifierInfo() == NULL ||
|
||||
LeftOfParens->is(tok::kw_return)) &&
|
||||
LeftOfParens->Type != TT_OverloadedOperator &&
|
||||
LeftOfParens->isNot(tok::at) &&
|
||||
LeftOfParens->Type != TT_TemplateCloser && Current.Next) {
|
||||
if (Current.Next->isOneOf(tok::identifier, tok::numeric_constant)) {
|
||||
IsCast = true;
|
||||
} else {
|
||||
// Use heuristics to recognize c style casting.
|
||||
FormatToken *Prev = Current.Previous;
|
||||
if (Prev && Prev->isOneOf(tok::amp, tok::star))
|
||||
Prev = Prev->Previous;
|
||||
|
||||
if (Prev && Current.Next && Current.Next->Next) {
|
||||
bool NextIsUnary = Current.Next->isUnaryOperator() ||
|
||||
Current.Next->isOneOf(tok::amp, tok::star);
|
||||
IsCast = NextIsUnary &&
|
||||
Current.Next->Next->isOneOf(tok::identifier,
|
||||
tok::numeric_constant);
|
||||
}
|
||||
|
||||
for (; Prev != Current.MatchingParen; Prev = Prev->Previous) {
|
||||
if (!Prev || !Prev->isOneOf(tok::kw_const, tok::identifier)) {
|
||||
IsCast = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsCast && !ParensAreEmpty)
|
||||
Current.Type = TT_CastRParen;
|
||||
} else if (Current.is(tok::at) && Current.Next) {
|
||||
|
|
|
@ -4741,12 +4741,18 @@ TEST_F(FormatTest, FormatsCasts) {
|
|||
verifyFormat("#define x ((int)-1)");
|
||||
verifyFormat("#define p(q) ((int *)&q)");
|
||||
|
||||
// FIXME: Without type knowledge, this can still fall apart miserably.
|
||||
verifyFormat("void f() { my_int a = (my_int) * b; }");
|
||||
verifyFormat("void f() { return P ? (my_int) * P : (my_int)0; }");
|
||||
verifyFormat("my_int a = (my_int) ~0;");
|
||||
verifyFormat("my_int a = (my_int)++ a;");
|
||||
verifyFormat("my_int a = (my_int) + 2;");
|
||||
verifyFormat("void f() { my_int a = (my_int)*b; }");
|
||||
verifyFormat("void f() { return P ? (my_int)*P : (my_int)0; }");
|
||||
verifyFormat("my_int a = (my_int)~0;");
|
||||
verifyFormat("my_int a = (my_int)++a;");
|
||||
verifyFormat("my_int a = (my_int)+2;");
|
||||
verifyFormat("my_int a = (my_int)1;");
|
||||
verifyFormat("my_int a = (my_int *)1;");
|
||||
verifyFormat("my_int a = (const my_int)-1;");
|
||||
verifyFormat("my_int a = (const my_int *)-1;");
|
||||
|
||||
// FIXME: single value wrapped with paren will be treated as cast.
|
||||
verifyFormat("void f(int i = (kValue)*kMask) {}");
|
||||
|
||||
// Don't break after a cast's
|
||||
verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
|
||||
|
@ -4767,7 +4773,6 @@ TEST_F(FormatTest, FormatsCasts) {
|
|||
verifyFormat("void f(SmallVector<int>) {}");
|
||||
verifyFormat("void f(SmallVector<int>);");
|
||||
verifyFormat("void f(SmallVector<int>) = 0;");
|
||||
verifyFormat("void f(int i = (kValue) * kMask) {}");
|
||||
verifyFormat("void f(int i = (kA * kB) & kMask) {}");
|
||||
verifyFormat("int a = sizeof(int) * b;");
|
||||
verifyFormat("int a = alignof(int) * b;", getGoogleStyle());
|
||||
|
|
Loading…
Reference in New Issue