MyDeveloperDay created this revision. MyDeveloperDay added reviewers: djasper, klimek, JonasToth, krasimir, reuk. MyDeveloperDay added a project: clang-tools-extra.
Addresses PR40696 - https://bugs.llvm.org/show_bug.cgi?id=40696 The BreakAfterReturnType didn't work if it had a single arguments which was a template with an integer template parameter int foo(A<8> a) { return a; } When run with the Mozilla style. would not break after the `int` int TestFn(A<8> a) { return a; } This revision resolves this issue by allowing numeric constants to be considered function parameters if if seen inside `<>` https://reviews.llvm.org/D59309 Files: 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 @@ -5419,6 +5419,42 @@ "}\n" "template <class T> T *f(T &c);\n", // No break here. Style); + verifyFormat("int\n" + "foo(A<bool> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<8> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<B<bool>, 8> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<B<8>, bool> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<B<bool>, bool> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<B<8>, 8> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); } TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2040,6 +2040,7 @@ if (Next->MatchingParen->Next && Next->MatchingParen->Next->is(TT_PointerOrReference)) return true; + int TemplateOpenerLevel = 0; for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen; Tok = Tok->Next) { if (Tok->is(tok::l_paren) && Tok->MatchingParen) { @@ -2049,6 +2050,15 @@ if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() || Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) return true; + // Keep a track of how deep inside nested templates chevrons we are. + if (Tok->is(TT_TemplateOpener)) + TemplateOpenerLevel++; + if (Tok->is(TT_TemplateCloser)) + TemplateOpenerLevel--; + // We need to see a numeric_constant in a template argument e.g. <8> + // for it to be an argument that suggests a function decl. + if (Tok->is(tok::numeric_constant) && TemplateOpenerLevel > 0) + return true; if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) || Tok->Tok.isLiteral()) return false;
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -5419,6 +5419,42 @@ "}\n" "template <class T> T *f(T &c);\n", // No break here. Style); + verifyFormat("int\n" + "foo(A<bool> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<8> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<B<bool>, 8> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<B<8>, bool> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<B<bool>, bool> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); + verifyFormat("int\n" + "foo(A<B<8>, 8> a)\n" + "{\n" + " return a;\n" + "}\n", + Style); } TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2040,6 +2040,7 @@ if (Next->MatchingParen->Next && Next->MatchingParen->Next->is(TT_PointerOrReference)) return true; + int TemplateOpenerLevel = 0; for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen; Tok = Tok->Next) { if (Tok->is(tok::l_paren) && Tok->MatchingParen) { @@ -2049,6 +2050,15 @@ if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() || Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) return true; + // Keep a track of how deep inside nested templates chevrons we are. + if (Tok->is(TT_TemplateOpener)) + TemplateOpenerLevel++; + if (Tok->is(TT_TemplateCloser)) + TemplateOpenerLevel--; + // We need to see a numeric_constant in a template argument e.g. <8> + // for it to be an argument that suggests a function decl. + if (Tok->is(tok::numeric_constant) && TemplateOpenerLevel > 0) + return true; if (Tok->isOneOf(tok::l_brace, tok::string_literal, TT_ObjCMethodExpr) || Tok->Tok.isLiteral()) return false;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits