[PATCH] Some heuristics to identify c style casting (PR18937)
Dinesh Dwivedi
dinesh.d at samsung.com
Wed Apr 30 14:19:38 PDT 2014
Hi djasper, klimek,
I have added few heuristics to identify c style casting. Only side
effect of this patch is that single identifier wrapped with parentheses
(identifier) are getting treated as cast.
http://reviews.llvm.org/D3576
Files:
lib/Format/TokenAnnotator.cpp
unittests/Format/FormatTest.cpp
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -775,19 +775,45 @@
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 { // Some heuristics to identify c style casting
+ FormatToken *Prev = Current.Previous;
+ if (Prev && Prev->isOneOf(tok::amp, tok::star))
+ Prev = Prev->Previous;
+
+ // if there is some unary operator after () and then an identifier
+ // it is likely a cast
+ if (Prev && (Current.Next->isUnaryOperator() ||
+ Current.Next->isOneOf(tok::amp, tok::star)) &&
+ Current.Next->Next &&
+ Current.Next->Next->isOneOf(tok::identifier,
+ tok::numeric_constant))
+ IsCast = true;
+
+ // only tokens allowed inside () is const and some identifier
+ // isSimpleTypeSpecifier case is already handled above
+ while (Prev != Current.MatchingParen) {
+ if (!Prev || !Prev->isOneOf(tok::kw_const, tok::identifier)) {
+ IsCast = false;
+ break;
+ }
+ Prev = Prev->Previous;
+ }
+ }
+ }
if (IsCast && !ParensAreEmpty)
Current.Type = TT_CastRParen;
} else if (Current.is(tok::at) && Current.Next) {
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -4741,12 +4741,18 @@
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 @@
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());
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3576.8991.patch
Type: text/x-patch
Size: 4662 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140430/1d933286/attachment.bin>
More information about the cfe-commits
mailing list