This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGbfb4afee74c8: [clang-format] Avoid inserting space after C++ casts. (authored by curdeius).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D120140/new/ https://reviews.llvm.org/D120140 Files: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -10570,6 +10570,19 @@ TEST_F(FormatTest, FormatsCasts) { verifyFormat("Type *A = static_cast<Type *>(P);"); + verifyFormat("static_cast<Type *>(P);"); + verifyFormat("static_cast<Type &>(Fun)(Args);"); + verifyFormat("static_cast<Type &>(*Fun)(Args);"); + verifyFormat("if (static_cast<int>(A) + B >= 0)\n ;"); + // Check that static_cast<...>(...) does not require the next token to be on + // the same line. + verifyFormat("some_loooong_output << something_something__ << " + "static_cast<const void *>(R)\n" + " << something;"); + verifyFormat("a = static_cast<Type &>(*Fun)(Args);"); + verifyFormat("const_cast<Type &>(*Fun)(Args);"); + verifyFormat("dynamic_cast<Type &>(*Fun)(Args);"); + verifyFormat("reinterpret_cast<Type &>(*Fun)(Args);"); verifyFormat("Type *A = (Type *)P;"); verifyFormat("Type *A = (vector<Type *, int *>)P;"); verifyFormat("int a = (int)(2.0f);"); Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -358,7 +358,8 @@ if (CurrentToken->Previous->is(TT_BinaryOperator)) Contexts.back().IsExpression = true; if (CurrentToken->is(tok::r_paren)) { - if (MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next && + if (Left->isNot(TT_CppCastLParen) && MightBeFunctionType && + ProbablyFunctionType && CurrentToken->Next && (CurrentToken->Next->is(tok::l_paren) || (CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration))) Left->setType(Left->Next->is(tok::caret) ? TT_ObjCBlockLParen @@ -1733,6 +1734,9 @@ Current.Tok.setKind(tok::unknown); else Current.setType(TT_LineComment); + } else if (Current.is(tok::l_paren)) { + if (lParenStartsCppCast(Current)) + Current.setType(TT_CppCastLParen); } else if (Current.is(tok::r_paren)) { if (rParenEndsCast(Current)) Current.setType(TT_CastRParen); @@ -1880,6 +1884,25 @@ return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const); } + /// Determine whether '(' is starting a C++ cast. + bool lParenStartsCppCast(const FormatToken &Tok) { + // C-style casts are only used in C++. + if (!Style.isCpp()) + return false; + + FormatToken *LeftOfParens = Tok.getPreviousNonComment(); + if (LeftOfParens && LeftOfParens->is(TT_TemplateCloser) && + LeftOfParens->MatchingParen) { + auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment(); + if (Prev && Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast, + tok::kw_reinterpret_cast, tok::kw_static_cast)) + // FIXME: Maybe we should handle identifiers ending with "_cast", + // e.g. any_cast? + return true; + } + return false; + } + /// Determine whether ')' is ending a cast. bool rParenEndsCast(const FormatToken &Tok) { // C-style casts are only used in C++, C# and Java. Index: clang/lib/Format/FormatToken.h =================================================================== --- clang/lib/Format/FormatToken.h +++ clang/lib/Format/FormatToken.h @@ -43,6 +43,7 @@ TYPE(ConflictAlternative) \ TYPE(ConflictEnd) \ TYPE(ConflictStart) \ + TYPE(CppCastLParen) \ TYPE(CtorInitializerColon) \ TYPE(CtorInitializerComma) \ TYPE(DesignatedInitializerLSquare) \
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -10570,6 +10570,19 @@ TEST_F(FormatTest, FormatsCasts) { verifyFormat("Type *A = static_cast<Type *>(P);"); + verifyFormat("static_cast<Type *>(P);"); + verifyFormat("static_cast<Type &>(Fun)(Args);"); + verifyFormat("static_cast<Type &>(*Fun)(Args);"); + verifyFormat("if (static_cast<int>(A) + B >= 0)\n ;"); + // Check that static_cast<...>(...) does not require the next token to be on + // the same line. + verifyFormat("some_loooong_output << something_something__ << " + "static_cast<const void *>(R)\n" + " << something;"); + verifyFormat("a = static_cast<Type &>(*Fun)(Args);"); + verifyFormat("const_cast<Type &>(*Fun)(Args);"); + verifyFormat("dynamic_cast<Type &>(*Fun)(Args);"); + verifyFormat("reinterpret_cast<Type &>(*Fun)(Args);"); verifyFormat("Type *A = (Type *)P;"); verifyFormat("Type *A = (vector<Type *, int *>)P;"); verifyFormat("int a = (int)(2.0f);"); Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -358,7 +358,8 @@ if (CurrentToken->Previous->is(TT_BinaryOperator)) Contexts.back().IsExpression = true; if (CurrentToken->is(tok::r_paren)) { - if (MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next && + if (Left->isNot(TT_CppCastLParen) && MightBeFunctionType && + ProbablyFunctionType && CurrentToken->Next && (CurrentToken->Next->is(tok::l_paren) || (CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration))) Left->setType(Left->Next->is(tok::caret) ? TT_ObjCBlockLParen @@ -1733,6 +1734,9 @@ Current.Tok.setKind(tok::unknown); else Current.setType(TT_LineComment); + } else if (Current.is(tok::l_paren)) { + if (lParenStartsCppCast(Current)) + Current.setType(TT_CppCastLParen); } else if (Current.is(tok::r_paren)) { if (rParenEndsCast(Current)) Current.setType(TT_CastRParen); @@ -1880,6 +1884,25 @@ return Style.isJavaScript() && PreviousNotConst->is(tok::kw_const); } + /// Determine whether '(' is starting a C++ cast. + bool lParenStartsCppCast(const FormatToken &Tok) { + // C-style casts are only used in C++. + if (!Style.isCpp()) + return false; + + FormatToken *LeftOfParens = Tok.getPreviousNonComment(); + if (LeftOfParens && LeftOfParens->is(TT_TemplateCloser) && + LeftOfParens->MatchingParen) { + auto *Prev = LeftOfParens->MatchingParen->getPreviousNonComment(); + if (Prev && Prev->isOneOf(tok::kw_const_cast, tok::kw_dynamic_cast, + tok::kw_reinterpret_cast, tok::kw_static_cast)) + // FIXME: Maybe we should handle identifiers ending with "_cast", + // e.g. any_cast? + return true; + } + return false; + } + /// Determine whether ')' is ending a cast. bool rParenEndsCast(const FormatToken &Tok) { // C-style casts are only used in C++, C# and Java. Index: clang/lib/Format/FormatToken.h =================================================================== --- clang/lib/Format/FormatToken.h +++ clang/lib/Format/FormatToken.h @@ -43,6 +43,7 @@ TYPE(ConflictAlternative) \ TYPE(ConflictEnd) \ TYPE(ConflictStart) \ + TYPE(CppCastLParen) \ TYPE(CtorInitializerColon) \ TYPE(CtorInitializerComma) \ TYPE(DesignatedInitializerLSquare) \
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits