aaron.ballman added a comment. In D127462#3939243 <https://reviews.llvm.org/D127462#3939243>, @ksaunders wrote:
> Hi Aaron. Unfortunately, I don't feel I can make a great case for why these > extensions should be in Clang. Although there are users of Plan 9 C > extensions, I don't see these features being adopted more generally enough to > warrant its inclusion in Clang which violates the inclusion policy. Just to check -- do you think (some of) these features are something you wish to propose to WG14 for adoption into C? e.g., are you aiming to get multiple compilers to implement Plan 9 extensions to demonstrate to WG14 that this is existing practice in C compilers? > To this effect, I tried using libTooling to rewrite Plan 9 C to standard C > that can be correctly compiled with Clang, but because the AST creation > requires semantic analysis to run it leaves the AST in a state of disrepair > (it can parse Plan 9 C, but the analyzer gets confused with duplicate fields > and so on). > > I'll have to decide if I am going to keep these changes in a Clang fork or > modify another C compiler for LLVM. Regardless, I believe my diffs for adding > the Plan 9 calling convention to LLVM still apply (they are simple), so I > will send them upstream when I feel they are ready. SGTM > --- > > I think it also makes sense to address your questions here for the sake of > completeness. Thank you, I appreciate the education. :-) >> I'm wondering if you could go into a bit more detail about what Automatic >> embedded structure type decay and Embedded structure type name accesses mean >> in practice (some code examples would be helpful). > > Absolutely. "Automatic embedded structure type decay" and "Embedded structure > type name accesses" are features best described by example: > > typedef struct Lock Lock; > typedef struct Rc Rc; > typedef struct Resource Resource; > > struct Lock > { > int hold; > }; > > struct Rc > { > int references; > }: > > struct Resource > { > Rc; > Lock; > void *buffer; > size_t size; > }; > > Now with "Embedded structure type name accesses" enabled, if we have a value > like `Resource *r`, we can do `r->Lock`. This simply returns the field as if > `Lock;` was declared as `Lock Lock;`, but this special declaration also > brings all names into scope (like an anonymous struct) so we can do > `r->hold`. This also does NOT work if you declare the field as `struct > Lock;`, it must be a typedef name. What an interesting extension! What happens with something like this? typedef struct Lock FirstLock; typedef struct Lock SecondLock; typedef struct Rc Rc; typedef struct Resource Resource; struct Lock { int hold; }; struct Rc { int references; }; struct Resource { Rc; FirstLock; SecondLock; void *buffer; size_t size; }; Does this work for accessing `r->FirstLock` but give an ambiguous lookup for `r->hold`? Or do you only allow one member of the underlying canonical type? Also, why does it require a typedef name? > Further, with "Automatic embedded structure type decay" structure pointers > are automatically converted into an access of an embedded compatible > structure. So we have a function like: `void lock(Lock *);` we can call it > with `lock(r);` and the compiler will automatically search all unnamed > structures in `Resource` recursively until it finds a matching type. Note > that `Lock;` is declared after `Rc;`, this is intentional. In standard C it > is possible to have a pointer to a struct declay to a pointer to the first > field in the struct. That is completely separate from this extension. Ah, interesting. So this is another case where multiple members of the same type would be a problem. Does this only find structure/union members, or does this also work for other members? e.g. `void size(size_t *)` being called with `lock(r)`? And if it works for other members... what does it do for bit-field members which share an allocation unit? > If that was unclear, GCC also supports this functionality and it is > documented here for a different explanation: > https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html > >> Are you planning to add a new driver for Clang to emulate the Plan 9 >> compiler driver (similar to how we have a driver for MSVC compatibility)? > > For now, no. > > Adding the Plan 9 object format to LLD is out-of-scope for this project (this > was discussed previously > <https://discourse.llvm.org/t/plan-9-a-out-executables-with-lld/61438>) so I > don't think it's necessary to add a new driver, we can just use the generic > ELF driver. > > Similarly, adding the Plan 9 assembler syntax is not necessary either as most > programs are C so the assembler can be trivially converted as the idea is > that programs will be compiled with the Plan 9 calling convention and C ABI. > >> Are there other extensions planned, or is the list in the summary pretty >> complete? > > No, the listing above is complete. > >> Do I understand correctly that plan 9 compatibility mode forces C89 as the >> language standard mode, or is it expected that users can do things like >> -std=c2x -fplan9-extensions? > > Plan 9 C extensions are not mutually exclusive with C2x so I think that you > should be allowed to write C2x Plan 9 C. If we did have a Plan 9 driver > though, it would set `-fplan9-extensions -std=c89` to be as close as possible > to the Plan 9 compilers functionality. > > Cheers Thanks for the extra details! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D127462/new/ https://reviews.llvm.org/D127462 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits