erichkeane added inline comments.

================
Comment at: clang/docs/LanguageExtensions.rst:2434
+
+     bool print(int arg1, int arg2, std::initializer_list<Field> fields) {
+       for (auto f : fields) {
----------------
rsmith wrote:
> erichkeane wrote:
> > rsmith wrote:
> > > erichkeane wrote:
> > > > I'm curious as to the need for the 'arg1' and 'arg2'?  Also, what is 
> > > > the type of the 'fields' array that works in C?
> > > This is aimed to fix a major deficiency in `__builtin_dump_struct`, that 
> > > there's no way to pass information into its callback (other than stashing 
> > > it in TLS).
> > > 
> > > As noted in the patch description, this builtin is not especially usable 
> > > in C. I'm not sure whether that's fixable, given the very limited 
> > > metaprogramming support in C.
> > Presumably one could also put it in the functor for the callback, or even 
> > as a capture in the lambda.  Though, I'm not positive I see the VALUE to 
> > passing this information, but was just curious as to the intent.
> Suppose you want to dump a struct to a log file, or you want the dump in a 
> string. Or you want to carry along an indentation level. My first attempt at 
> using `__builtin_dump_struct` essentially failed because it doesn't have 
> anything like this; even if we don't want this patch, this is functionality 
> we should add to that builtin.
Ah, I see!  Sure, I can see how those are useful, though again, mostly to the C 
implementation (as those should all be part of the functor's state), and this 
doesn't work particularly well in C.


================
Comment at: clang/docs/LanguageExtensions.rst:2462
+to the type to reflect. The second argument ``f`` should be some callable
+expression, and can be a function object or an overload set. The builtin calls
+``f``, passing any further arguments ``args...`` followed by an initializer
----------------
rsmith wrote:
> erichkeane wrote:
> > rsmith wrote:
> > > erichkeane wrote:
> > > > Is the purpose of the overload set/functor so you can support multiple 
> > > > types (seeing how the 'base' below works)?  How does this all work in 
> > > > C? (or do we just do fields in C, since they cannot have the rest?
> > > > 
> > > > I wonder if we would be better if we treated this function as a 
> > > > 'callback' or a 'callback set' that returned a discriminated union of a 
> > > > pre-defined type that describes what is being returned.  That way it 
> > > > could handle member functions, static variables, etc.
> > > This doesn't really work well in C, as noted in the patch description. A 
> > > set of callbacks might work a bit better across both languages, but I 
> > > don't think it solves the larger problem that there's no good way to pass 
> > > type information into a callback in C.
> > Well, if the callback itself took the discriminated union for each thing, 
> > and we did 1 callback per base/field/etc, perhaps that would be useful? I 
> > just am having a hard time seeing this being all that useful in C, which is 
> > a shame.
> > 
> > 
> I think that would work. I'm not sure it would be better, though, given that 
> it loses the ability to build a type whose shape depends on the number of 
> bases and fields, because you're not given them all at once. (Eg, if you want 
> to build a static array of field names.)
Yep, thats definitely true. There are ways to DO that (either a 2-pass at this 
to get the sizes, allocate something, then go through again filling in your 
struct OR a constant 'append' thing with a `vector` like type), but I see what 
you mean.  It seems that either case we are limiting a couple of useful use 
cases.


================
Comment at: clang/docs/LanguageExtensions.rst:2473
+
+* For each direct base class, the address of the base class, in declaration
+  order.
----------------
rsmith wrote:
> erichkeane wrote:
> > rsmith wrote:
> > > erichkeane wrote:
> > > > I wonder if bases should include their virtualness or access specifier.
> > > I mean, maybe, but I don't have a use case for either. For access in 
> > > general my leaning is to say that the built-in doesn't get special access 
> > > rights -- either it can access everything or you'll get an access error 
> > > if you use it -- in which case including the access for bases and fields 
> > > doesn't seem likely to be super useful.
> > I guess it depends on the use case for these builtins.  I saw the 
> > 'dump-struct' builtin's purpose was for quick & dirty printf-debugging.  At 
> > which point the format/features were less important than the action.  So 
> > from that perspective, I would see this having 'special access rights' as 
> > sort of a necessity.  
> > 
> > Though again, this is a significantly more general builtin, which comes 
> > with additional potential use cases.
> The use cases are the things that `__builtin_dump_struct` gets close to but 
> fails at, such as: I have an `EXPECT_EQ` macro that I'd like to log the 
> difference in input and output values where possible, or I want to build a 
> simple print-to-string utility for structs. Or I want a dump to stout but I 
> want it formatted differently from what `__builtin_dump_struct` thinks is 
> best.
> 
> The fact that the dump built-in gets us into this area but can't solve these 
> problems is frustrating.
>>The use cases are the things that __builtin_dump_struct gets close to but 
>>fails at, such as: I have an EXPECT_EQ macro that I'd like to log the 
>>difference in input and output values where possible

THAT is an interesting use case, I see value to that too.

>>The fact that the dump built-in gets us into this area but can't solve these 
>>problems is frustrating.

I definitely see that. FWIW, I don't think I was the one to approve/review the 
initial version of `__builtin_dump_struct` (and perhaps would have been equally 
frustrated if I thought that through), but was looking into the patches after 
the fact to help out.

I guess I find myself equally/additionally/etc frustrated at THIS patch because 
it gets us so close to everything SG7 promises they can invent.


================
Comment at: clang/lib/Sema/SemaChecking.cpp:420
+    auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
+    if (!FD || (FD->isUnnamedBitfield() || FD->isAnonymousStructOrUnion()))
+      continue;
----------------
rsmith wrote:
> erichkeane wrote:
> > rsmith wrote:
> > > erichkeane wrote:
> > > > Losing the unnamed bitfield is unfortunate, and I the 'dump struct' 
> > > > handles.  As is losing the anonymous struct/union.
> > > > 
> > > > Also, how does this handle 'record type' members?  Does the user have 
> > > > to know the inner type already?  If they already know that much 
> > > > information about the type, they wouldn't really need this, right?
> > > If `__builtin_dump_struct` includes unnamed bitfields, that's a bug in 
> > > that builtin.
> > > 
> > > In general, the user function gets given the bases and members with the 
> > > right types, so they can use an overload set or a template to dispatch 
> > > based on that type. See the SemaCXX test for a basic example of that.
> > I thought it did?  For the use case I see `__builtin_dump_struct` having, I 
> > would think printing the existence of unnamed bitfields to be quite useful.
> > 
> > 
> Why? They're not part of the value, they're just padding.
They are lexically part of the type and are part of what makes up the 'size' of 
the thing. I would expect something dumping the type to be as consistent 
lexically as possible.


================
Comment at: clang/lib/Sema/SemaChecking.cpp:420
+    auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
+    if (!FD || (FD->isUnnamedBitfield() || FD->isAnonymousStructOrUnion()))
+      continue;
----------------
rsmith wrote:
> erichkeane wrote:
> > rsmith wrote:
> > > erichkeane wrote:
> > > > rsmith wrote:
> > > > > erichkeane wrote:
> > > > > > Losing the unnamed bitfield is unfortunate, and I the 'dump struct' 
> > > > > > handles.  As is losing the anonymous struct/union.
> > > > > > 
> > > > > > Also, how does this handle 'record type' members?  Does the user 
> > > > > > have to know the inner type already?  If they already know that 
> > > > > > much information about the type, they wouldn't really need this, 
> > > > > > right?
> > > > > If `__builtin_dump_struct` includes unnamed bitfields, that's a bug 
> > > > > in that builtin.
> > > > > 
> > > > > In general, the user function gets given the bases and members with 
> > > > > the right types, so they can use an overload set or a template to 
> > > > > dispatch based on that type. See the SemaCXX test for a basic example 
> > > > > of that.
> > > > I thought it did?  For the use case I see `__builtin_dump_struct` 
> > > > having, I would think printing the existence of unnamed bitfields to be 
> > > > quite useful.
> > > > 
> > > > 
> > > Why? They're not part of the value, they're just padding.
> > They are lexically part of the type and are part of what makes up the 
> > 'size' of the thing. I would expect something dumping the type to be as 
> > consistent lexically as possible.
> Looks like `__builtin_dump_struct` currently includes them *and* prints a 
> value (whatever garbage happens to be in those padding bits). That's 
> obviously a bug.
O.o! Yeah, printing the value is nonsense.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D124221

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

Reply via email to