clang-format: better detection for multiplication operator

Daniel Jasper djasper at google.com
Sun Mar 30 10:45:51 PDT 2014


On Sun, Mar 30, 2014 at 5:40 PM, Kapfhammer <kapf at student.ethz.ch> wrote:

> This is a fix for: http://llvm.org/bugs/show_bug.cgi?id=16500
>
> Before: cout << a *b;
> After : cout << a * b;
>
> I tried to be conservative to have as few false positives as possible.
> The following lines are still formatted wrong:
>
> template <int i = a *b>
>

Yeah, I need to look some more at this one.


> f(a *b);
>

No, this is handled correctly. All you need to do is put it into a context
where there can actually be statements, i.e. into a function.


> a *b + c;
>

Put this as a call argument or onto the RHS of an assignment and it will be
formatted correctly. As it, it doesn't make much sense in actual code.

All in all, I think a much easier solution for the mentioned bug would be
to treat "<<" similar to how we treat assignments, i.e. if we find a <<, we
assume the RHS to be an expression (that's the very first "if" in
determineTokenType()).


> There's also the possibility to be more aggressive, but then the
> following existing testcase would have been broken:
>
> template <class CallbackClass>
> using MyCallback = void (CallbackClass::*)(SomeObject *Data);
>
> --
>
> From 2717f48825ecb1a24f6fe47400bbd3039d915120 Mon Sep 17 00:00:00 2001
> From: Kapfhammer <kapf at student.ethz.ch>
> Date: Sun, 30 Mar 2014 12:04:17 +0200
> Subject: [PATCH] clang-format: Use binary operators as an indicator of for
> an expression and
>  extend the test suite.
>
> This solves the issue where the star was too often interpreted as a
> pointer, e.g "cout<<a*b;" was formatted to "cout << a *b;" instead of
> "cout << a * b;".  By marking statements more often an expression, the
> function determineStarAmpUsage() is more reliable.
>
> The test suite was extended.
> ---
>  lib/Format/TokenAnnotator.cpp   | 11 +++++++++++
>  unittests/Format/FormatTest.cpp | 15 +++++++++++++++
>  2 files changed, 26 insertions(+)
>
> diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
> index 6a0e034..2e1faec 100644
> --- a/lib/Format/TokenAnnotator.cpp
> +++ b/lib/Format/TokenAnnotator.cpp
> @@ -798,6 +798,17 @@ private:
>          // function declaration have been found.
>          Current.Type = TT_TrailingAnnotation;
>        }
> +
> +      // A binary operator is most likely part of an expression
> +      if (Current.Type == TT_BinaryOperator &&
> +          !Current.isOneOf(tok::ampamp, tok::less, tok::greater,
> +                           tok::greatergreater) &&
> +          (!Current.Previous ||
> +           Current.Previous->isNot(tok::kw_operator)) &&
> +          Contexts.back().CanBeExpression &&
> +          !Line.First->isOneOf(tok::kw_template, tok::kw_using)) {
> +        Contexts.back().IsExpression = true;
> +      }
>      }
>    }
>
> diff --git a/unittests/Format/FormatTest.cpp
> b/unittests/Format/FormatTest.cpp
> index 7332fd0..a4eec3a 100644
> --- a/unittests/Format/FormatTest.cpp
> +++ b/unittests/Format/FormatTest.cpp
> @@ -4610,6 +4610,21 @@ TEST_F(FormatTest, UnderstandsRvalueReferences) {
>    verifyGoogleFormat("#define WHILE(a, b, c) while (a && (b == c))");
>  }
>
> +TEST_F(FormatTest, FormatsMultiplicationOperator) {
> +  verifyFormat("operator*(type *a)");
> +  verifyFormat("operator<<(type *a)");
> +  verifyFormat("cout << (a * b)");
> +  verifyFormat("cout << a * b");
> +  verifyFormat("x + a * b");
> +  verifyFormat("type (*f)(type *a)");
> +  verifyFormat("type (&f)(type *a)");
> +  verifyFormat("void f(type *a)");
> +  verifyFormat("using f = void (*)(a *b)");
> +  verifyFormat("template <typename T = void (*)(a *b)");
> +  verifyFormat("using f = void (c::*)(a *b)");
> +  verifyFormat("template <typename T = void (c::*)(a *b)>");
> +}
> +
>  TEST_F(FormatTest, FormatsBinaryOperatorsPrecedingEquals) {
>    verifyFormat("void f() {\n"
>                 "  x[aaaaaaaaa -\n"
> --
> 1.9.1
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140330/9055c063/attachment.html>


More information about the cfe-commits mailing list