[PATCH] D127462: [Clang] Begin implementing Plan 9 C extensions

2022-07-31 Thread Keegan Saunders via Phabricator via cfe-commits
ksaunders added a comment.

Gentle ping. I have 2 other patches ready, and I'd like to get the discussion 
started on this if possible.


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


[PATCH] D130857: [Clang] Plan 9 member resolution

2022-07-31 Thread Keegan Saunders via Phabricator via cfe-commits
ksaunders created this revision.
ksaunders added a reviewer: rsmith.
ksaunders added a project: clang.
Herald added a project: All.
ksaunders requested review of this revision.
Herald added a subscriber: cfe-commits.

This patch implements the Plan 9 member resolution algorithm which is described 
referenced in the original revision: https://reviews.llvm.org/D127462. The test 
code is illustrative as to what is considered valid, as it was derived from 
samples compiled using the Plan 9 C compiler.

It is not clear what the policy on issuing diagnostics is for extensions usage, 
so there is a warning emitted for usage of duplicated members (which is a Plan 
9 extension). However this might not be a good idea, as there could be 
potentially a large number of warnings emitted, as this is used throughout 
headers Plan 9 C.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130857

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaLookup.cpp
  clang/test/Sema/2c-anon-record.c

Index: clang/test/Sema/2c-anon-record.c
===
--- clang/test/Sema/2c-anon-record.c
+++ clang/test/Sema/2c-anon-record.c
@@ -1,9 +1,95 @@
 // RUN: %clang_cc1 %s -fsyntax-only -Wplan9 -verify -fplan9-extensions
 
-struct A {
+typedef struct {
+  int x; // expected-note {{previous declaration is here}}
+} A;
+
+struct B {
+  A;   // expected-warning {{anonymous structs are a Plan 9 extension}}
+  char *x; // expected-warning {{duplicate member 'x' is a Plan 9 extension}}
+};
+
+char *f0(struct B *b) {
+  return b->x;
+}
+
+typedef struct {
   int x;
+} C;
+
+struct D {
+  // expected-warning@+2 {{anonymous structs are a Plan 9 extension}}
+  // expected-note@+1 {{candidate found by name lookup is 'D::(anonymous)'}}
+  C;
+  int C; // expected-note {{candidate found by name lookup is 'D::C'}}
 };
 
-struct B {
-  struct A; // expected-warning {{anonymous structs are a Plan 9 extension}}
+int f1(struct D *d) {
+  int x = d->x;
+  return d->C; // expected-error {{reference to 'C' is ambiguous}}
+}
+
+typedef struct {
+  int x; // expected-note {{previous declaration is here}}
+} E;
+
+struct F {
+  E; // expected-warning {{anonymous structs are a Plan 9 extension}}
+  int x; // expected-warning {{duplicate member 'x' is a Plan 9 extension}}
+};
+
+E f2(struct F *f) {
+  int x = f->x;
+  return f->E;
+}
+
+typedef struct {
+  // expected-note@+3 {{previous declaration is here}}
+  // expected-note@+2 {{previous declaration is here}}
+  // expected-note@+1 {{candidate found by name lookup is 'H::a'}}
+  int a;
+  // expected-warning@+3 {{duplicate member 'a' is a Plan 9 extension}}
+  // expected-warning@+2 {{duplicate member 'a' is a Plan 9 extension}}
+  // expected-note@+1 {{candidate found by name lookup is 'H::a'}}
+  int a;
+} G;
+
+struct H {
+  G; // expected-warning {{anonymous structs are a Plan 9 extension}}
+  int b;
 };
+
+int f3(struct H *h) {
+  int b = h->b;
+  return h->a; // expected-error {{reference to 'a' is ambiguous}}
+}
+
+typedef union {
+  int a;
+} I;
+
+union J {
+  I; // expected-warning {{anonymous unions are a Plan 9 extension}}
+  int b : 4;
+};
+
+int f4(union J *j) {
+  int b = j->b;
+  return j->a;
+}
+
+typedef struct K TK;
+
+struct K {
+  int x;
+};
+
+struct L {
+  TK; // expected-warning {{anonymous structs are a Plan 9 extension}}
+  int l;
+};
+
+TK f5(struct L *l) {
+  struct K k = l->K; // expected-error {{no member named 'K' in 'struct L'}}
+  return l->TK;
+}
Index: clang/lib/Sema/SemaLookup.cpp
===
--- clang/lib/Sema/SemaLookup.cpp
+++ clang/lib/Sema/SemaLookup.cpp
@@ -1085,6 +1085,99 @@
   }
 }
 
+// Resolves fields in a record like a Plan 9 compiler.  The resolution
+// is performed in 3 passes:
+//
+//   Pass 1: Look for field names that match the lookup name.
+//   Pass 2: Look for unnamed embedded records who's typedef'd name
+//   match the lookup name.
+//   Pass 3: Look for candidate fields in unnamed embedded records.
+//
+// Returns true if any matches were found.
+static bool LookupPlan9(Sema &S, LookupResult &R, const RecordDecl *RD,
+const DeclContext *Owner) {
+  bool Found = false;
+
+  // Pass 1 & 2 are fused: conflicts are an error.
+  for (FieldDecl *Field : RD->fields()) {
+// Pass 1
+if (Field->getDeclName() == R.getLookupName()) {
+  R.addDecl(Field);
+  Found = true;
+}
+
+// Pass 2
+if (isa(Field->getType()) && Field->getDeclName().isEmpty()) {
+  if (const auto *Typedef =
+  Field->getTypeSourceInfo()->getType()->getAs()) {
+if (Typedef->getDecl()->getDeclName() == R.getLookupName()) {
+  R.addDecl(Field);
+  Found = true;
+}
+  }
+}
+  }
+
+  if (Found)
+return true;
+
+  LookupRes

[PATCH] D127462: [Clang] Begin implementing Plan 9 C extensions

2022-10-23 Thread Keegan Saunders via Phabricator via cfe-commits
ksaunders added a comment.

Ping.


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


[PATCH] D127462: [Clang] Begin implementing Plan 9 C extensions

2022-10-26 Thread Keegan Saunders via Phabricator via cfe-commits
ksaunders added a comment.

Thanks for your response. I am working on an RFC now which addresses your 
feedback and questions.


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


[PATCH] D127462: [Clang] Begin implementing Plan 9 C extensions

2022-06-13 Thread Keegan Saunders via Phabricator via cfe-commits
ksaunders added a comment.

Two questions for Clang developers as I work on my next patches:

1. What is the Clang policy for warnings on extension usages? For example, this 
diff permits redeclaration of typedefs, which is a Plan 9 and Microsoft C 
extension. Earlier in the file this extension is enabled for Microsoft C as 
well, however no warning is emitted. In contrast, in Microsoft C if you use an 
anonymous embedded record in Clang a warning //is emitted// for extension 
usage. So it's unclear what should be a warning and what shouldn't be.
2. //MSVC Compatibility// has its own dedicated page on the Clang documentation 
site. Should I add a page for //Plan 9 Compatibility// which details the status 
of each feature now (and can be updated in subsequent diffs)?


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


[PATCH] D127706: [Clang] Enable MSVC embedded records for Plan 9

2022-06-13 Thread Keegan Saunders via Phabricator via cfe-commits
ksaunders created this revision.
ksaunders added a reviewer: rsmith.
ksaunders added a project: clang.
Herald added a project: All.
ksaunders requested review of this revision.
Herald added a subscriber: cfe-commits.

This diff enables MSVC embedded records when Plan 9 extensions are enabled. As 
well, it creates the Plan 9 warning group.

Please see the initial Plan 9 diff for more details about this extension and 
more: https://reviews.llvm.org/D127462.

Aside: It's not clear if Clang developers prefer these incremental diffs, or 
one big diff. Let me know.

Depends On: https://reviews.llvm.org/D127462


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D127706

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/2c-anon-record.c


Index: clang/test/Sema/2c-anon-record.c
===
--- /dev/null
+++ clang/test/Sema/2c-anon-record.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wplan9 -verify -fplan9-extensions
+
+struct A {
+  int x;
+};
+
+struct B {
+  struct A; // expected-warning {{anonymous structs are a Plan 9 extension}}
+};
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -4989,8 +4989,10 @@
   else if (const RecordType *UT = 
DS.getRepAsType().get()->getAsUnionType())
 Record = UT->getDecl();
 
-  if (Record && getLangOpts().MicrosoftExt) {
-Diag(DS.getBeginLoc(), diag::ext_ms_anonymous_record)
+  if (Record && (getLangOpts().MicrosoftExt || getLangOpts().Plan9)) {
+Diag(DS.getBeginLoc(), getLangOpts().MicrosoftExt
+   ? diag::ext_ms_anonymous_record
+   : diag::ext_plan9_anonymous_record)
 << Record->isUnion() << DS.getSourceRange();
 return BuildMicrosoftCAnonymousStruct(S, DS, Record);
   }
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9011,6 +9011,9 @@
 def ext_ms_anonymous_record : ExtWarn<
   "anonymous %select{structs|unions}0 are a Microsoft extension">,
   InGroup;
+def ext_plan9_anonymous_record : ExtWarn<
+  "anonymous %select{structs|unions}0 are a Plan 9 extension">,
+  InGroup;
 
 // C++ local classes
 def err_reference_to_local_in_enclosing_context : Error<
Index: clang/include/clang/Basic/DiagnosticGroups.td
===
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -1133,6 +1133,12 @@
 // A warning group for warnings about code that may be incompatible on AIX.
 def AIXCompat : DiagGroup<"aix-compat">;
 
+// Warnings for Plan 9 extensions.
+def Plan9AnonTag : DiagGroup<"plan9-anon-tag">;
+
+// Warnings group for warnings about Plan 9 extensions.
+def Plan9 : DiagGroup<"plan9", [Plan9AnonTag]>;
+
 // Warnings for Microsoft extensions.
 def MicrosoftCharize : DiagGroup<"microsoft-charize">;
 def MicrosoftDrectveSection : DiagGroup<"microsoft-drectve-section">;


Index: clang/test/Sema/2c-anon-record.c
===
--- /dev/null
+++ clang/test/Sema/2c-anon-record.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wplan9 -verify -fplan9-extensions
+
+struct A {
+  int x;
+};
+
+struct B {
+  struct A; // expected-warning {{anonymous structs are a Plan 9 extension}}
+};
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -4989,8 +4989,10 @@
   else if (const RecordType *UT = DS.getRepAsType().get()->getAsUnionType())
 Record = UT->getDecl();
 
-  if (Record && getLangOpts().MicrosoftExt) {
-Diag(DS.getBeginLoc(), diag::ext_ms_anonymous_record)
+  if (Record && (getLangOpts().MicrosoftExt || getLangOpts().Plan9)) {
+Diag(DS.getBeginLoc(), getLangOpts().MicrosoftExt
+   ? diag::ext_ms_anonymous_record
+   : diag::ext_plan9_anonymous_record)
 << Record->isUnion() << DS.getSourceRange();
 return BuildMicrosoftCAnonymousStruct(S, DS, Record);
   }
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9011,6 +9011,9 @@
 def ext_ms_anonymous_record : ExtWarn<
   "anonymous %select{structs|unions}0 are a Microsoft extension">,
   InGroup;
+def ext_plan9_anonymous_record : ExtWarn<
+  "anonymous %select{struc

[PATCH] D127462: Begin implementing Plan 9 C extensions [V2]

2022-06-09 Thread Keegan Saunders via Phabricator via cfe-commits
ksaunders created this revision.
ksaunders added a reviewer: rsmith.
ksaunders added a project: clang.
Herald added a project: All.
ksaunders requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.

This patch enables the addition of extensions supported by the Plan 9 C 
compilers by adding the -fplan9-extensions flag.

This flag currently enables 1 extension: allowing typedefs to be declared 
multiple times like in C11. Once merged, I have plans to implement the 
following Plan 9 C compiler behavior, as covered below.

Plan 9 C compilers can be summarized as a C89 compiler with the following 
non-standard extensions enabled:

- Embedded structures, like Microsoft C (already implemented in Clang with 
-fms-extensions)
- Automatic embedded structure type decay
- Embedded structure type name accesses

As well as the following standardized C extensions enabled:

- C99 compound literals
- C99 designated initializers for arrays and structures
- C11 redeclaration of typedefs
- C11 anonymous structures and unions
- C2x omitting the parameter name in a function definition

A description of these extensions can be found in the //How to Use the Plan 9 C 
Compiler// paper by Rob Pike: https://9p.io/sys/doc/comp.html. However, there 
are no plans to implement the "extern register" feature, which is used in the 
kernel.

The motivation for this patch, and the patches that follow, are to enable the 
compilation of the Plan 9 kernel C source and Plan 9 userspace applications 
with Clang for the purpose of increased code optimizations and sanitizer 
instrumentation. In this respect, GCC support is inadequate, as it does not 
support the member resolution algorithm used in the Plan 9 C compilers to 
reconcile overlapping declaration names in a record.

This patch is largely based off of the following obsolete patch by @pcc: 
https://reviews.llvm.org/D3853.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D127462

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/c11-typedef-redef.c


Index: clang/test/Sema/c11-typedef-redef.c
===
--- clang/test/Sema/c11-typedef-redef.c
+++ clang/test/Sema/c11-typedef-redef.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c11 %s -verify
+// RUN: %clang_cc1 -fplan9-extensions %s -verify
 
 typedef int type;
 typedef type type;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -2560,8 +2560,8 @@
 return New->setInvalidDecl();
   }
 
-  // Modules always permit redefinition of typedefs, as does C11.
-  if (getLangOpts().Modules || getLangOpts().C11)
+  // Modules always permit redefinition of typedefs, as do C11 and Plan 9.
+  if (getLangOpts().Modules || getLangOpts().C11 || getLangOpts().Plan9)
 return;
 
   // If we have a redefinition of a typedef in C, emit a warning.  This warning
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -6495,6 +6495,9 @@
   Args.addOptInFlag(CmdArgs, options::OPT_fborland_extensions,
 options::OPT_fno_borland_extensions);
 
+  Args.addOptInFlag(CmdArgs, options::OPT_fplan9_extensions,
+options::OPT_fno_plan9_extensions);
+
   // -fno-declspec is default, except for PS4/PS5.
   if (Args.hasFlag(options::OPT_fdeclspec, options::OPT_fno_declspec,
RawTriple.isPS()))
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1343,6 +1343,10 @@
   LangOpts<"Borland">, DefaultFalse,
   PosFlag,
   NegFlag>;
+defm plan9_extensions : BoolFOption<"plan9-extensions",
+  LangOpts<"Plan9">, DefaultFalse,
+  PosFlag,
+  NegFlag>;
 def fbuiltin : Flag<["-"], "fbuiltin">, Group, Flags<[CoreOption]>;
 def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group,
   Flags<[NoXarchOption]>, HelpText<"Load the clang builtins module map file.">;
Index: clang/include/clang/Basic/LangOptions.def
===
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -92,6 +92,7 @@
 LANGOPT(MicrosoftExt  , 1, 0, "Microsoft C++ extensions")
 LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
 LANGOPT(Borland   , 1, 0, "Borland extensions")
+LANGOPT(Plan9 , 1, 0, "Plan 9 extensions")
 LANGOPT(CPlusPlus , 1, 0, "C++")
 LANGOPT(CPlusPlus11   , 1, 0, "C++11")
 LANGOPT(CPlusPlus14   , 1, 0, "C++14")


Index: clang/test/Sema/c11-typedef-redef.

[PATCH] D127462: [Clang] Begin implementing Plan 9 C extensions

2022-11-19 Thread Keegan Saunders via Phabricator via cfe-commits
ksaunders added a comment.

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.

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.

---

I think it also makes sense to address your questions here for the sake of 
completeness.

> 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.

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.

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 
) 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


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


[PATCH] D127462: [Clang] Begin implementing Plan 9 C extensions

2022-11-24 Thread Keegan Saunders via Phabricator via cfe-commits
ksaunders added a comment.

> 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?

A lot of the Plan 9 extensions were actually adopted by C99 like compound 
literals and anonymous structures. Although I find these additional extensions 
interesting and useful, I don't think that they belong in C and they should 
remain as non-standard extensions. My interests lie in compiling existing code 
with Clang which utilizes these extensions, rather than encouraging new code to 
utilize them.

There was actually a proposal to add Plan 9 extensions into the Linux kernel, 
but Linus rejected it. I personally share his opinion that the silent type 
conversion that the Plan 9 compilers introduce can be problematic. But on the 
other hand, they are also very powerful when used judiciously. It's on the LKML 
here if you're interested: https://lkml.org/lkml/2019/1/9/1127

> 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?

Good question. The compilers only allow one member of the underlying type. So 
you'll get an error saying you've declared `Lock` twice.

> Also, why does it require a typedef name?

I am not sure, but I presume it is because of cases like this:

  struct A
  {
  int a;
  };
  
  struct B
  {
  int b;
  };
  
  typedef struct B A;
  
  struct Example
  {
  struct A;
  A;
  };

So it's not clear when you do `example->A` which member you are referring to. 
If you restrict it to typedef names then you have no ambiguity of this kind.

> 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?

It only searches for //unnamed// structure and union members, so non-record 
members like bit-fields are not used for resolution. That's a good test case I 
should add as well, yeah.

> Thanks for the extra details!

Thank you for your interest :)


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