sammccall added a comment.

Thanks, this all looks good, at least as far as I understand it! The 
two-passes-over-the-whole-file approach is easier for me to follow, too.

Mostly just comment nits, but I have one annoying question left about using 
macros with the wrong arity - I thought this was just an implementation 
limitation, but it sounds like you want it to be a feature, so I'd like to nail 
it down a little...



================
Comment at: clang/include/clang/Format/Format.h:2750
+  ///
+  /// Code will be parsed with macros expanded, and formatting will try to best
+  /// match the structure of the expanded call.
----------------
I find "try to match the structure of the expanded call" a bit hard to follow 
from a user perspective.

Maybe "Code will be parsed with macros expanded, in order to determine how to 
interpret and format the macro arguments"?


================
Comment at: clang/include/clang/Format/Format.h:2753
+  ///
+  /// For example, with the macro "A(x)=x", the code
+  /// \code
----------------
This is a good example. I think you should spell out both sides, and probably 
start with the simpler case (no macro definition) to motivate the problem.

```
For example, the code:
  A(a*b);
will usually be interpreted as a call to a function A, and the multiplication 
expression will be formatted as `a * b`.

If we specify the macro definition:
  Macros:
    - A(x)=x

the code will now be parsed as a declaration of the variable b of type a*,
and formatted as `a* b` (depending on pointer-binding rules).
```


================
Comment at: clang/include/clang/Format/Format.h:2757
+  /// \endcode
+  /// will be formatted as a declaration of the variable \c b of type \c A*
+  /// (depending on pointer-binding rules)
----------------
type a*, not A*


================
Comment at: clang/include/clang/Format/Format.h:2762
+  /// \endcode
+  /// instead of as multiplication.
+  std::vector<std::string> Macros;
----------------
I think the restrictions should be spelled out here: object-like and 
function-like macros are both supported, macro args should be used exactly 
once, macros should not reference other macros.


================
Comment at: clang/lib/Format/UnwrappedLineParser.cpp:225
+      }
+      Callback.finishRun();
+    }
----------------
klimek wrote:
> sammccall wrote:
> > I'm sure you got this right, but it's hard for me to evaluate this code 
> > because I don't know what `UnwrappedLineConsumer::finishRun()` is for - 
> > it's not documented and the implementation is mysterious.
> > 
> > You might consider adding a comment to that interface/method, it's not 
> > really related to this change though.
> Done. Not sure I've put too much info about how it's going to be used into 
> the interface, where it doesn't really belong.
Thanks, comment seems just right to me.


================
Comment at: clang/lib/Format/UnwrappedLineParser.h:88
+/// - for different combinations of #if blocks
+/// - for code where macros are expanded and the code with the original
+///   macro calls.
----------------
this is a bit of a garden path sentence: `for code where ((macros are expanded) 
and (the code with (the original macro calls) ... ERR_MISSING_PREDICATE))`

maybe `when macros are involved, for the expanded code and the as-written code`?


================
Comment at: clang/lib/Format/UnwrappedLineParser.h:260
+  // was expanded from a macro call.
+  bool containsExpansion(const UnwrappedLine &Line);
+
----------------
nit: should these added functions be const?

(maybe this class doesn't bother with const - computePPHash is const though)


================
Comment at: clang/unittests/Format/FormatTest.cpp:22584
+  Style.Macros.push_back("CALL(x)=f([] { x })");
+  Style.Macros.push_back("ASSIGN_OR_RETURN(a, b, c)=a = (b) || (c)");
+
----------------
klimek wrote:
> sammccall wrote:
> > If this is assign_or_return, the treatment of "c" is fairly strange. Also 
> > you are mostly calling this with only two args. Maybe drop C and use a 
> > different macro for the 3-arg case?
> ASSIGN_OR_RETURN allows 3 args, though; this is basically the thing I'd 
> propose to configure for ASSIGN_OR_RETURN in general; is there anything 
> specific you don't like about this?
OK, this is a bit sticky.
 - `ASSIGN_OR_RETURN` is almost always called with two args
 - some versions of `ASSIGN_OR_RETURN` support an optional third arg (there's 
no canonical public version)
 - these emulate overloading using variadic macro tricks
 - this patch doesn't claim to support either variadic macros or overloading

So the principled options seem to be:
 - macros have fixed arity: clang-format can support the two-arg version of 
`ASSIGN_OR_RETURN` but not the three-arg version. (This is what I was assuming)
 - macros have variable arity: the public docs need to describe how passing too 
many/too few args is treated, because this isn't obvious and it sounds like we 
want people to rely on it. This feels like stretching "principled" to me - 
we're relying on the expansion still parsing correctly when args are missing, 
which basically seems like coincidence.
 - macros support overloading: instead of looking up macros by name, the key is 
`(string Name, optional<int> Arity)`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144170/new/

https://reviews.llvm.org/D144170

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to