r183014 - Improve clang-format's c-style cast detection.
Daniel Jasper
djasper at google.com
Fri May 31 09:14:28 PDT 2013
Author: djasper
Date: Fri May 31 11:14:28 2013
New Revision: 183014
URL: http://llvm.org/viewvc/llvm-project?rev=183014&view=rev
Log:
Improve clang-format's c-style cast detection.
Before:
x[(uint8) y];
x = (uint8) y;
void f() { x = (uint8) y; }
#define AA(X) sizeof(((X *) NULL)->a)
After:
x[(uint8)y];
x = (uint8)y;
void f() { x = (uint8)y; }
#define AA(X) sizeof(((X *)NULL)->a)
Modified:
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=183014&r1=183013&r2=183014&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Fri May 31 11:14:28 2013
@@ -602,19 +602,35 @@ private:
else
Current.Type = TT_BlockComment;
} else if (Current.is(tok::r_paren)) {
- bool ParensNotExpr = !Current.Previous ||
+ FormatToken *LeftOfParens = NULL;
+ if (Current.MatchingParen)
+ LeftOfParens = Current.MatchingParen->getPreviousNoneComment();
+ bool IsCast = false;
+ bool ParensAreEmpty = Current.Previous == Current.MatchingParen;
+ bool ParensAreType = !Current.Previous ||
Current.Previous->Type == TT_PointerOrReference ||
- Current.Previous->Type == TT_TemplateCloser;
+ Current.Previous->Type == TT_TemplateCloser ||
+ isSimpleTypeSpecifier(*Current.Previous);
bool ParensCouldEndDecl =
Current.Next &&
Current.Next->isOneOf(tok::equal, tok::semi, tok::l_brace);
bool IsSizeOfOrAlignOf =
- Current.MatchingParen && Current.MatchingParen->Previous &&
- Current.MatchingParen->Previous->isOneOf(tok::kw_sizeof,
- tok::kw_alignof);
- if (ParensNotExpr && !ParensCouldEndDecl && !IsSizeOfOrAlignOf &&
+ LeftOfParens &&
+ LeftOfParens->isOneOf(tok::kw_sizeof, tok::kw_alignof);
+ if (ParensAreType && !ParensCouldEndDecl && !IsSizeOfOrAlignOf &&
Contexts.back().IsExpression)
- // FIXME: We need to get smarter and understand more cases of casts.
+ IsCast = true;
+ if (Current.Next &&
+ (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->Type != TT_ObjCMethodExpr && Current.Next &&
+ (Current.Next->is(tok::identifier)))
+ IsCast = true;
+ if (IsCast && !ParensAreEmpty)
Current.Type = TT_CastRParen;
} else if (Current.is(tok::at) && Current.Next) {
switch (Current.Next->Tok.getObjCKeywordID()) {
@@ -677,7 +693,7 @@ private:
TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {
const FormatToken *PrevToken = Tok.getPreviousNoneComment();
- if (PrevToken == NULL)
+ if (PrevToken == NULL || PrevToken->Type == TT_CastRParen)
return TT_UnaryOperator;
// Use heuristics to recognize unary operators.
@@ -697,7 +713,7 @@ private:
/// \brief Determine whether ++/-- are pre- or post-increments/-decrements.
TokenType determineIncrementUsage(const FormatToken &Tok) {
const FormatToken *PrevToken = Tok.getPreviousNoneComment();
- if (PrevToken == NULL)
+ if (PrevToken == NULL || PrevToken->Type == TT_CastRParen)
return TT_UnaryOperator;
if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
return TT_TrailingUnaryOperator;
@@ -780,11 +796,11 @@ public:
int CurrentPrecedence = 0;
if (Current) {
if (Current->Type == TT_ConditionalExpr)
- CurrentPrecedence = 1 + (int) prec::Conditional;
+ CurrentPrecedence = 1 + (int)prec::Conditional;
else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon)
CurrentPrecedence = 1;
else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma))
- CurrentPrecedence = 1 + (int) Current->getPrecedence();
+ CurrentPrecedence = 1 + (int)Current->getPrecedence();
}
// At the end of the line or when an operator with higher precedence is
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=183014&r1=183013&r2=183014&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Fri May 31 11:14:28 2013
@@ -3173,10 +3173,24 @@ TEST_F(FormatTest, FormatsCasts) {
verifyFormat("Type *A = (Type *)P;");
verifyFormat("Type *A = (vector<Type *, int *>)P;");
verifyFormat("int a = (int)(2.0f);");
+ verifyFormat("int a = (int)2.0f;");
+ verifyFormat("x[(int32)y];");
+ verifyFormat("x = (int32)y;");
+ verifyFormat("#define AA(X) sizeof(((X *)NULL)->a)");
+ verifyFormat("int a = (int)*b;");
+ verifyFormat("int a = (int)2.0f;");
+ verifyFormat("int a = (int)~0;");
+ verifyFormat("int a = (int)++a;");
+ verifyFormat("int a = (int)sizeof(int);");
+ verifyFormat("int a = (int)+2;");
+ verifyFormat("my_int a = (my_int)2.0f;");
+ verifyFormat("my_int a = (my_int)sizeof(int);");
- // FIXME: These also need to be identified.
- verifyFormat("int a = (int) 2.0f;");
- verifyFormat("int a = (int) * b;");
+ // FIXME: Without type knowledge, this can still fall apart miserably.
+ verifyFormat("void f() { my_int a = (my_int) * b; }");
+ verifyFormat("my_int a = (my_int) ~0;");
+ verifyFormat("my_int a = (my_int)++ a;");
+ verifyFormat("my_int a = (my_int) + 2;");
// These are not casts.
verifyFormat("void f(int *) {}");
More information about the cfe-commits
mailing list