Author: Emilia Dreamer Date: 2022-09-05T12:35:39+02:00 New Revision: c6e7752f8e144ad78aee2e56a7c901c56be360de
URL: https://github.com/llvm/llvm-project/commit/c6e7752f8e144ad78aee2e56a7c901c56be360de DIFF: https://github.com/llvm/llvm-project/commit/c6e7752f8e144ad78aee2e56a7c901c56be360de.diff LOG: [clang-format] Allow `throw` to be a keyword in front of casts This makes throw more similar to return. However, unlike return, it has to more strict as to not remove spaces after usages of throw as a (deprecated) exception specifier. Fixes https://github.com/llvm/llvm-project/issues/57391 Differential Revision: https://reviews.llvm.org/D132762 Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 663e8ae6a898..d7c2e66ca488 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2153,7 +2153,7 @@ class AnnotatingParser { // before the parentheses, this is unlikely to be a cast. if (LeftOfParens->Tok.getIdentifierInfo() && !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case, - tok::kw_delete)) { + tok::kw_delete, tok::kw_throw)) { return false; } @@ -3315,6 +3315,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) { return true; } + if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen && + Right.MatchingParen->is(TT_CastRParen)) { + return true; + } if (Style.isJson() && Left.is(tok::string_literal) && Right.is(tok::colon)) return false; if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index ce56570697cd..4383a903b2f6 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -11038,6 +11038,7 @@ TEST_F(FormatTest, FormatsCasts) { verifyFormat("my_int a = (my_int)2.0f;"); verifyFormat("my_int a = (my_int)sizeof(int);"); verifyFormat("return (my_int)aaa;"); + verifyFormat("throw (my_int)aaa;"); verifyFormat("#define x ((int)-1)"); verifyFormat("#define LENGTH(x, y) (x) - (y) + 1"); verifyFormat("#define p(q) ((int *)&q)"); @@ -15730,6 +15731,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParentheses) { verifyFormat("Type *A = ( Type * )P;", Spaces); verifyFormat("Type *A = ( vector<Type *, int *> )P;", Spaces); verifyFormat("x = ( int32 )y;", Spaces); + verifyFormat("throw ( int32 )x;", Spaces); verifyFormat("int a = ( int )(2.0f);", Spaces); verifyFormat("#define AA(X) sizeof((( X * )NULL)->a)", Spaces); verifyFormat("my_int a = ( my_int )sizeof(int);", Spaces); @@ -15793,6 +15795,7 @@ TEST_F(FormatTest, ConfigurableSpacesInParentheses) { verifyFormat("#define CONF_BOOL(x) ( bool ) (x)", Spaces); verifyFormat("bool *y = ( bool * ) ( void * ) (x);", Spaces); verifyFormat("bool *y = ( bool * ) (x);", Spaces); + verifyFormat("throw ( int32 ) x;", Spaces); // Run subset of tests again with: Spaces.SpacesInCStyleCastParentheses = false; @@ -15817,6 +15820,8 @@ TEST_F(FormatTest, ConfigurableSpacesInParentheses) { verifyFormat("bool *y = (bool *) (void *) (x);", Spaces); verifyFormat("bool *y = (bool *) (void *) (int) (x);", Spaces); verifyFormat("bool *y = (bool *) (void *) (int) foo(x);", Spaces); + verifyFormat("throw (int32) x;", Spaces); + Spaces.ColumnLimit = 80; Spaces.IndentWidth = 4; Spaces.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 21ef5c382a90..60684d72605e 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -319,6 +319,34 @@ TEST_F(TokenAnnotatorTest, UnderstandsDelete) { EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); } +TEST_F(TokenAnnotatorTest, UnderstandsCasts) { + auto Tokens = annotate("(void)p;"); + EXPECT_EQ(Tokens.size(), 6u) << Tokens; + EXPECT_TOKEN(Tokens[2], tok::r_paren, TT_CastRParen); + + Tokens = annotate("auto x = (Foo)p;"); + EXPECT_EQ(Tokens.size(), 9u) << Tokens; + EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_CastRParen); + + Tokens = annotate("(std::vector<int>)p;"); + EXPECT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen); + + Tokens = annotate("return (Foo)p;"); + EXPECT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen); + + Tokens = annotate("throw (Foo)p;"); + EXPECT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen); +} + +TEST_F(TokenAnnotatorTest, UnderstandsDynamicExceptionSpecifier) { + auto Tokens = annotate("void f() throw(int);"); + EXPECT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[4], tok::kw_throw, TT_Unknown); +} + TEST_F(TokenAnnotatorTest, UnderstandsFunctionRefQualifiers) { auto Tokens = annotate("void f() &;"); EXPECT_EQ(Tokens.size(), 7u) << Tokens; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits