[PATCH] D126691: ASTContext: Provide a query for module initializer contents.

2023-10-03 Thread Iain Sandoe via Phabricator via cfe-commits
iains abandoned this revision.
iains added a comment.

although this was approved, we did not need to use it to implement the 
dependent changes.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126691

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


[PATCH] D126694: [C++20][Modules] Implementation of GMF decl elision.

2023-07-04 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D126694#4470297 , @ChuanqiXu wrote:

>> Yes, that was the decision at the last time we looked - because removing 
>> decls would degrade this - if we have new information that changes our 
>> preferred design, then fine.
>
> I remember the major reason for the last time to not remove the decls are 
> that the design of AST doesn't support to remove decls. And my current idea 
> is, we can refuse to write the discardable Decls into the BMIs.

@rsmith pointed out that the API was not intended for that purpose - so, yes, 
you are correct that the next place to look was in the serialisation [but ISTR 
that this also has some challenges because of the way in which the structures 
are interconnected].  It might be necessary to do a pass before the 
serialisation and actually prune the AST there. (in a similar manner we'd need 
to prune it to remove non-inline function bodies in some future version)

>> One solution is to place the elision behind a flag so that the user can 
>> choose slower compilation with better diagnostics or faster compilation but 
>> maybe harder-to-find errors?
>
> I proposed to add a flag. But that was a helper for developers to find if we 
> did anything wrong. I don't want to provide such a flag since on the one 
> hand, there are already many flags  and on the other hand, form my user 
> experience, it is not so hard to find the unexported decls. It is really much 
> much more easier than template programming.

Yeah, (as you know) I definitely prefer not to add more flags - there are too 
many - it was only an option in case there were many people against degrading 
diagnostic output.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126694

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


[PATCH] D126694: [C++20][Modules] Implementation of GMF decl elision.

2023-07-03 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D126694#4470261 , @ChuanqiXu wrote:

>> That is clearly a big motivation - I will ask the folks we were talking to 
>> at WG21 if that is their priority - or maybe they care about language 
>> isolation etc.
>
> Yeah, I know the folks in WG21 prefer the language isolation. But you know, 
> there are many folks who are not in WG21...

indeed :)

> Oh, the thing I want to say, in this case we have a chance to improve the 
> compilation speed significantly and the so called diagnose quality became a 
> blocker for us. Also it is beneficial to remove them out of the BMI to 
> improve the language isolation feature.

Yes, that was the decision at the last time we looked - because removing decls 
would degrade this - if we have new information that changes our preferred 
design, then fine.  
One solution is to place the elision behind a flag so that the user can choose 
slower compilation with better diagnostics or faster compilation but maybe 
harder-to-find errors?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126694

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


[PATCH] D126694: [C++20][Modules] Implementation of GMF decl elision.

2023-07-03 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D126694#4470250 , @ChuanqiXu wrote:

> BTW, in my experience for talking about modules to users, they mainly/mostly 
> care about the compilation performance. And I can't image how many people 
> would like to use modules if they know they won't get a compilation 
> performance win.

That is clearly a big motivation - I will ask the folks we were talking to at 
WG21 if that is their priority - or maybe they care about language isolation 
etc.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126694

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


[PATCH] D126694: [C++20][Modules] Implementation of GMF decl elision.

2023-07-03 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D126694#4470139 , @ChuanqiXu wrote:

> Now I think the feature may be important for the performance of modules. And 
> I feel we should work on the ASTWriter side instead of ASTReader side. Since 
> the size of BMIs is a problem now also it shows that it is not free to load 
> the large BMIs. So while it is semantical correct to work on the reader side, 
> it is better for the performance to work on the writer side.
>
> I'd like to finish the idea. And for the current patch, I'd like to refactor 
> it a little bit:
>
> 1. Test it by unittest instead of by matching the dump result.

fine with me

> 2. Remove the Serialization part. So it will be a NFC patch.

how do you plan to identify "elided" decls (we agreed to leave them in the BMI 
to keep diagnostics quality up, but we need to be able to ignore them)

> 3. Some other trivial polishment.



4. I wanted to take another look at using visitors to implement the checks.

> Of course, I'll still mark you as the author.
>
> How do you feel about this?

Do you plan to try this before clang-17?
 (if so, then go ahead - my next priority for 17 is the lookup bug)

Otherwise, this is on my TODO for clang-18.

BTW, I think that there are other opportunities to reduce the BMI size that we 
could realistically aim for clang-18
 (but let us make that discussion separately from this patch)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126694

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-07-01 Thread Iain Sandoe via Phabricator via cfe-commits
iains planned changes to this revision.
iains added a comment.

changes are needed to address review comments - but this revision is needed as 
a parent to other work (so might need to be rebased from time to time)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-07-01 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 536524.
iains added a comment.

rebased, fixed some format issues; again to support p1815 work only.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Lookup.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaLookup.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CXX/module/module.import/p2.cpp
  clang/test/CXX/module/module.interface/p2.cpp
  clang/test/CXX/module/module.interface/p7.cpp
  clang/test/CXX/module/module.reach/ex1.cpp
  clang/test/CXX/module/module.reach/p2.cpp
  clang/test/CXX/module/module.reach/p5.cpp
  clang/test/Modules/Reachability-template-default-arg.cpp
  clang/test/Modules/cxx20-10-1-ex2.cpp
  clang/test/Modules/deduction-guide3.cppm
  clang/test/Modules/diagnose-missing-import.m
  clang/test/Modules/pr61601.cpp

Index: clang/test/Modules/pr61601.cpp
===
--- /dev/null
+++ clang/test/Modules/pr61601.cpp
@@ -0,0 +1,30 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// All of the following should build without diagnostics.
+//
+// RUN: %clang_cc1 -std=c++20 %t/Part1.cpp -emit-module-interface -o %t/TheMod-Part1.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/Part2.cpp -emit-module-interface -o %t/TheMod-Part2.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/TheMod.cpp -emit-module-interface -o %t/TheMod.pcm \
+// RUN: -fprebuilt-module-path=%t
+
+//--- Part1.cpp
+
+export module TheMod:Part1;
+static int loog = 1;
+
+//--- Part2.cpp
+
+export module TheMod:Part2;
+static int loog = 2;
+
+//--- TheMod.cpp
+
+export module TheMod;
+export import :Part1;
+export import :Part2;
+
+static int loog = 3;
+export int V = loog;
Index: clang/test/Modules/diagnose-missing-import.m
===
--- clang/test/Modules/diagnose-missing-import.m
+++ clang/test/Modules/diagnose-missing-import.m
@@ -6,9 +6,9 @@
 
 void foo(void) {
   XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \
-  expected-error {{declaration of 'XYZLogEvent' must be imported}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
+  expected-error {{declaration of 'XYZLogEvent' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}}
 }
 
 // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
Index: clang/test/Modules/deduction-guide3.cppm
===
--- clang/test/Modules/deduction-guide3.cppm
+++ clang/test/Modules/deduction-guide3.cppm
@@ -19,8 +19,8 @@
 //--- Use.cpp
 import Templ;
 void func() {
-Templ t(5); // expected-error {{declaration of 'Templ' must be imported from module 'Templ' before it is required}}
+Templ t(5); // expected-error {{declaration of 'Templ' is private to module 'Templ'}}
 // expected-error@-1 {{unknown type name 'Templ'}}
-// expected-n...@templ.cppm:3 {{declaration here is not visible}}
+// expected-n...@templ.cppm:3 {{export the declaration to make it available}}
 }
 
Index: clang/test/Modules/cxx20-10-1-ex2.cpp
===
--- clang/test/Modules/cxx20-10-1-ex2.cpp
+++ clang/test/Modules/cxx20-10-1-ex2.cpp
@@ -54,8 +54,8 @@
 //--- std10-1-ex2-tu6.cpp
 import B;
 // error, n is module-local and this is not a module.
-int &c = n; // expected-error {{declaration of 'n' must be imported}}
-// expected-note@* {{declaration here is not visible}}
+int &c = n; // expected-error {{declaration of 'n' is private to module 'B'}}
+// expected-note@* {{export the declaration to make it available}}
 
 //--- std10-1-ex2-tu7.cpp
 // expected-no-diagnostics
Index: clang/test/Modules/Reachability-template-default-arg.cpp
===
--- clang/test/Mo

[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-06-30 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 536457.
iains added a comment.

just rebased to support p1815 work


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Lookup.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaLookup.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CXX/module/module.import/p2.cpp
  clang/test/CXX/module/module.interface/p2.cpp
  clang/test/CXX/module/module.interface/p7.cpp
  clang/test/CXX/module/module.reach/ex1.cpp
  clang/test/CXX/module/module.reach/p2.cpp
  clang/test/CXX/module/module.reach/p5.cpp
  clang/test/Modules/Reachability-template-default-arg.cpp
  clang/test/Modules/cxx20-10-1-ex2.cpp
  clang/test/Modules/deduction-guide3.cppm
  clang/test/Modules/diagnose-missing-import.m
  clang/test/Modules/pr61601.cpp

Index: clang/test/Modules/pr61601.cpp
===
--- /dev/null
+++ clang/test/Modules/pr61601.cpp
@@ -0,0 +1,30 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// All of the following should build without diagnostics.
+//
+// RUN: %clang_cc1 -std=c++20 %t/Part1.cpp -emit-module-interface -o %t/TheMod-Part1.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/Part2.cpp -emit-module-interface -o %t/TheMod-Part2.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/TheMod.cpp -emit-module-interface -o %t/TheMod.pcm \
+// RUN: -fprebuilt-module-path=%t
+
+//--- Part1.cpp
+
+export module TheMod:Part1;
+static int loog = 1;
+
+//--- Part2.cpp
+
+export module TheMod:Part2;
+static int loog = 2;
+
+//--- TheMod.cpp
+
+export module TheMod;
+export import :Part1;
+export import :Part2;
+
+static int loog = 3;
+export int V = loog;
Index: clang/test/Modules/diagnose-missing-import.m
===
--- clang/test/Modules/diagnose-missing-import.m
+++ clang/test/Modules/diagnose-missing-import.m
@@ -6,9 +6,9 @@
 
 void foo(void) {
   XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \
-  expected-error {{declaration of 'XYZLogEvent' must be imported}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
+  expected-error {{declaration of 'XYZLogEvent' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}}
 }
 
 // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
Index: clang/test/Modules/deduction-guide3.cppm
===
--- clang/test/Modules/deduction-guide3.cppm
+++ clang/test/Modules/deduction-guide3.cppm
@@ -19,8 +19,8 @@
 //--- Use.cpp
 import Templ;
 void func() {
-Templ t(5); // expected-error {{declaration of 'Templ' must be imported from module 'Templ' before it is required}}
+Templ t(5); // expected-error {{declaration of 'Templ' is private to module 'Templ'}}
 // expected-error@-1 {{unknown type name 'Templ'}}
-// expected-n...@templ.cppm:3 {{declaration here is not visible}}
+// expected-n...@templ.cppm:3 {{export the declaration to make it available}}
 }
 
Index: clang/test/Modules/cxx20-10-1-ex2.cpp
===
--- clang/test/Modules/cxx20-10-1-ex2.cpp
+++ clang/test/Modules/cxx20-10-1-ex2.cpp
@@ -54,8 +54,8 @@
 //--- std10-1-ex2-tu6.cpp
 import B;
 // error, n is module-local and this is not a module.
-int &c = n; // expected-error {{declaration of 'n' must be imported}}
-// expected-note@* {{declaration here is not visible}}
+int &c = n; // expected-error {{declaration of 'n' is private to module 'B'}}
+// expected-note@* {{export the declaration to make it available}}
 
 //--- std10-1-ex2-tu7.cpp
 // expected-no-diagnostics
Index: clang/test/Modules/Reachability-template-default-arg.cpp
===
--- clang/test/Modules/Reachability-template-defaul

[PATCH] D153542: [C++20][Modules] Implement P2615R1 exported specialization diagnostics.

2023-06-26 Thread Iain Sandoe via Phabricator via cfe-commits
iains planned changes to this revision.
iains added a comment.

need to re-check that the intention of the paper is covered (since we currently 
treat bare 'export' and 'export {}' in a similar manner).




Comment at: clang/lib/Sema/SemaModule.cpp:848-849
+if (auto *FD = dyn_cast(D)) {
+  if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+BadExport = true;
+} else if (auto *VD = dyn_cast(D)) {

ChuanqiXu wrote:
> ChuanqiXu wrote:
> > iains wrote:
> > > ChuanqiXu wrote:
> > > > Given P2615R1 doesn't allow explicit-instantiation in export block too.
> > > I think I must be missing something - I do not see that in the paper - 
> > > please could you expand your comment?
> > See the proposed change in #[module.interface]p1 in the paper, it changed:
> > 
> > ```
> > export declaration
> > ```
> > 
> > to 
> > 
> > 
> > ```
> > export named-declaration
> > ```
> > 
> > And the change between the old declaration and the new named declaration is 
> > in the proposed change in #[dcl.pre]p1. So it shows the special 
> > declarations shouldn't be allowed after `export`.
> > 
> > Also I noted it is allowed to write `export { declaration-seq_opt }` where 
> > the `declaration-seq` may contain special declarations. It looks weird to 
> > me. I'll try to check it and ask WG21 when necessary.
> I checked the record. And it shows that the current wording reflects the 
> intention. I mean
> 
> ```
> export template<> class A;
> ```
> 
> is not allowed. But,
> 
> ```
> export { template<> class A };
> ```
> 
> is allowed.
> 
> See the proposed change in #[module.interface]p1 in the paper, it changed:
...
> And the change between the old declaration and the new named declaration is 
> in the proposed change in #[dcl.pre]p1. So it shows the special declarations 
> shouldn't be allowed after `export`.
> 
> Also I noted it is allowed to write `export { declaration-seq_opt }` where 
> the `declaration-seq` may contain special declarations. It looks weird to me. 
> I'll try to check it and ask WG21 when necessary.

Indeed that does seem to be a strange mismatch - but you are right the 
introduction does mention this:

"This paper addresses CWG2443 by forbidding applying export directly to certain 
meaningless declarations. Conversely, it also allows all kinds to appear with 
export {}. For consistency extern "C" is given the same restrictions when used 
directly."

so I think I need to recheck this patch.




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153542

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


[PATCH] D153542: [C++20][Modules] Implement P2615R1 exported specialization diagnostics.

2023-06-26 Thread Iain Sandoe via Phabricator via cfe-commits
iains added inline comments.



Comment at: clang/lib/Sema/SemaModule.cpp:848-849
+if (auto *FD = dyn_cast(D)) {
+  if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+BadExport = true;
+} else if (auto *VD = dyn_cast(D)) {

ChuanqiXu wrote:
> Given P2615R1 doesn't allow explicit-instantiation in export block too.
I think I must be missing something - I do not see that in the paper - please 
could you expand your comment?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153542

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


[PATCH] D152746: [C++20][Modules] Complete implementation of module.import p7.

2023-06-25 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb37233a253f3: [C++20][Modules] Complete implementation of 
module.import p7. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152746

Files:
  clang/include/clang/Basic/Module.h
  clang/lib/Basic/Module.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/module/basic/basic.def.odr/p6.cppm
  clang/test/CXX/module/module.import/p7.cpp

Index: clang/test/CXX/module/module.import/p7.cpp
===
--- /dev/null
+++ clang/test/CXX/module/module.import/p7.cpp
@@ -0,0 +1,49 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// All of the following should build without diagnostics.
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cpp  -emit-module-interface -o %t/a.pcm
+// R U N: %clang_cc1 -std=c++20 %t/a.pcm  -emit-obj -o %t/a.o
+//
+// RUN: %clang_cc1 -std=c++20 %t/b.cpp  -emit-module-interface -o %t/b.pcm \
+// RUN: -fprebuilt-module-path=%t 
+// R U N: %clang_cc1 -std=c++20 %t/b.pcm  -emit-obj -o %t/b.o
+//
+// RUN: %clang_cc1 -std=c++20 %t/b-impl.cpp -emit-obj -o %t/b-impl.o \
+// RUN: -fprebuilt-module-path=%t
+//
+// RUN: %clang_cc1 -std=c++20 %t/ab-main.cpp  -fsyntax-only \
+// RUN: -fprebuilt-module-path=%t
+
+//--- a.cpp
+
+export module a;
+
+export int foo() {
+   return 42;
+}
+
+//--- b.cpp
+
+export module b;
+import a;
+
+export int bar();
+
+//--- b-impl.cpp
+
+module b;
+
+int bar() {
+   return foo();
+}
+
+//--- ab-main.cpp
+
+import b;
+
+int main() {
+   return bar();
+}
+
Index: clang/test/CXX/module/basic/basic.def.odr/p6.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p6.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p6.cppm
@@ -17,9 +17,8 @@
 //
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N.pcm -DMODULE_INTERFACE -DNO_ERRORS
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -verify
-// FIXME: Once we start importing "import" declarations properly, this should
-// be rejected (-verify should be added to the following line).
-// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -DNO_IMPORT
+//
+// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -DNO_IMPORT -verify
 //
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N-no-M.pcm -DMODULE_INTERFACE -DNO_ERRORS -DNO_IMPORT
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N-no-M.pcm -verify
Index: clang/lib/Sema/SemaModule.cpp
===
--- clang/lib/Sema/SemaModule.cpp
+++ clang/lib/Sema/SemaModule.cpp
@@ -397,6 +397,7 @@
   if (Interface) {
 
 VisibleModules.setVisible(Interface, ModuleLoc);
+VisibleModules.makeTransitiveImportsVisible(Interface, ModuleLoc);
 
 // Make the import decl for the interface in the impl module.
 ImportDecl *Import = ImportDecl::Create(Context, CurContext, ModuleLoc,
Index: clang/lib/Basic/Module.cpp
===
--- clang/lib/Basic/Module.cpp
+++ clang/lib/Basic/Module.cpp
@@ -695,6 +695,14 @@
   VisitModule({M, nullptr});
 }
 
+void VisibleModuleSet::makeTransitiveImportsVisible(Module *M,
+SourceLocation Loc,
+VisibleCallback Vis,
+ConflictCallback Cb) {
+  for (auto *I : M->Imports)
+setVisible(I, Loc, Vis, Cb);
+}
+
 ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
 : Signature(M.Signature), ClangModule(&M) {
   if (M.Directory)
Index: clang/include/clang/Basic/Module.h
===
--- clang/include/clang/Basic/Module.h
+++ clang/include/clang/Basic/Module.h
@@ -822,6 +822,11 @@
   ConflictCallback Cb = [](ArrayRef, Module *,
StringRef) {});
 
+  /// Make transitive imports visible for [module.import]/7.
+  void makeTransitiveImportsVisible(
+  Module *M, SourceLocation Loc, VisibleCallback Vis = [](Module *) {},
+  ConflictCallback Cb = [](ArrayRef, Module *, StringRef) {});
+
 private:
   /// Import locations for each visible module. Indexed by the module's
   /// VisibilityID.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152946: [C++20][Modules] Implement P2615R1 revised export diagnostics.

2023-06-24 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
iains marked an inline comment as done.
Closed by commit rGe5c7904fa0bf: [C++20][Modules] Implement P2615R1 revised 
export diagnostics. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152946

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/module/module.interface/p3.cpp
  clang/test/Modules/cxx20-10-2-ex1.cpp
  clang/test/Modules/cxx20-10-2-ex7.cpp
  clang/test/SemaCXX/modules.cppm

Index: clang/test/SemaCXX/modules.cppm
===
--- clang/test/SemaCXX/modules.cppm
+++ clang/test/SemaCXX/modules.cppm
@@ -34,11 +34,11 @@
 import foo; // expected-error {{imports must immediately follow the module declaration}}
 
 export {}
-export {  // expected-note {{begins here}}
-  ;   // expected-warning {{ISO C++20 does not permit an empty declaration to appear in an export block}}
+export {
+  ;   // No diagnostic after P2615R1 DR
 }
-export {   // expected-note {{begins here}}
-  static_assert(true); // expected-warning {{ISO C++20 does not permit a static_assert declaration to appear in an export block}}
+export {
+  static_assert(true); // No diagnostic after P2615R1 DR
 }
 
 int use_b = b; // expected-error{{use of undeclared identifier 'b'}}
Index: clang/test/Modules/cxx20-10-2-ex7.cpp
===
--- clang/test/Modules/cxx20-10-2-ex7.cpp
+++ clang/test/Modules/cxx20-10-2-ex7.cpp
@@ -2,8 +2,10 @@
 
 // RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -verify -o %t
 
+// expected-no-diagnostics
+
 export module M;
 export namespace N {
 int x; // OK
-static_assert(1 == 1); // expected-error {{static_assert declaration cannot be exported}}
+static_assert(1 == 1); // No diagnostic after P2615R1 DR
 } // namespace N
Index: clang/test/Modules/cxx20-10-2-ex1.cpp
===
--- clang/test/Modules/cxx20-10-2-ex1.cpp
+++ clang/test/Modules/cxx20-10-2-ex1.cpp
@@ -17,9 +17,9 @@
 // expected-error@std-10-2-ex1.h:* {{export declaration can only be used within a module purview}}
 
 export module M1;
-export namespace {} // expected-error {{declaration does not introduce any names to be exported}}
-export namespace {
-int a1; // expected-error {{declaration of 'a1' with internal linkage cannot be exported}}
+export namespace {} // expected-error {{anonymous namespaces cannot be exported}}
+export namespace { // expected-error {{anonymous namespaces cannot be exported}}
+int a1;
 }
 namespace {// expected-note {{anonymous namespace begins here}}
 export int a2; // expected-error {{export declaration appears within anonymous namespace}}
@@ -28,4 +28,4 @@
 export int f();  // OK
 
 export namespace N {} // namespace N
-export using namespace N; // expected-error {{ISO C++20 does not permit using directive to be exported}}
+export using namespace N; // No diagnostic after P2615R1 DR
Index: clang/test/CXX/module/module.interface/p3.cpp
===
--- clang/test/CXX/module/module.interface/p3.cpp
+++ clang/test/CXX/module/module.interface/p3.cpp
@@ -1,18 +1,19 @@
-// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 %s -verify -pedantic-errors
 
+// As amended by P2615R1 applied as a DR against C++20.
 export module p3;
 
 namespace A { int ns_mem; } // expected-note 2{{target}}
 
 // An exported declaration shall declare at least one name.
-export; // expected-error {{empty declaration cannot be exported}}
-export static_assert(true); // expected-error {{static_assert declaration cannot be exported}}
-export using namespace A;   // expected-error {{ISO C++20 does not permit using directive to be exported}}
+export; // No diagnostic after P2615R1 DR
+export static_assert(true); // No diagnostic after P2615R1 DR
+export using namespace A;   // No diagnostic after P2615R1 DR
 
-export { // expected-note 3{{export block begins here}}
-  ; // expected-error {{ISO C++20 does not permit an empty declaration to appear in an export block}}
-  static_assert(true); // expected-error {{ISO C++20 does not permit a static_assert declaration to appear in an export block}}
-  using namespace A;   // expected-error {{ISO C++20 does not permit using directive to be exported}}
+export { // No diagnostic after P2615R1 DR
+  ; // No diagnostic after P2615R1 DR
+  static_assert(true); // No diagnostic after P2615R1 DR
+  using namespace A;   // No diagnostic after P2615R1 DR
 }
 
 export struct {}; // expected-error {{must be class member}} expected-error {{GNU extension}} expected-error {{does not declare anything}}
@@ -24,27 +25,28 @@
 export enum E : int;
 export typedef int; // expected-error {{typedef r

[PATCH] D152746: [C++20][Modules] Complete implementation of module.import p7.

2023-06-22 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 533656.
iains added a comment.

rebased and fixed some formatting.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152746

Files:
  clang/include/clang/Basic/Module.h
  clang/lib/Basic/Module.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/module/basic/basic.def.odr/p6.cppm
  clang/test/CXX/module/module.import/p7.cpp

Index: clang/test/CXX/module/module.import/p7.cpp
===
--- /dev/null
+++ clang/test/CXX/module/module.import/p7.cpp
@@ -0,0 +1,49 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// All of the following should build without diagnostics.
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cpp  -emit-module-interface -o %t/a.pcm
+// R U N: %clang_cc1 -std=c++20 %t/a.pcm  -emit-obj -o %t/a.o
+//
+// RUN: %clang_cc1 -std=c++20 %t/b.cpp  -emit-module-interface -o %t/b.pcm \
+// RUN: -fprebuilt-module-path=%t 
+// R U N: %clang_cc1 -std=c++20 %t/b.pcm  -emit-obj -o %t/b.o
+//
+// RUN: %clang_cc1 -std=c++20 %t/b-impl.cpp -emit-obj -o %t/b-impl.o \
+// RUN: -fprebuilt-module-path=%t
+//
+// RUN: %clang_cc1 -std=c++20 %t/ab-main.cpp  -fsyntax-only \
+// RUN: -fprebuilt-module-path=%t
+
+//--- a.cpp
+
+export module a;
+
+export int foo() {
+   return 42;
+}
+
+//--- b.cpp
+
+export module b;
+import a;
+
+export int bar();
+
+//--- b-impl.cpp
+
+module b;
+
+int bar() {
+   return foo();
+}
+
+//--- ab-main.cpp
+
+import b;
+
+int main() {
+   return bar();
+}
+
Index: clang/test/CXX/module/basic/basic.def.odr/p6.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p6.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p6.cppm
@@ -17,9 +17,8 @@
 //
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N.pcm -DMODULE_INTERFACE -DNO_ERRORS
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -verify
-// FIXME: Once we start importing "import" declarations properly, this should
-// be rejected (-verify should be added to the following line).
-// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -DNO_IMPORT
+//
+// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -DNO_IMPORT -verify
 //
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N-no-M.pcm -DMODULE_INTERFACE -DNO_ERRORS -DNO_IMPORT
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N-no-M.pcm -verify
Index: clang/lib/Sema/SemaModule.cpp
===
--- clang/lib/Sema/SemaModule.cpp
+++ clang/lib/Sema/SemaModule.cpp
@@ -397,6 +397,7 @@
   if (Interface) {
 
 VisibleModules.setVisible(Interface, ModuleLoc);
+VisibleModules.makeTransitiveImportsVisible(Interface, ModuleLoc);
 
 // Make the import decl for the interface in the impl module.
 ImportDecl *Import = ImportDecl::Create(Context, CurContext, ModuleLoc,
Index: clang/lib/Basic/Module.cpp
===
--- clang/lib/Basic/Module.cpp
+++ clang/lib/Basic/Module.cpp
@@ -695,6 +695,14 @@
   VisitModule({M, nullptr});
 }
 
+void VisibleModuleSet::makeTransitiveImportsVisible(Module *M,
+SourceLocation Loc,
+VisibleCallback Vis,
+ConflictCallback Cb) {
+  for (auto *I : M->Imports)
+setVisible(I, Loc, Vis, Cb);
+}
+
 ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
 : Signature(M.Signature), ClangModule(&M) {
   if (M.Directory)
Index: clang/include/clang/Basic/Module.h
===
--- clang/include/clang/Basic/Module.h
+++ clang/include/clang/Basic/Module.h
@@ -822,6 +822,11 @@
   ConflictCallback Cb = [](ArrayRef, Module *,
StringRef) {});
 
+  /// Make transitive imports visible for [module.import]/7.
+  void makeTransitiveImportsVisible(
+  Module *M, SourceLocation Loc, VisibleCallback Vis = [](Module *) {},
+  ConflictCallback Cb = [](ArrayRef, Module *, StringRef) {});
+
 private:
   /// Import locations for each visible module. Indexed by the module's
   /// VisibilityID.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D153542: [C++20][Modules] Implement P2615R1 exported specialization diagnostics.

2023-06-22 Thread Iain Sandoe via Phabricator via cfe-commits
iains created this revision.
Herald added a subscriber: ChuanqiXu.
Herald added a project: All.
iains added a reviewer: ChuanqiXu.
iains added subscribers: clang-modules, h-vetinari.
iains published this revision for review.
iains added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

I think it is a good idea to keep this part of P2615R1 separate from the 
unnamed exports diagnostics [the parent commit] - it seems likely that there 
will be more fallout from this (given that there were already PRs about the 
behaviour of exported specialisations).


P2615R1 introduces diagnostics for partial and explicit specializations in 
module export declarations. This is applied as a DR to C++20.

Two testcases are removed since they were testing behaviour of imported 
specialisations (which are no longer permitted as exports).
Three testcases are amended to remove exports of specialisations, but retain 
the remainder of the test.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153542

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/module/module.interface/p1-p2615r1.cpp
  clang/test/CXX/temp/temp.explicit/p2-p2615r1.cpp
  clang/test/Modules/merge-var-template-spec-cxx-modules.cppm
  clang/test/Modules/pr59780.cppm
  clang/test/Modules/pr60890.cppm
  clang/test/Modules/pr62796.cppm
  clang/test/Modules/template-function-specialization.cpp
  clang/unittests/Serialization/VarDeclConstantInitTest.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -772,7 +772,7 @@
   

 https://wg21.link/P2615R1";>P2615R1 (DR)
-No
+Clang 17
   

 https://wg21.link/P2788R0";>P2788R0 (DR)
Index: clang/unittests/Serialization/VarDeclConstantInitTest.cpp
===
--- clang/unittests/Serialization/VarDeclConstantInitTest.cpp
+++ clang/unittests/Serialization/VarDeclConstantInitTest.cpp
@@ -86,7 +86,6 @@
 	template
 	constexpr unsigned long Cache = Compute(Number{}, Strategy{});
 
-  template constexpr unsigned long Cache<10ul>;
 }
   )cpp");
 
@@ -116,6 +115,7 @@
   std::unique_ptr AST = tooling::buildASTFromCodeWithArgs(
   R"cpp(
 import Fibonacci.Cache;
+template constexpr unsigned long Fibonacci::Cache<10ul>;
 )cpp",
   /*Args=*/{"-std=c++20", DepArg.c_str()});
 
Index: clang/test/Modules/template-function-specialization.cpp
===
--- clang/test/Modules/template-function-specialization.cpp
+++ clang/test/Modules/template-function-specialization.cpp
@@ -39,10 +39,6 @@
 void foo4() {
 }
 
-export template <>
-void foo4() {
-}
-
 //--- Use.cpp
 import foo;
 void use() {
Index: clang/test/Modules/pr62796.cppm
===
--- clang/test/Modules/pr62796.cppm
+++ clang/test/Modules/pr62796.cppm
@@ -38,8 +38,6 @@
 
 	template
 	constexpr unsigned long Cache = Compute(Number{}, Strategy{});
-
-template constexpr unsigned long Cache<10ul>;
 }
 
 //--- Use.cpp
Index: clang/test/Modules/pr60890.cppm
===
--- clang/test/Modules/pr60890.cppm
+++ clang/test/Modules/pr60890.cppm
@@ -18,8 +18,6 @@
 	void aaa() requires(true) {}
 };
 
-export template struct a;
-
 export template
 void foo(T) requires(true) {}
 
Index: clang/test/Modules/pr59780.cppm
===
--- clang/test/Modules/pr59780.cppm
+++ /dev/null
@@ -1,46 +0,0 @@
-// https://github.com/llvm/llvm-project/issues/59780
-//
-// RUN: rm -rf %t
-// RUN: mkdir %t
-// RUN: split-file %s %t
-//
-// RUN: %clang_cc1 -std=c++20 %t/a.cppm -triple %itanium_abi_triple -emit-module-interface -o %t/a.pcm
-// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fprebuilt-module-path=%t -S \
-// RUN: -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %t/use.cpp
-// RUN: %clang_cc1 -std=c++20 %t/a.pcm -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %t/a.cppm
-
-//--- a.cppm
-export module a;
-
-export template
-int x = 0;
-
-export template<>
-int x = 0;
-
-export template
-struct Y {
-static int value;
-};
-
-template 
-int Y::value = 0;
-
-export template<>
-struct Y {
-static int value;
-};
-
-int Y::value = 0;
-
-// CHECK-NOT: @_ZW1a1xIiE = {{.*}}external{{.*}}global
-// CHECK-NOT: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global
-
-//--- use.cpp
-import a;
-int foo() {
-return x + Y::value;
-}
-
-// CHECK: @_ZW1a1xIiE = {{.*}}external{{.*}}global
-// CHECK: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global
Index: clang/test/Modules/merge-var-template-spec-cxx-modules.cppm
===
--- clang/test/Modules/merge-var-tem

[PATCH] D152946: [C++20][Modules] Implement P2615R1 revised export diagnostics.

2023-06-22 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked 4 inline comments as done.
iains added a comment.

not sure why the debian CI is reported clang-format errors; I am not seeing 
them here.




Comment at: clang/lib/Sema/SemaModule.cpp:824-827
+  bool AllUnnamed = true;
+  for (auto *D : DC->decls())
+AllUnnamed &= checkExportedDecl(S, D, BlockStart);
+  return AllUnnamed;

ChuanqiXu wrote:
> 
(actually I just moved this code to place it closer to the use-point).

you change is more efficient, indeed, but it alters the behaviour of the 
diagnostics such that only the first occurrence is reported (which regresses 
module.interface/p5.cpp).

It seems to me to be more user-friendly to report all the errors at the same 
time rather than one by one.




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152946

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


[PATCH] D152946: [C++20][Modules] Implement P2615R1 revised export diagnostics.

2023-06-22 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 533554.
iains added a comment.

rebased, addressed review comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152946

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/module/module.interface/p3.cpp
  clang/test/Modules/cxx20-10-2-ex1.cpp
  clang/test/Modules/cxx20-10-2-ex7.cpp
  clang/test/SemaCXX/modules.cppm

Index: clang/test/SemaCXX/modules.cppm
===
--- clang/test/SemaCXX/modules.cppm
+++ clang/test/SemaCXX/modules.cppm
@@ -34,11 +34,11 @@
 import foo; // expected-error {{imports must immediately follow the module declaration}}
 
 export {}
-export {  // expected-note {{begins here}}
-  ;   // expected-warning {{ISO C++20 does not permit an empty declaration to appear in an export block}}
+export {
+  ;   // No diagnostic after P2615R1 DR
 }
-export {   // expected-note {{begins here}}
-  static_assert(true); // expected-warning {{ISO C++20 does not permit a static_assert declaration to appear in an export block}}
+export {
+  static_assert(true); // No diagnostic after P2615R1 DR
 }
 
 int use_b = b; // expected-error{{use of undeclared identifier 'b'}}
Index: clang/test/Modules/cxx20-10-2-ex7.cpp
===
--- clang/test/Modules/cxx20-10-2-ex7.cpp
+++ clang/test/Modules/cxx20-10-2-ex7.cpp
@@ -2,8 +2,10 @@
 
 // RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -verify -o %t
 
+// expected-no-diagnostics
+
 export module M;
 export namespace N {
 int x; // OK
-static_assert(1 == 1); // expected-error {{static_assert declaration cannot be exported}}
+static_assert(1 == 1); // No diagnostic after P2615R1 DR
 } // namespace N
Index: clang/test/Modules/cxx20-10-2-ex1.cpp
===
--- clang/test/Modules/cxx20-10-2-ex1.cpp
+++ clang/test/Modules/cxx20-10-2-ex1.cpp
@@ -17,9 +17,9 @@
 // expected-error@std-10-2-ex1.h:* {{export declaration can only be used within a module purview}}
 
 export module M1;
-export namespace {} // expected-error {{declaration does not introduce any names to be exported}}
-export namespace {
-int a1; // expected-error {{declaration of 'a1' with internal linkage cannot be exported}}
+export namespace {} // expected-error {{anonymous namespaces cannot be exported}}
+export namespace { // expected-error {{anonymous namespaces cannot be exported}}
+int a1;
 }
 namespace {// expected-note {{anonymous namespace begins here}}
 export int a2; // expected-error {{export declaration appears within anonymous namespace}}
@@ -28,4 +28,4 @@
 export int f();  // OK
 
 export namespace N {} // namespace N
-export using namespace N; // expected-error {{ISO C++20 does not permit using directive to be exported}}
+export using namespace N; // No diagnostic after P2615R1 DR
Index: clang/test/CXX/module/module.interface/p3.cpp
===
--- clang/test/CXX/module/module.interface/p3.cpp
+++ clang/test/CXX/module/module.interface/p3.cpp
@@ -1,18 +1,19 @@
-// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 %s -verify -pedantic-errors
 
+// As amended by P2615R1 applied as a DR against C++20.
 export module p3;
 
 namespace A { int ns_mem; } // expected-note 2{{target}}
 
 // An exported declaration shall declare at least one name.
-export; // expected-error {{empty declaration cannot be exported}}
-export static_assert(true); // expected-error {{static_assert declaration cannot be exported}}
-export using namespace A;   // expected-error {{ISO C++20 does not permit using directive to be exported}}
+export; // No diagnostic after P2615R1 DR
+export static_assert(true); // No diagnostic after P2615R1 DR
+export using namespace A;   // No diagnostic after P2615R1 DR
 
-export { // expected-note 3{{export block begins here}}
-  ; // expected-error {{ISO C++20 does not permit an empty declaration to appear in an export block}}
-  static_assert(true); // expected-error {{ISO C++20 does not permit a static_assert declaration to appear in an export block}}
-  using namespace A;   // expected-error {{ISO C++20 does not permit using directive to be exported}}
+export { // No diagnostic after P2615R1 DR
+  ; // No diagnostic after P2615R1 DR
+  static_assert(true); // No diagnostic after P2615R1 DR
+  using namespace A;   // No diagnostic after P2615R1 DR
 }
 
 export struct {}; // expected-error {{must be class member}} expected-error {{GNU extension}} expected-error {{does not declare anything}}
@@ -24,27 +25,28 @@
 export enum E : int;
 export typedef int; // expected-error {{typedef requires a name}}
 export static union {}; // expected-error {{does not declare anything}}
-export asm(""); // expected-error {{

[PATCH] D152946: [C++20][Modules] Implement P2615R1 revised export diagnostics.

2023-06-21 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D152946#4431974 , @h-vetinari 
wrote:

> Mark P2615  as implemented in 
> https://github.com/llvm/llvm-project/blame/main/clang/www/cxx_status.html?



In D152946#4431974 , @h-vetinari 
wrote:

> Mark P2615  as implemented in 
> https://github.com/llvm/llvm-project/blame/main/clang/www/cxx_status.html?

I did not do that yet since this patch only implements the removal of unnamed 
export diagnostics.  There will be a follow-on patch shortly that implements 
the addition of the export specialisation diagnostics and then we can claim 
P2615R1.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152946

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-06-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked an inline comment as done.
iains added a comment.

In D145965#4431997 , @ChuanqiXu wrote:

>> It is a case that we have supported; the user puts in a use of a decl but 
>> forgets to import the module exporting it (I agree it is not _exactly_ a 
>> "typo" in terms of names, but the diagnostics counts it in the same way)
>
> I got your point. But I prefer to implement an all-visible mode (not 
> available for users) for such situations. And I still think it is not problem 
> for the special case. Since this is patch is working for **internal** decls.

Yes, but AFAIR we also support the user naming an internal entity and then say 
"you must export PP before using it".
(I am sure that these changes were needed to avoid regressing existing 
diagnostics).

I have some ideas now - will thin about them during travel.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-06-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked 3 inline comments as done.
iains added a comment.

I will look at the rest of the comments once back in the office.

In D145965#4431929 , @ChuanqiXu wrote:

> In D145965#4431888 , @iains wrote:
>
>> In D145965#4431846 , @ChuanqiXu 
>> wrote:
>>
 if we do not adjust the typo fixes, we will regress diagnostics.
>>>
>>> What the kind of diagnostics will be regressed? I mean, it looks weird to 
>>> me that we suggest typo fixes from hidden names.
>>
>> Because when we do typo checking, we relax the visibility conditions so that 
>> we can see some decl that might be hidden or misspelled - then we can say
>>
>>   "you need to import module XX before using YY", 
>>
>> or
>>
>>   "did you mean ZZ"
>>
>> (I would be happy if we did not need to do this in this patch, but not sure 
>> how we can work around it).
>
> It is OK to see the misspelled decl. But it looks weird to me to see the 
> hidden decls. I think such regression should be called correction.

It is a case that we have supported; the user puts in a use of a decl but 
forgets to import the module exporting it (I agree it is not _exactly_ a "typo" 
in terms of names, but the diagnostics counts it in the same way)




Comment at: clang/lib/Sema/SemaLookup.cpp:1782
   assert(DeclModule && "hidden decl has no owning module");
 
+  // If the owning module is visible, the decl is potentially acceptable.

ChuanqiXu wrote:
> iains wrote:
> > ChuanqiXu wrote:
> > > It looks better to me if we can insert codes here
> > I am not sure exactly what you mean by "insert codes"?
> Oh, this is a little bit historical. I mean it looks better to do the main 
> job of the patch (correcting the visibility of internal linkage entities) if 
> possible.
OK. I agree that is ideal; it remains to be seen if it is feasible.



Comment at: clang/lib/Sema/SemaLookup.cpp:3912-3936
+  if (Visible) {
+if (!FM)
+  break;
+assert (D->hasLinkage() && "an imported func with no linkage?");
+// Unless the module is a defining one for the
+bool Ovr = true;
+for (unsigned I = 0; I < CodeSynthesisContexts.size(); ++I) {

ChuanqiXu wrote:
> iains wrote:
> > ChuanqiXu wrote:
> > > ChuanqiXu wrote:
> > > > ChuanqiXu wrote:
> > > > > ChuanqiXu wrote:
> > > > > > What's the intention for the change? And why is the current 
> > > > > > behavior bad without this?
> > > > > > What's the intention for the change? And why is the current 
> > > > > > behavior bad without this?
> > > > > 
> > > > > 
> > > > Oh, I understand why I feel the code is not good since the decl with 
> > > > internal linkage or module linkage shouldn't be visible. So even if 
> > > > there are problems, we should handle them elsewhere.
> > > Could we tried to address this? The change smells not so good.
> > I am not sure what you mean here - I would like us to get this lookup stuff 
> > fixed for 17, so will be working on it when back in the office (traveling 
> > today)
> > 
> > There is a different behaviour between cases where the entry is from an 
> > named module (but not the current one) and a different TU of the same named 
> > module.
> I mean the we should put the similar things together as much as possible. It 
> looks that the codes are trying to correcting the visibilities returned from 
> `isVisible()`. But this sounds not good. Since it implies that the result 
> from `isVisible()` is not valid.
> 
> > There is a different behaviour between cases where the entry is from an 
> > named module (but not the current one) and a different TU of the same named 
> > module.
> 
> Maybe we can tried to solve this by adding other `isVisible` interfaces.
> 
> > I would like us to get this lookup stuff fixed for 17, so will be working 
> > on it when back in the office (traveling today)
> 
> Yeah, but we still have one month. And even if we didn't get it in time. 
> (Given the size of the patch) It is still OK to back port this before the 
> first week of September. So we can be more relaxed.
> I mean the we should put the similar things together as much as possible. It 
> looks that the codes are trying to correcting the visibilities returned from 
> `isVisible()`. But this sounds not good. Since it implies that the result 
> from `isVisible()` is not valid.

Yes, indeed, I agree - if we were starting from scratch, we would do all this 
in the lower-level 'isVisible' - but since that is used in different ways by 
the higher levels, it seemed quite tricky to change.

> > There is a different behaviour between cases where the entry is from an 
> > named module (but not the current one) and a different TU of the same named 
> > module.
> 
> Maybe we can tried to solve this by adding other `isVisible` interfaces.

maybe that might work, I believe that 

[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-06-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked 2 inline comments as done.
iains added a comment.

In D145965#4431846 , @ChuanqiXu wrote:

>> if we do not adjust the typo fixes, we will regress diagnostics.
>
> What the kind of diagnostics will be regressed? I mean, it looks weird to me 
> that we suggest typo fixes from hidden names.

Because when we do typo checking, we relax the visibility conditions so that we 
can see some decl that might be hidden or misspelled - then we can say

  "you need to import module XX before using YY", 

or

  "did you mean ZZ"

(I would be happy if we did not need to do this in this patch, but not sure how 
we can work around it).




Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:11181
+  "%select{declaration|definition|default argument|"
+  "explicit specialization|partial specialization}0 of %1 is private to module 
"
+  "'%2'">;

ChuanqiXu wrote:
> ChuanqiXu wrote:
> > The 'private'  here makes me to think about module private fragment while 
> > it is not true. I prefer to refactor it to something like "it is not 
> > exported".
> let's try rewording `private` to `invisible`?
I will reword.



Comment at: clang/include/clang/Sema/Sema.h:2373
+  // Determine whether the module M belongs to the  current TU.
+  bool isModuleUnitOfCurrentTU(const Module *M) const;
+

ChuanqiXu wrote:
> Let's use `!DeclBase::isInAnotherModuleUnit()` instead now.
'isInAnotherModuleUnit' is not precise - for this work we need to have :

"is in another module unit of the same named module"
"is in another module unit of a different named module"

so I have made two functions to do these two jobs (although they are in Sema 
now, we can move them either to decl or module - as suggested later)




Comment at: clang/include/clang/Sema/Sema.h:2375-2383
+  /// Determine whether the module MA is part of the same named module as MB.
+  bool arePartOfSameNamedModule(const Module *MA, const Module *MB) const {
+if (!MA || MA->isGlobalModule())
+  return false;
+if (!MB || MB->isGlobalModule())
+  return false;
+return MA->getPrimaryModuleInterfaceName() ==

ChuanqiXu wrote:
> nit: I prefer this to be a freestanding function in Module.h. This looks 
> slightly not good within Sema.
what about moving all the module tu-related tests to decl.cpp/h (or maybe to 
module.cpp/h)?




Comment at: clang/lib/Sema/SemaLookup.cpp:1782
   assert(DeclModule && "hidden decl has no owning module");
 
+  // If the owning module is visible, the decl is potentially acceptable.

ChuanqiXu wrote:
> It looks better to me if we can insert codes here
I am not sure exactly what you mean by "insert codes"?



Comment at: clang/lib/Sema/SemaLookup.cpp:3912-3936
+  if (Visible) {
+if (!FM)
+  break;
+assert (D->hasLinkage() && "an imported func with no linkage?");
+// Unless the module is a defining one for the
+bool Ovr = true;
+for (unsigned I = 0; I < CodeSynthesisContexts.size(); ++I) {

ChuanqiXu wrote:
> ChuanqiXu wrote:
> > ChuanqiXu wrote:
> > > ChuanqiXu wrote:
> > > > What's the intention for the change? And why is the current behavior 
> > > > bad without this?
> > > > What's the intention for the change? And why is the current behavior 
> > > > bad without this?
> > > 
> > > 
> > Oh, I understand why I feel the code is not good since the decl with 
> > internal linkage or module linkage shouldn't be visible. So even if there 
> > are problems, we should handle them elsewhere.
> Could we tried to address this? The change smells not so good.
I am not sure what you mean here - I would like us to get this lookup stuff 
fixed for 17, so will be working on it when back in the office (traveling today)

There is a different behaviour between cases where the entry is from an named 
module (but not the current one) and a different TU of the same named module.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D152946: [C++20][Modules] Implement P2615R1 revised export diagnostics.

2023-06-14 Thread Iain Sandoe via Phabricator via cfe-commits
iains created this revision.
Herald added a subscriber: ChuanqiXu.
Herald added a project: All.
iains added a reviewer: ChuanqiXu.
iains added a subscriber: clang-modules.
iains edited the summary of this revision.
iains published this revision for review.
iains added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

thanks to Daniela Engert for reporting this and helping identify the current 
WG21 status on the topic.


It has been reported that the current clang  errors for, specifically,
static_assert in export contexts are a serious blocker to adoption of
modules in some cases.

There is also implementation divergence with GCC and MSVC allowing the
constructs mentioned below where clang currently rejects them with an
error.

The category of errors [for declarations in an exported context] is:
(unnamed, static_assert, empty and asm decls). These are now permitted
after P2615R1 which was approved by WG21 as a DR (and thus should be
applied to C++20 as well).

This patch removes these diagnostics and amends the testsuite accordingly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152946

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/module/module.interface/p3.cpp
  clang/test/Modules/cxx20-10-2-ex1.cpp
  clang/test/Modules/cxx20-10-2-ex7.cpp
  clang/test/SemaCXX/modules.cppm

Index: clang/test/SemaCXX/modules.cppm
===
--- clang/test/SemaCXX/modules.cppm
+++ clang/test/SemaCXX/modules.cppm
@@ -34,11 +34,11 @@
 import foo; // expected-error {{imports must immediately follow the module declaration}}
 
 export {}
-export {  // expected-note {{begins here}}
-  ;   // expected-warning {{ISO C++20 does not permit an empty declaration to appear in an export block}}
+export {
+  ;   // No diagnostic after P2615R1 DR
 }
-export {   // expected-note {{begins here}}
-  static_assert(true); // expected-warning {{ISO C++20 does not permit a static_assert declaration to appear in an export block}}
+export {
+  static_assert(true); // No diagnostic after P2615R1 DR
 }
 
 int use_b = b; // expected-error{{use of undeclared identifier 'b'}}
Index: clang/test/Modules/cxx20-10-2-ex7.cpp
===
--- clang/test/Modules/cxx20-10-2-ex7.cpp
+++ clang/test/Modules/cxx20-10-2-ex7.cpp
@@ -2,8 +2,10 @@
 
 // RUN: %clang_cc1 -std=c++20 -emit-module-interface %s -verify -o %t
 
+// expected-no-diagnostics
+
 export module M;
 export namespace N {
 int x; // OK
-static_assert(1 == 1); // expected-error {{static_assert declaration cannot be exported}}
+static_assert(1 == 1); // No diagnostic after P2615R1 DR
 } // namespace N
Index: clang/test/Modules/cxx20-10-2-ex1.cpp
===
--- clang/test/Modules/cxx20-10-2-ex1.cpp
+++ clang/test/Modules/cxx20-10-2-ex1.cpp
@@ -17,9 +17,9 @@
 // expected-error@std-10-2-ex1.h:* {{export declaration can only be used within a module purview}}
 
 export module M1;
-export namespace {} // expected-error {{declaration does not introduce any names to be exported}}
-export namespace {
-int a1; // expected-error {{declaration of 'a1' with internal linkage cannot be exported}}
+export namespace {} // expected-error {{anonymous namespaces cannot be exported}}
+export namespace { // expected-error {{anonymous namespaces cannot be exported}}
+int a1;
 }
 namespace {// expected-note {{anonymous namespace begins here}}
 export int a2; // expected-error {{export declaration appears within anonymous namespace}}
@@ -28,4 +28,4 @@
 export int f();  // OK
 
 export namespace N {} // namespace N
-export using namespace N; // expected-error {{ISO C++20 does not permit using directive to be exported}}
+export using namespace N; // No diagnostic after P2615R1 DR
Index: clang/test/CXX/module/module.interface/p3.cpp
===
--- clang/test/CXX/module/module.interface/p3.cpp
+++ clang/test/CXX/module/module.interface/p3.cpp
@@ -1,18 +1,19 @@
-// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 %s -verify -pedantic-errors
 
+// As amended by P2615R1 applied as a DR against C++20.
 export module p3;
 
 namespace A { int ns_mem; } // expected-note 2{{target}}
 
 // An exported declaration shall declare at least one name.
-export; // expected-error {{empty declaration cannot be exported}}
-export static_assert(true); // expected-error {{static_assert declaration cannot be exported}}
-export using namespace A;   // expected-error {{ISO C++20 does not permit using directive to be exported}}
+export; // No diagnostic after P2615R1 DR
+export static_assert(true); // No diagnostic after P2615R1 DR
+export using namespace A;   // No diagnostic after P2615R1 DR
 
-export { // expected-note 3{{export block

[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-06-12 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 530786.
iains added a comment.

rebased, added testcase for Issue 61601.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Lookup.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaLookup.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CXX/module/module.import/p2.cpp
  clang/test/CXX/module/module.interface/p2.cpp
  clang/test/CXX/module/module.interface/p7.cpp
  clang/test/CXX/module/module.reach/ex1.cpp
  clang/test/CXX/module/module.reach/p2.cpp
  clang/test/CXX/module/module.reach/p5.cpp
  clang/test/Modules/Reachability-template-default-arg.cpp
  clang/test/Modules/cxx20-10-1-ex2.cpp
  clang/test/Modules/deduction-guide3.cppm
  clang/test/Modules/diagnose-missing-import.m
  clang/test/Modules/pr61601.cpp

Index: clang/test/Modules/pr61601.cpp
===
--- /dev/null
+++ clang/test/Modules/pr61601.cpp
@@ -0,0 +1,30 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// All of the following should build without diagnostics.
+//
+// RUN: %clang_cc1 -std=c++20 %t/Part1.cpp -emit-module-interface -o %t/TheMod-Part1.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/Part2.cpp -emit-module-interface -o %t/TheMod-Part2.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/TheMod.cpp -emit-module-interface -o %t/TheMod.pcm \
+// RUN: -fprebuilt-module-path=%t
+
+//--- Part1.cpp
+
+export module TheMod:Part1;
+static int loog = 1;
+
+//--- Part2.cpp
+
+export module TheMod:Part2;
+static int loog = 2;
+
+//--- TheMod.cpp
+
+export module TheMod;
+export import :Part1;
+export import :Part2;
+
+static int loog = 3;
+export int V = loog;
Index: clang/test/Modules/diagnose-missing-import.m
===
--- clang/test/Modules/diagnose-missing-import.m
+++ clang/test/Modules/diagnose-missing-import.m
@@ -6,9 +6,9 @@
 
 void foo(void) {
   XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \
-  expected-error {{declaration of 'XYZLogEvent' must be imported}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
+  expected-error {{declaration of 'XYZLogEvent' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}}
 }
 
 // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
Index: clang/test/Modules/deduction-guide3.cppm
===
--- clang/test/Modules/deduction-guide3.cppm
+++ clang/test/Modules/deduction-guide3.cppm
@@ -19,8 +19,8 @@
 //--- Use.cpp
 import Templ;
 void func() {
-Templ t(5); // expected-error {{declaration of 'Templ' must be imported from module 'Templ' before it is required}}
+Templ t(5); // expected-error {{declaration of 'Templ' is private to module 'Templ'}}
 // expected-error@-1 {{unknown type name 'Templ'}}
-// expected-n...@templ.cppm:3 {{declaration here is not visible}}
+// expected-n...@templ.cppm:3 {{export the declaration to make it available}}
 }
 
Index: clang/test/Modules/cxx20-10-1-ex2.cpp
===
--- clang/test/Modules/cxx20-10-1-ex2.cpp
+++ clang/test/Modules/cxx20-10-1-ex2.cpp
@@ -54,8 +54,8 @@
 //--- std10-1-ex2-tu6.cpp
 import B;
 // error, n is module-local and this is not a module.
-int &c = n; // expected-error {{declaration of 'n' must be imported}}
-// expected-note@* {{declaration here is not visible}}
+int &c = n; // expected-error {{declaration of 'n' is private to module 'B'}}
+// expected-note@* {{export the declaration to make it available}}
 
 //--- std10-1-ex2-tu7.cpp
 // expected-no-diagnostics
Index: clang/test/Modules/Reachability-template-default-arg.cpp
===
--- clang/test/Modules/Reachability-template-

[PATCH] D152746: [C++20][Modules] Complete implementation of module.import p7.

2023-06-12 Thread Iain Sandoe via Phabricator via cfe-commits
iains created this revision.
Herald added a subscriber: ChuanqiXu.
Herald added a project: All.
iains edited the summary of this revision.
iains added a reviewer: ChuanqiXu.
iains added a subscriber: clang-modules.
iains published this revision for review.
iains added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

many thanks to Daniela Engert from bringing this to my attention (and providing 
a reproducer test case).


The following test fails to compile TU b.cpp because we are not making the 
transitively imported modules visible (per [module.import]/p7)

  a.cppm:
  export module a;
  
  export int foo() {
 return 42;
  }
  
  b.cppm:
  export module b;
  import a;
  
  export int bar();
  
  b.cpp:
  module b;
  
  int bar() {
 return foo();
  }
  
  clang++ -c -std=c++2b -fmodule-output a.cppm
  clang++ -c -std=c++2b -fmodule-output -fprebuilt-module-path=. b.cppm
  clang++ -c -std=c++2b -fprebuilt-module-path=. b.cpp
  b.cpp:4:12: error: declaration of 'foo' must be imported from module 'a' 
before it is required
 return foo();

This is fixed by the following patch (which also addresses a FIXME in 
basic.def.odr/p6.cppm).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152746

Files:
  clang/include/clang/Basic/Module.h
  clang/lib/Basic/Module.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/module/basic/basic.def.odr/p6.cppm
  clang/test/CXX/module/module.import/p7.cpp

Index: clang/test/CXX/module/module.import/p7.cpp
===
--- /dev/null
+++ clang/test/CXX/module/module.import/p7.cpp
@@ -0,0 +1,49 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// All of the following should build without diagnostics.
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cpp  -emit-module-interface -o %t/a.pcm
+// R U N: %clang_cc1 -std=c++20 %t/a.pcm  -emit-obj -o %t/a.o
+//
+// RUN: %clang_cc1 -std=c++20 %t/b.cpp  -emit-module-interface -o %t/b.pcm \
+// RUN: -fprebuilt-module-path=%t 
+// R U N: %clang_cc1 -std=c++20 %t/b.pcm  -emit-obj -o %t/b.o
+//
+// RUN: %clang_cc1 -std=c++20 %t/b-impl.cpp -emit-obj -o %t/b-impl.o \
+// RUN: -fprebuilt-module-path=%t
+//
+// RUN: %clang_cc1 -std=c++20 %t/ab-main.cpp  -fsyntax-only \
+// RUN: -fprebuilt-module-path=%t
+
+//--- a.cpp
+
+export module a;
+
+export int foo() {
+   return 42;
+}
+
+//--- b.cpp
+
+export module b;
+import a;
+
+export int bar();
+
+//--- b-impl.cpp
+
+module b;
+
+int bar() {
+   return foo();
+}
+
+//--- ab-main.cpp
+
+import b;
+
+int main() {
+   return bar();
+}
+
Index: clang/test/CXX/module/basic/basic.def.odr/p6.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p6.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p6.cppm
@@ -17,9 +17,8 @@
 //
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N.pcm -DMODULE_INTERFACE -DNO_ERRORS
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -verify
-// FIXME: Once we start importing "import" declarations properly, this should
-// be rejected (-verify should be added to the following line).
-// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -DNO_IMPORT
+//
+// RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N.pcm -DNO_IMPORT -verify
 //
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -emit-module-interface -o %t/N-no-M.pcm -DMODULE_INTERFACE -DNO_ERRORS -DNO_IMPORT
 // RUN: %clang_cc1 -std=c++20 %t/module-vs-module.cpp -fmodule-file=M=%t/M.pcm -fmodule-file=N=%t/N-no-M.pcm -verify
Index: clang/lib/Sema/SemaModule.cpp
===
--- clang/lib/Sema/SemaModule.cpp
+++ clang/lib/Sema/SemaModule.cpp
@@ -397,6 +397,7 @@
   if (Interface) {
 
 VisibleModules.setVisible(Interface, ModuleLoc);
+VisibleModules.makeTransitiveImportsVisible(Interface, ModuleLoc);
 
 // Make the import decl for the interface in the impl module.
 ImportDecl *Import = ImportDecl::Create(Context, CurContext, ModuleLoc,
Index: clang/lib/Basic/Module.cpp
===
--- clang/lib/Basic/Module.cpp
+++ clang/lib/Basic/Module.cpp
@@ -697,6 +697,13 @@
   VisitModule({M, nullptr});
 }
 
+void
+VisibleModuleSet::makeTransitiveImportsVisible(Module *M, SourceLocation Loc,
+ VisibleCallback Vis, ConflictCallback Cb) {
+  for (auto *I : M->Imports)
+setVisible(I, Loc, Vis, Cb);
+}
+
 ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
 : Signature(M.Signature), ClangModule(&M) {
   if (M.Directory)
Index: clang/include/clang/Basic/Module.h
===
--- clang/include/clang/Basic/Module.h
+++ cla

[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-06-09 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

about the comments that the patch seems to do multiple things;  I do not think 
we can fix the lookup without touching the typo-fixes since it uses the same 
underlying machinery - if we do not adjust the typo fixes, we will regress 
diagnostics.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-06-09 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 529852.
iains marked 2 inline comments as done.
iains added a comment.

rebased and adjusted for upstream changes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Lookup.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaLookup.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CXX/module/module.import/p2.cpp
  clang/test/CXX/module/module.interface/p2.cpp
  clang/test/CXX/module/module.interface/p7.cpp
  clang/test/CXX/module/module.reach/ex1.cpp
  clang/test/CXX/module/module.reach/p2.cpp
  clang/test/CXX/module/module.reach/p5.cpp
  clang/test/Modules/Reachability-template-default-arg.cpp
  clang/test/Modules/cxx20-10-1-ex2.cpp
  clang/test/Modules/deduction-guide3.cppm
  clang/test/Modules/diagnose-missing-import.m

Index: clang/test/Modules/diagnose-missing-import.m
===
--- clang/test/Modules/diagnose-missing-import.m
+++ clang/test/Modules/diagnose-missing-import.m
@@ -6,9 +6,9 @@
 
 void foo(void) {
   XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \
-  expected-error {{declaration of 'XYZLogEvent' must be imported}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
+  expected-error {{declaration of 'XYZLogEvent' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}}
 }
 
 // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
Index: clang/test/Modules/deduction-guide3.cppm
===
--- clang/test/Modules/deduction-guide3.cppm
+++ clang/test/Modules/deduction-guide3.cppm
@@ -19,8 +19,8 @@
 //--- Use.cpp
 import Templ;
 void func() {
-Templ t(5); // expected-error {{declaration of 'Templ' must be imported from module 'Templ' before it is required}}
+Templ t(5); // expected-error {{declaration of 'Templ' is private to module 'Templ'}}
 // expected-error@-1 {{unknown type name 'Templ'}}
-// expected-n...@templ.cppm:3 {{declaration here is not visible}}
+// expected-n...@templ.cppm:3 {{export the declaration to make it available}}
 }
 
Index: clang/test/Modules/cxx20-10-1-ex2.cpp
===
--- clang/test/Modules/cxx20-10-1-ex2.cpp
+++ clang/test/Modules/cxx20-10-1-ex2.cpp
@@ -54,8 +54,8 @@
 //--- std10-1-ex2-tu6.cpp
 import B;
 // error, n is module-local and this is not a module.
-int &c = n; // expected-error {{declaration of 'n' must be imported}}
-// expected-note@* {{declaration here is not visible}}
+int &c = n; // expected-error {{declaration of 'n' is private to module 'B'}}
+// expected-note@* {{export the declaration to make it available}}
 
 //--- std10-1-ex2-tu7.cpp
 // expected-no-diagnostics
Index: clang/test/Modules/Reachability-template-default-arg.cpp
===
--- clang/test/Modules/Reachability-template-default-arg.cpp
+++ clang/test/Modules/Reachability-template-default-arg.cpp
@@ -18,6 +18,6 @@
 import template_default_arg;
 void bar() {
   A<> a0;
-  A a1; // expected-error {{declaration of 't' must be imported from module 'template_default_arg' before it is required}}
-   // expected-note@* {{declaration here is not visible}}
+  A a1; // expected-error {{declaration of 't' is private to module 'template_default_arg'}}
+   // expected-note@* {{export the declaration to make it available}}
 }
Index: clang/test/CXX/module/module.reach/p5.cpp
===
--- clang/test/CXX/module/module.reach/p5.cpp
+++ clang/test/CXX/module/module.reach/p5.cpp
@@ -14,5 +14,5 @@
 export module B;
 import A;
 Y y; // OK, definition of X is reachable
-X x; // expected-error {{declaration of 'X' must be

[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-04-06 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked 2 inline comments as done.
iains added inline comments.



Comment at: clang/include/clang/Sema/Sema.h:2356
+  /// Determine whether the module M is part of the current named module.
+  bool isPartOfCurrentNamedModule(const Module *M) const {
+if (!M || M->isGlobalModule())

ChuanqiXu wrote:
> While I am not a native speaker, I feel `isSameModuleWithCurrentTU` may be a 
> better name.
actually, as noted, both cases are needed. So I have made that clear by 
splitting the function into two.



Comment at: clang/lib/Sema/SemaLookup.cpp:5821-5832
+  } else if (Decl->hasLinkage() &&
+ Decl->getFormalLinkage() == Linkage::ModuleLinkage) {
+Diag(UseLoc, diag::err_module_private_use)
+<< (int)MIK << Decl << Modules[0]->getFullModuleName();
+Diag(Decl->getBeginLoc(), diag::note_suggest_export)
+<< (int)MIK
+<< FixItHint::CreateInsertion(Decl->getBeginLoc(), "export");

ChuanqiXu wrote:
> I feel like this can be another change. I'm a little bit confused since I 
> feel the patch did multiple things at the same time again..
sure, we can refactor; the current patch is a placeholder to allow work to 
continue on `p1815`.



Comment at: clang/lib/Sema/SemaLookup.cpp:2101
+  if (isVisible(SemaRef, ND)) {
+if (SemaRef.getLangOpts().CPlusPlusModules && ND->isFromASTFile()) {
+  // The module that owns the decl is visible; However

ChuanqiXu wrote:
> iains wrote:
> > ChuanqiXu wrote:
> > > Let's not use `isFromASTFile()`. It is a low level API without higher 
> > > level semantics. I think it is good enough to check the module of ND.
> > lookup is very heavily used; the purpose of the isFromAST() check is to 
> > short-circuit the more expensive checks when we know that a decl must be in 
> > the same TU (i.e. it is not from an AST file).  
> > 
> > If we can find a suitable inexpensive check that has better semantics, I am 
> > fine to change this,
> > 
> It looks good enough to me to check that `ND` lives in a module. And from 
> what I profiled, the lookup process is not hot really.
OK, we can always revisit performance later,



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-04-06 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

in the end, we have to deal with the following cases:

1. decls in the same TU (including GMF and PMF)
2. decls in the current named module (excluding GMF)
3. decls on an instantiation path (which can include internal-linkage entities)
4. decls that are needed by an exported entity from a *differennt" named module 
[e.g. a module-linkage entity that is used by some exported  content].


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-04-06 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 511327.
iains added a comment.

rebased, addressed review comments (patch still needs refactoring)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Lookup.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaLookup.cpp
  clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CXX/module/module.import/p2.cpp
  clang/test/CXX/module/module.interface/p2.cpp
  clang/test/CXX/module/module.interface/p7.cpp
  clang/test/CXX/module/module.reach/ex1.cpp
  clang/test/CXX/module/module.reach/p2.cpp
  clang/test/CXX/module/module.reach/p5.cpp
  clang/test/Modules/Reachability-template-default-arg.cpp
  clang/test/Modules/cxx20-10-1-ex2.cpp
  clang/test/Modules/deduction-guide3.cppm
  clang/test/Modules/diagnose-missing-import.m

Index: clang/test/Modules/diagnose-missing-import.m
===
--- clang/test/Modules/diagnose-missing-import.m
+++ clang/test/Modules/diagnose-missing-import.m
@@ -6,9 +6,9 @@
 
 void foo(void) {
   XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \
-  expected-error {{declaration of 'XYZLogEvent' must be imported}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
+  expected-error {{declaration of 'XYZLogEvent' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}}
 }
 
 // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
Index: clang/test/Modules/deduction-guide3.cppm
===
--- clang/test/Modules/deduction-guide3.cppm
+++ clang/test/Modules/deduction-guide3.cppm
@@ -19,8 +19,8 @@
 //--- Use.cpp
 import Templ;
 void func() {
-Templ t(5); // expected-error {{declaration of 'Templ' must be imported from module 'Templ' before it is required}}
+Templ t(5); // expected-error {{declaration of 'Templ' is private to module 'Templ'}}
 // expected-error@-1 {{unknown type name 'Templ'}}
-// expected-n...@templ.cppm:3 {{declaration here is not visible}}
+// expected-n...@templ.cppm:3 {{export the declaration to make it available}}
 }
 
Index: clang/test/Modules/cxx20-10-1-ex2.cpp
===
--- clang/test/Modules/cxx20-10-1-ex2.cpp
+++ clang/test/Modules/cxx20-10-1-ex2.cpp
@@ -53,8 +53,8 @@
 //--- std10-1-ex2-tu6.cpp
 import B;
 // error, n is module-local and this is not a module.
-int &c = n; // expected-error {{declaration of 'n' must be imported}}
-// expected-note@* {{declaration here is not visible}}
+int &c = n; // expected-error {{declaration of 'n' is private to module 'B'}}
+// expected-note@* {{export the declaration to make it available}}
 
 //--- std10-1-ex2-tu7.cpp
 // expected-no-diagnostics
Index: clang/test/Modules/Reachability-template-default-arg.cpp
===
--- clang/test/Modules/Reachability-template-default-arg.cpp
+++ clang/test/Modules/Reachability-template-default-arg.cpp
@@ -18,6 +18,6 @@
 import template_default_arg;
 void bar() {
   A<> a0;
-  A a1; // expected-error {{declaration of 't' must be imported from module 'template_default_arg' before it is required}}
-   // expected-note@* {{declaration here is not visible}}
+  A a1; // expected-error {{declaration of 't' is private to module 'template_default_arg'}}
+   // expected-note@* {{export the declaration to make it available}}
 }
Index: clang/test/CXX/module/module.reach/p5.cpp
===
--- clang/test/CXX/module/module.reach/p5.cpp
+++ clang/test/CXX/module/module.reach/p5.cpp
@@ -14,5 +14,5 @@
 export module B;
 import A;
 Y y; // OK, definition of X is reachable
-X x; // expected-error {{declaration of 'X' must be imported from module 'A' before it is required

[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-04-02 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked 2 inline comments as done.
iains added inline comments.



Comment at: clang/lib/Sema/SemaLookup.cpp:2082
+Module *DeclModule = SemaRef.getOwningModule(D);
+if (DeclModule && !DeclModule->isModuleMapModule() &&
+!SemaRef.isModuleUnitOfCurrentTU(DeclModule) &&

ChuanqiXu wrote:
> iains wrote:
> > ChuanqiXu wrote:
> > > We should check header units here.
> > The point of checking module map modules was to avoid affecting clang 
> > modules with the change in semantics.
> > 
> > At the moment, I am not sure why we could exclude lookup from finding decls 
> > in an imported header unit?
> > 
> > At the moment, I am not sure why we could exclude lookup from finding decls 
> > in an imported header unit?
> 
> We're not **excluding** decls from an imported header units. We're trying to 
> include the decls from the headers units. Since we've allowed decls with 
> internal linkage to appear to header units. We must need to allow decls with 
> internal linkage in  header units to be found here. Otherwise, the following 
> example may fail:
> 
> ```
> // foo.h
> static int a = 43;
> 
> // m.cppm
> export module m;
> import "foo.h";
> use of a...
> ```
> 
> BTW, given the semantics of header units and clang modules are pretty 
> similar, we should use `isHeaderModule ` in most cases.
ah yes, that special case, I should have remembered.
OK I will adjust this at the next iteration (I think you mean 
`isHeaderLikeModule()`)



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-04-02 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked 2 inline comments as done.
iains added a comment.

I updated this because I am going to push the latest version of the `P1815` 
patch and that depends on the lookup changes.




Comment at: clang/lib/Sema/SemaLookup.cpp:2082
+Module *DeclModule = SemaRef.getOwningModule(D);
+if (DeclModule && !DeclModule->isModuleMapModule() &&
+!SemaRef.isModuleUnitOfCurrentTU(DeclModule) &&

ChuanqiXu wrote:
> We should check header units here.
The point of checking module map modules was to avoid affecting clang modules 
with the change in semantics.

At the moment, I am not sure why we could exclude lookup from finding decls in 
an imported header unit?




Comment at: clang/lib/Sema/SemaLookup.cpp:2101
+  if (isVisible(SemaRef, ND)) {
+if (SemaRef.getLangOpts().CPlusPlusModules && ND->isFromASTFile()) {
+  // The module that owns the decl is visible; However

ChuanqiXu wrote:
> Let's not use `isFromASTFile()`. It is a low level API without higher level 
> semantics. I think it is good enough to check the module of ND.
lookup is very heavily used; the purpose of the isFromAST() check is to 
short-circuit the more expensive checks when we know that a decl must be in the 
same TU (i.e. it is not from an AST file).  

If we can find a suitable inexpensive check that has better semantics, I am 
fine to change this,



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-04-02 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 510388.
iains added a comment.

rebased


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Lookup.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaLookup.cpp
  clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CXX/module/module.import/p2.cpp
  clang/test/CXX/module/module.interface/p2.cpp
  clang/test/CXX/module/module.interface/p7.cpp
  clang/test/CXX/module/module.reach/ex1.cpp
  clang/test/CXX/module/module.reach/p2.cpp
  clang/test/CXX/module/module.reach/p5.cpp
  clang/test/Modules/Reachability-template-default-arg.cpp
  clang/test/Modules/cxx20-10-1-ex2.cpp
  clang/test/Modules/deduction-guide3.cppm
  clang/test/Modules/diagnose-missing-import.m

Index: clang/test/Modules/diagnose-missing-import.m
===
--- clang/test/Modules/diagnose-missing-import.m
+++ clang/test/Modules/diagnose-missing-import.m
@@ -6,9 +6,9 @@
 
 void foo(void) {
   XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \
-  expected-error {{declaration of 'XYZLogEvent' must be imported}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
+  expected-error {{declaration of 'XYZLogEvent' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}}
 }
 
 // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
Index: clang/test/Modules/deduction-guide3.cppm
===
--- clang/test/Modules/deduction-guide3.cppm
+++ clang/test/Modules/deduction-guide3.cppm
@@ -19,8 +19,8 @@
 //--- Use.cpp
 import Templ;
 void func() {
-Templ t(5); // expected-error {{declaration of 'Templ' must be imported from module 'Templ' before it is required}}
+Templ t(5); // expected-error {{declaration of 'Templ' is private to module 'Templ'}}
 // expected-error@-1 {{unknown type name 'Templ'}}
-// expected-n...@templ.cppm:3 {{declaration here is not visible}}
+// expected-n...@templ.cppm:3 {{export the declaration to make it available}}
 }
 
Index: clang/test/Modules/cxx20-10-1-ex2.cpp
===
--- clang/test/Modules/cxx20-10-1-ex2.cpp
+++ clang/test/Modules/cxx20-10-1-ex2.cpp
@@ -53,8 +53,8 @@
 //--- std10-1-ex2-tu6.cpp
 import B;
 // error, n is module-local and this is not a module.
-int &c = n; // expected-error {{declaration of 'n' must be imported}}
-// expected-note@* {{declaration here is not visible}}
+int &c = n; // expected-error {{declaration of 'n' is private to module 'B'}}
+// expected-note@* {{export the declaration to make it available}}
 
 //--- std10-1-ex2-tu7.cpp
 // expected-no-diagnostics
Index: clang/test/Modules/Reachability-template-default-arg.cpp
===
--- clang/test/Modules/Reachability-template-default-arg.cpp
+++ clang/test/Modules/Reachability-template-default-arg.cpp
@@ -18,6 +18,6 @@
 import template_default_arg;
 void bar() {
   A<> a0;
-  A a1; // expected-error {{declaration of 't' must be imported from module 'template_default_arg' before it is required}}
-   // expected-note@* {{declaration here is not visible}}
+  A a1; // expected-error {{declaration of 't' is private to module 'template_default_arg'}}
+   // expected-note@* {{export the declaration to make it available}}
 }
Index: clang/test/CXX/module/module.reach/p5.cpp
===
--- clang/test/CXX/module/module.reach/p5.cpp
+++ clang/test/CXX/module/module.reach/p5.cpp
@@ -14,5 +14,5 @@
 export module B;
 import A;
 Y y; // OK, definition of X is reachable
-X x; // expected-error {{declaration of 'X' must be imported from module 'A' before it is required}}
- // expected-note@* {{declaration here is not visib

[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-28 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked an inline comment as done.
iains added inline comments.



Comment at: clang/lib/Lex/ModuleMap.cpp:935
+  // with any legal user-defined module name).
+  StringRef IName = ".ImplementationUnit";
+  assert(!Modules[IName] && "multiple implementation units?");

ChuanqiXu wrote:
> nit: It should more consistent to use ``.
(I do not mind making this change later, if you like - but I did not want to 
repeat the test cycle today).

In this case I think that `<>` would not mean the same thing as it does in 
`` and `` modules fragments,  These are never entered into the 
module map - but are always owned by a parent module.

In the case of the ImplementationUnit - the *name* of the module is unchanged 
(i.e. it would still be called `M`  when the module line is ` module M;`.

The `.ImplementationUnit` is not the name of the module - but rather it is a 
key into the module map (which needs to be different from the name of the 
interface),  Since there can only be one Implementation Unit in a given 
session, it is safe to use a fixed key. 

However, I do not mind changing the key to `` if you think 
that it would be more clear.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

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


[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-28 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6e4f870a21e3: re-land [C++20][Modules] Introduce an 
implementation module. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

Files:
  clang/include/clang/Basic/Module.h
  clang/include/clang/Lex/ModuleMap.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Decl.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/FrontendActions.cpp
  clang/lib/Lex/ModuleMap.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CodeGenCXX/module-intializer.cpp

Index: clang/test/CodeGenCXX/module-intializer.cpp
===
--- clang/test/CodeGenCXX/module-intializer.cpp
+++ clang/test/CodeGenCXX/module-intializer.cpp
@@ -18,17 +18,17 @@
 // RUN: -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN: -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN: -fmodule-file=N=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:-emit-module-interface -o M.pcm
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.pcm -S -emit-llvm \
 // RUN:  -o - | FileCheck %s --check-prefix=CHECK-M
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 useM.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-USE
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M-impl.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-IMPL
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 N.cpp -S -emit-llvm \
@@ -41,7 +41,7 @@
 // RUN:   -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN:   -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN:   -fmodule-file=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:   -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-M
 
 //--- N-h.h
Index: clang/test/CXX/module/basic/basic.link/p2.cppm
===
--- clang/test/CXX/module/basic/basic.link/p2.cppm
+++ clang/test/CXX/module/basic/basic.link/p2.cppm
@@ -39,19 +39,21 @@
 }
 
 //--- M.cpp
-// expected-no-diagnostics
+
 module M;
 
-// FIXME: Use of internal linkage entities should be rejected.
 void use_from_module_impl() {
   external_linkage_fn();
   module_linkage_fn();
-  internal_linkage_fn();
+  internal_linkage_fn(); // expected-error {{no matching function for call to 'internal_linkage_fn'}}
   (void)external_linkage_class{};
   (void)module_linkage_class{};
-  (void)internal_linkage_class{};
   (void)external_linkage_var;
   (void)module_linkage_var;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
+  (void)internal_linkage_class{};
   (void)internal_linkage_var;
 }
 
Index: clang/test/CXX/module/basic/basic.def.odr/p4.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p4.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p4.cppm
@@ -143,9 +143,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
-  // CHECK: define {{.*}}@_ZL26used_static_module_linkagev
-  used_static_module_linkage();
-
   // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev
   used_inline_module_linkage();
 
@@ -154,8 +151,12 @@
 
   (void)&extern_var_module_linkage;
   (void)&inline_var_module_linkage;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
   (void)&static_var_module_linkage; // FIXME: Should not be visible here.
-  (void)&const_var_module_linkage;
+
+  (void)&const_var_module_linkage; // FIXME: will be visible after P2788R0
 }
 
 //--- user.cpp
@@ -176,5 +177,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
+  // Internal-linkage declarations are not visible here.
   // Module-linkage declarations are not visible here.
 }
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -2719,7 +2719,7 @@
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
-  Abbrev->Add(Bi

[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-28 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 509014.
iains added a comment.

rebased, retested.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

Files:
  clang/include/clang/Basic/Module.h
  clang/include/clang/Lex/ModuleMap.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Decl.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/FrontendActions.cpp
  clang/lib/Lex/ModuleMap.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CodeGenCXX/module-intializer.cpp

Index: clang/test/CodeGenCXX/module-intializer.cpp
===
--- clang/test/CodeGenCXX/module-intializer.cpp
+++ clang/test/CodeGenCXX/module-intializer.cpp
@@ -18,17 +18,17 @@
 // RUN: -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN: -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN: -fmodule-file=N=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:-emit-module-interface -o M.pcm
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.pcm -S -emit-llvm \
 // RUN:  -o - | FileCheck %s --check-prefix=CHECK-M
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 useM.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-USE
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M-impl.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-IMPL
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 N.cpp -S -emit-llvm \
@@ -41,7 +41,7 @@
 // RUN:   -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN:   -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN:   -fmodule-file=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:   -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-M
 
 //--- N-h.h
Index: clang/test/CXX/module/basic/basic.link/p2.cppm
===
--- clang/test/CXX/module/basic/basic.link/p2.cppm
+++ clang/test/CXX/module/basic/basic.link/p2.cppm
@@ -39,19 +39,21 @@
 }
 
 //--- M.cpp
-// expected-no-diagnostics
+
 module M;
 
-// FIXME: Use of internal linkage entities should be rejected.
 void use_from_module_impl() {
   external_linkage_fn();
   module_linkage_fn();
-  internal_linkage_fn();
+  internal_linkage_fn(); // expected-error {{no matching function for call to 'internal_linkage_fn'}}
   (void)external_linkage_class{};
   (void)module_linkage_class{};
-  (void)internal_linkage_class{};
   (void)external_linkage_var;
   (void)module_linkage_var;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
+  (void)internal_linkage_class{};
   (void)internal_linkage_var;
 }
 
Index: clang/test/CXX/module/basic/basic.def.odr/p4.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p4.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p4.cppm
@@ -143,9 +143,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
-  // CHECK: define {{.*}}@_ZL26used_static_module_linkagev
-  used_static_module_linkage();
-
   // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev
   used_inline_module_linkage();
 
@@ -154,8 +151,12 @@
 
   (void)&extern_var_module_linkage;
   (void)&inline_var_module_linkage;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
   (void)&static_var_module_linkage; // FIXME: Should not be visible here.
-  (void)&const_var_module_linkage;
+
+  (void)&const_var_module_linkage; // FIXME: will be visible after P2788R0
 }
 
 //--- user.cpp
@@ -176,5 +177,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
+  // Internal-linkage declarations are not visible here.
   // Module-linkage declarations are not visible here.
 }
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -2719,7 +2719,7 @@
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
-  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Kind
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fix

[PATCH] D146986: Downgrade reserved module identifier error into a warning

2023-03-28 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

+1 for this as an interim solution.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146986

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


[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-27 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

It took me a while to get my local macOS  based devt. environment to reproduce 
the problem - but it was as expected; the implementation module was unowned and 
nothing was deleting it.

unless CI throws up anything untoward, I plan to re-land this tomorrow (since 
there is dependent work in my queue and this blocks or at least impedes 
progress there).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

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


[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-27 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 508662.
iains added a comment.

rebased, reworked to have the module owned.

The implementation module needs to be owned by the mpodul map so that
it is released when done.  Reworked the comments and assert to check the
main file presence.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

Files:
  clang/include/clang/Basic/Module.h
  clang/include/clang/Lex/ModuleMap.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Decl.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/FrontendActions.cpp
  clang/lib/Lex/ModuleMap.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CodeGenCXX/module-intializer.cpp

Index: clang/test/CodeGenCXX/module-intializer.cpp
===
--- clang/test/CodeGenCXX/module-intializer.cpp
+++ clang/test/CodeGenCXX/module-intializer.cpp
@@ -18,17 +18,17 @@
 // RUN: -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN: -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN: -fmodule-file=N=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:-emit-module-interface -o M.pcm
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.pcm -S -emit-llvm \
 // RUN:  -o - | FileCheck %s --check-prefix=CHECK-M
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 useM.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-USE
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M-impl.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-IMPL
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 N.cpp -S -emit-llvm \
@@ -41,7 +41,7 @@
 // RUN:   -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN:   -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN:   -fmodule-file=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:   -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-M
 
 //--- N-h.h
Index: clang/test/CXX/module/basic/basic.link/p2.cppm
===
--- clang/test/CXX/module/basic/basic.link/p2.cppm
+++ clang/test/CXX/module/basic/basic.link/p2.cppm
@@ -39,19 +39,21 @@
 }
 
 //--- M.cpp
-// expected-no-diagnostics
+
 module M;
 
-// FIXME: Use of internal linkage entities should be rejected.
 void use_from_module_impl() {
   external_linkage_fn();
   module_linkage_fn();
-  internal_linkage_fn();
+  internal_linkage_fn(); // expected-error {{no matching function for call to 'internal_linkage_fn'}}
   (void)external_linkage_class{};
   (void)module_linkage_class{};
-  (void)internal_linkage_class{};
   (void)external_linkage_var;
   (void)module_linkage_var;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
+  (void)internal_linkage_class{};
   (void)internal_linkage_var;
 }
 
Index: clang/test/CXX/module/basic/basic.def.odr/p4.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p4.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p4.cppm
@@ -143,9 +143,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
-  // CHECK: define {{.*}}@_ZL26used_static_module_linkagev
-  used_static_module_linkage();
-
   // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev
   used_inline_module_linkage();
 
@@ -154,8 +151,12 @@
 
   (void)&extern_var_module_linkage;
   (void)&inline_var_module_linkage;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
   (void)&static_var_module_linkage; // FIXME: Should not be visible here.
-  (void)&const_var_module_linkage;
+
+  (void)&const_var_module_linkage; // FIXME: will be visible after P2788R0
 }
 
 //--- user.cpp
@@ -176,5 +177,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
+  // Internal-linkage declarations are not visible here.
   // Module-linkage declarations are not visible here.
 }
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -2719,7 +2719,7 @@
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // I

[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-27 Thread Iain Sandoe via Phabricator via cfe-commits
iains reopened this revision.
iains added a comment.
This revision is now accepted and ready to land.

I had a hunch that the issue was the non-ownership of the implementation module.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

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


[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-26 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D126959#4222637 , @bjope wrote:

> This seem to case problems when building with asan enabled 
> (LLVM_USE_SANITIZER='Address'):

investigating... do you need the patch reverted?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-03-24 Thread Iain Sandoe via Phabricator via cfe-commits
iains planned changes to this revision.
iains added a comment.

although this patch does handle the cases needed, it really needs refactoring.
posting here since we are both working in this area and this might be useful 
input.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-03-24 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 507977.
iains edited the summary of this revision.
iains added a comment.

rebased, split the changes to module and private linkage out,

this needs to be refactored to collect the test functions into either
module.h and / or sema.h


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Lookup.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaLookup.cpp
  clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CXX/module/module.import/p2.cpp
  clang/test/CXX/module/module.interface/p2.cpp
  clang/test/CXX/module/module.interface/p7.cpp
  clang/test/CXX/module/module.reach/ex1.cpp
  clang/test/CXX/module/module.reach/p2.cpp
  clang/test/CXX/module/module.reach/p5.cpp
  clang/test/Modules/Reachability-template-default-arg.cpp
  clang/test/Modules/cxx20-10-1-ex2.cpp
  clang/test/Modules/deduction-guide3.cppm
  clang/test/Modules/diagnose-missing-import.m

Index: clang/test/Modules/diagnose-missing-import.m
===
--- clang/test/Modules/diagnose-missing-import.m
+++ clang/test/Modules/diagnose-missing-import.m
@@ -6,9 +6,9 @@
 
 void foo(void) {
   XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \
-  expected-error {{declaration of 'XYZLogEvent' must be imported}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
+  expected-error {{declaration of 'XYZLogEvent' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}}
 }
 
 // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
Index: clang/test/Modules/deduction-guide3.cppm
===
--- clang/test/Modules/deduction-guide3.cppm
+++ clang/test/Modules/deduction-guide3.cppm
@@ -19,8 +19,8 @@
 //--- Use.cpp
 import Templ;
 void func() {
-Templ t(5); // expected-error {{declaration of 'Templ' must be imported from module 'Templ' before it is required}}
+Templ t(5); // expected-error {{declaration of 'Templ' is private to module 'Templ'}}
 // expected-error@-1 {{unknown type name 'Templ'}}
-// expected-n...@templ.cppm:3 {{declaration here is not visible}}
+// expected-n...@templ.cppm:3 {{export the declaration to make it available}}
 }
 
Index: clang/test/Modules/cxx20-10-1-ex2.cpp
===
--- clang/test/Modules/cxx20-10-1-ex2.cpp
+++ clang/test/Modules/cxx20-10-1-ex2.cpp
@@ -53,8 +53,8 @@
 //--- std10-1-ex2-tu6.cpp
 import B;
 // error, n is module-local and this is not a module.
-int &c = n; // expected-error {{declaration of 'n' must be imported}}
-// expected-note@* {{declaration here is not visible}}
+int &c = n; // expected-error {{declaration of 'n' is private to module 'B'}}
+// expected-note@* {{export the declaration to make it available}}
 
 //--- std10-1-ex2-tu7.cpp
 // expected-no-diagnostics
Index: clang/test/Modules/Reachability-template-default-arg.cpp
===
--- clang/test/Modules/Reachability-template-default-arg.cpp
+++ clang/test/Modules/Reachability-template-default-arg.cpp
@@ -18,6 +18,6 @@
 import template_default_arg;
 void bar() {
   A<> a0;
-  A a1; // expected-error {{declaration of 't' must be imported from module 'template_default_arg' before it is required}}
-   // expected-note@* {{declaration here is not visible}}
+  A a1; // expected-error {{declaration of 't' is private to module 'template_default_arg'}}
+   // expected-note@* {{export the declaration to make it available}}
 }
Index: clang/test/CXX/module/module.reach/p5.cpp
===
--- clang/test/CXX/module/module.reach/p5.cpp
+++ clang/test/CXX/module/module.reach/p5.cpp
@@ -14,5 +14,5 @@
 export module B;
 import A;
 Y y; /

[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-23 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
iains marked an inline comment as done.
Closed by commit rGc6e9823724ef: [C++20][Modules] Introduce an implementation 
module. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

Files:
  clang/include/clang/Basic/Module.h
  clang/include/clang/Lex/ModuleMap.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Decl.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/FrontendActions.cpp
  clang/lib/Lex/ModuleMap.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CodeGenCXX/module-intializer.cpp

Index: clang/test/CodeGenCXX/module-intializer.cpp
===
--- clang/test/CodeGenCXX/module-intializer.cpp
+++ clang/test/CodeGenCXX/module-intializer.cpp
@@ -18,17 +18,17 @@
 // RUN: -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN: -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN: -fmodule-file=N=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:-emit-module-interface -o M.pcm
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.pcm -S -emit-llvm \
 // RUN:  -o - | FileCheck %s --check-prefix=CHECK-M
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 useM.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-USE
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M-impl.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-IMPL
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 N.cpp -S -emit-llvm \
@@ -41,7 +41,7 @@
 // RUN:   -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN:   -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN:   -fmodule-file=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:   -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-M
 
 //--- N-h.h
Index: clang/test/CXX/module/basic/basic.link/p2.cppm
===
--- clang/test/CXX/module/basic/basic.link/p2.cppm
+++ clang/test/CXX/module/basic/basic.link/p2.cppm
@@ -39,19 +39,21 @@
 }
 
 //--- M.cpp
-// expected-no-diagnostics
+
 module M;
 
-// FIXME: Use of internal linkage entities should be rejected.
 void use_from_module_impl() {
   external_linkage_fn();
   module_linkage_fn();
-  internal_linkage_fn();
+  internal_linkage_fn(); // expected-error {{no matching function for call to 'internal_linkage_fn'}}
   (void)external_linkage_class{};
   (void)module_linkage_class{};
-  (void)internal_linkage_class{};
   (void)external_linkage_var;
   (void)module_linkage_var;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
+  (void)internal_linkage_class{};
   (void)internal_linkage_var;
 }
 
Index: clang/test/CXX/module/basic/basic.def.odr/p4.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p4.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p4.cppm
@@ -143,9 +143,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
-  // CHECK: define {{.*}}@_ZL26used_static_module_linkagev
-  used_static_module_linkage();
-
   // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev
   used_inline_module_linkage();
 
@@ -154,8 +151,12 @@
 
   (void)&extern_var_module_linkage;
   (void)&inline_var_module_linkage;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
   (void)&static_var_module_linkage; // FIXME: Should not be visible here.
-  (void)&const_var_module_linkage;
+
+  (void)&const_var_module_linkage; // FIXME: will be visible after P2788R0
 }
 
 //--- user.cpp
@@ -176,5 +177,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
+  // Internal-linkage declarations are not visible here.
   // Module-linkage declarations are not visible here.
 }
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -2719,7 +2719,7 @@
   Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // 

[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-22 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked an inline comment as done.
iains added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:1672-1677
+  // A module implementation unit has visibility of the decls in its implicitly
+  // imported interface.
+  if (getLangOpts().CPlusPlusModules && NewM && OldM &&
+  NewM->Kind == Module::ModuleImplementationUnit &&
+  OldM->Kind == Module::ModuleInterfaceUnit && NewM->Name == OldM->Name)
+return false;

ChuanqiXu wrote:
> iains wrote:
> > ChuanqiXu wrote:
> > > I feel slightly better to add a field in Sema:
> > > 
> > > ```
> > > Module *PrimaryModuleInterface = nullptr; // Only valid if we're parsing 
> > > a module unit.
> > > ```
> > > 
> > > Then we can avoid the string compare here.  Also we can add it to 
> > > `Sema::isUsableModule`. Now `Sema::isUsableModule` works because it falls 
> > > to the string comparison.
> > I also thought about doing this, but decided that we should try to keep the 
> > interface regular - so that all modules are treated the same.
> > 
> > If we find that the string comparison for primary module name is a "hot 
> > spot" then we should address it a different way - by caching an identifier 
> > or similar (since we need to compare it in other places too).
> It just smells bad. I did profiling for the performance for modules these 
> days. And it looks like the string comparison can hard to be the hot spot. 
> The bottleneck lives in other places. The string comparison may be in the 
> long tail. So we might not be able to prove this one by giving numbers. But 
> it indeed smells bad and we can solve it simply. So let's make it. I think it 
> is important to improve our code quality.
I have done this (for now) to make progress.

but, actually, in this case, I do not agree with the mechanism

.. instead of making this into a special case we should (as part of the 
following fixes to lookup) make efficient helpers in module / sema that allow 
us to see "same TU", "same named module" etc.  That way we can improve the 
performance of any one of those if it becomes an issue.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

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


[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-22 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 507535.
iains marked 12 inline comments as done.
iains edited the summary of this revision.
iains added a comment.

rebased, addressed review comments, and amended the description.

the patch has been repurposed to provide a mechanism to track implementation
TUs as separate entities which allows us to deal with handling Tu-local
entities better.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

Files:
  clang/include/clang/Basic/Module.h
  clang/include/clang/Lex/ModuleMap.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Decl.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/FrontendActions.cpp
  clang/lib/Lex/ModuleMap.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CodeGenCXX/module-intializer.cpp

Index: clang/test/CodeGenCXX/module-intializer.cpp
===
--- clang/test/CodeGenCXX/module-intializer.cpp
+++ clang/test/CodeGenCXX/module-intializer.cpp
@@ -18,17 +18,17 @@
 // RUN: -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN: -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN: -fmodule-file=N=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:-emit-module-interface -o M.pcm
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.pcm -S -emit-llvm \
 // RUN:  -o - | FileCheck %s --check-prefix=CHECK-M
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 useM.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-USE
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M-impl.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-IMPL
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 N.cpp -S -emit-llvm \
@@ -41,7 +41,7 @@
 // RUN:   -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN:   -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN:   -fmodule-file=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:   -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-M
 
 //--- N-h.h
Index: clang/test/CXX/module/basic/basic.link/p2.cppm
===
--- clang/test/CXX/module/basic/basic.link/p2.cppm
+++ clang/test/CXX/module/basic/basic.link/p2.cppm
@@ -39,19 +39,21 @@
 }
 
 //--- M.cpp
-// expected-no-diagnostics
+
 module M;
 
-// FIXME: Use of internal linkage entities should be rejected.
 void use_from_module_impl() {
   external_linkage_fn();
   module_linkage_fn();
-  internal_linkage_fn();
+  internal_linkage_fn(); // expected-error {{no matching function for call to 'internal_linkage_fn'}}
   (void)external_linkage_class{};
   (void)module_linkage_class{};
-  (void)internal_linkage_class{};
   (void)external_linkage_var;
   (void)module_linkage_var;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
+  (void)internal_linkage_class{};
   (void)internal_linkage_var;
 }
 
Index: clang/test/CXX/module/basic/basic.def.odr/p4.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p4.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p4.cppm
@@ -143,9 +143,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
-  // CHECK: define {{.*}}@_ZL26used_static_module_linkagev
-  used_static_module_linkage();
-
   // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev
   used_inline_module_linkage();
 
@@ -154,8 +151,12 @@
 
   (void)&extern_var_module_linkage;
   (void)&inline_var_module_linkage;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
   (void)&static_var_module_linkage; // FIXME: Should not be visible here.
-  (void)&const_var_module_linkage;
+
+  (void)&const_var_module_linkage; // FIXME: will be visible after P2788R0
 }
 
 //--- user.cpp
@@ -176,5 +177,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
+  // Internal-linkage declarations are not visible here.
   // Module-linkage declarations are not visible here.
 }
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -2719,7 +2719,7 @@
   Abbrev

[PATCH] D145886: [C++2x][Modules] Amend module purview constant linkage [P2788R0].

2023-03-19 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG62a16d5e2069: [C++2x][Modules] Amend module purview constant 
linkage [P2788R0]. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145886

Files:
  clang/lib/AST/Decl.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p3.cppm


Index: clang/test/CXX/module/basic/basic.link/p3.cppm
===
--- clang/test/CXX/module/basic/basic.link/p3.cppm
+++ clang/test/CXX/module/basic/basic.link/p3.cppm
@@ -3,7 +3,7 @@
 
 export module M;
 
-// CHECK-NOT: @_ZW1M1a ={{.*}}
+// CHECK: @_ZW1M1a ={{.*}} constant i32 1
 const int a = 1;
 // CHECK: @_ZW1M1b ={{.*}} constant i32 2
 export const int b = 2;
Index: clang/test/CXX/module/basic/basic.def.odr/p4.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p4.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p4.cppm
@@ -5,9 +5,9 @@
 // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple 
-emit-llvm -o - | FileCheck %t/Module.cppm --implicit-check-not unused
 //
 // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple 
-emit-module-interface -o %t/Module.pcm
-// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple 
-fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
+// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple 
-fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
 //
-// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple 
-fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
+// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple 
-fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
 
 //--- Module.cppm
 // CHECK-DAG: @extern_var_global_module = external {{(dso_local )?}}global
@@ -30,7 +30,7 @@
 // permitted to run the initializer for this variable.
 // CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr 
{{(dso_local )?}}global
 // CHECK-DAG: @_ZL25static_var_module_linkage = internal
-// CHECK-DAG: @_ZL24const_var_module_linkage = internal
+// CHECK-DAG: @_ZW6Module24const_var_module_linkage = {{(dso_local )?}}constant
 //
 // CHECK-DAG: @_ZW6Module25unused_var_module_linkage = {{(dso_local )?}}global 
i32 4
 
@@ -129,7 +129,7 @@
 // CHECK-DAG: @_ZW6Module25extern_var_module_linkage = external {{(dso_local 
)?}}global
 // CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr 
{{(dso_local )?}}global
 // CHECK-DAG: @_ZL25static_var_module_linkage = internal {{(dso_local 
)?}}global i32 0,
-// CHECK-DAG: @_ZL24const_var_module_linkage = internal {{(dso_local 
)?}}constant i32 3,
+// CHECK-DAG: @_ZW6Module24const_var_module_linkage = available_externally 
{{(dso_local )?}}constant i32 3,
 
 module Module;
 
Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -600,6 +600,12 @@
   llvm_unreachable("unexpected module ownership kind");
 }
 
+static bool isDeclaredInModuleInterfaceOrPartition(const NamedDecl *D) {
+  if (auto *M = D->getOwningModule())
+return M->isInterfaceOrPartition();
+  return false;
+}
+
 static LinkageInfo getInternalLinkageFor(const NamedDecl *D) {
   return LinkageInfo::internal();
 }
@@ -642,15 +648,15 @@
   if (const auto *Var = dyn_cast(D)) {
 // - a non-template variable of non-volatile const-qualified type, unless
 //   - it is explicitly declared extern, or
-//   - it is inline or exported, or
+//   - it is declared in the purview of a module interface unit
+// (outside the private-module-fragment, if any) or module partition, 
or
+//   - it is inline, or
 //   - it was previously declared and the prior declaration did not have
 // internal linkage
 // (There is no equivalent in C99.)
-if (Context.getLangOpts().CPlusPlus &&
-Var->getType().isConstQualified() &&
-!Var->getType().isVolatileQualified() &&
-!Var->isInline() &&
-!isExportedFromModuleInterfaceUnit(Var) &&
+if (Context.getLangOpts().CPlusPlus && Var->getType().isConstQualified() &&
+!Var->getType().isVolatileQualified() && !Var->isInline() &&
+!isDeclaredInModuleInterfaceOrPartition(Var) &&
 !isa(Var) &&
 !Var->getDescribedVarTemplate()) {
   const VarDecl *PrevVar = Var->getPreviousDecl();

[PATCH] D145886: [C++2x][Modules] Amend module purview constant linkage [P2788R0].

2023-03-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 506380.
iains added a comment.

rebased.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145886

Files:
  clang/lib/AST/Decl.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p3.cppm


Index: clang/test/CXX/module/basic/basic.link/p3.cppm
===
--- clang/test/CXX/module/basic/basic.link/p3.cppm
+++ clang/test/CXX/module/basic/basic.link/p3.cppm
@@ -3,7 +3,7 @@
 
 export module M;
 
-// CHECK-NOT: @_ZW1M1a ={{.*}}
+// CHECK: @_ZW1M1a ={{.*}} constant i32 1
 const int a = 1;
 // CHECK: @_ZW1M1b ={{.*}} constant i32 2
 export const int b = 2;
Index: clang/test/CXX/module/basic/basic.def.odr/p4.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p4.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p4.cppm
@@ -5,9 +5,9 @@
 // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple 
-emit-llvm -o - | FileCheck %t/Module.cppm --implicit-check-not unused
 //
 // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple 
-emit-module-interface -o %t/Module.pcm
-// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple 
-fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
+// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple 
-fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
 //
-// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple 
-fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
+// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple 
-fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
 
 //--- Module.cppm
 // CHECK-DAG: @extern_var_global_module = external {{(dso_local )?}}global
@@ -30,7 +30,7 @@
 // permitted to run the initializer for this variable.
 // CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr 
{{(dso_local )?}}global
 // CHECK-DAG: @_ZL25static_var_module_linkage = internal
-// CHECK-DAG: @_ZL24const_var_module_linkage = internal
+// CHECK-DAG: @_ZW6Module24const_var_module_linkage = {{(dso_local )?}}constant
 //
 // CHECK-DAG: @_ZW6Module25unused_var_module_linkage = {{(dso_local )?}}global 
i32 4
 
@@ -129,7 +129,7 @@
 // CHECK-DAG: @_ZW6Module25extern_var_module_linkage = external {{(dso_local 
)?}}global
 // CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr 
{{(dso_local )?}}global
 // CHECK-DAG: @_ZL25static_var_module_linkage = internal {{(dso_local 
)?}}global i32 0,
-// CHECK-DAG: @_ZL24const_var_module_linkage = internal {{(dso_local 
)?}}constant i32 3,
+// CHECK-DAG: @_ZW6Module24const_var_module_linkage = available_externally 
{{(dso_local )?}}constant i32 3,
 
 module Module;
 
Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -600,6 +600,12 @@
   llvm_unreachable("unexpected module ownership kind");
 }
 
+static bool isDeclaredInModuleInterfaceOrPartition(const NamedDecl *D) {
+  if (auto *M = D->getOwningModule())
+return M->isInterfaceOrPartition();
+  return false;
+}
+
 static LinkageInfo getInternalLinkageFor(const NamedDecl *D) {
   return LinkageInfo::internal();
 }
@@ -642,15 +648,15 @@
   if (const auto *Var = dyn_cast(D)) {
 // - a non-template variable of non-volatile const-qualified type, unless
 //   - it is explicitly declared extern, or
-//   - it is inline or exported, or
+//   - it is declared in the purview of a module interface unit
+// (outside the private-module-fragment, if any) or module partition, 
or
+//   - it is inline, or
 //   - it was previously declared and the prior declaration did not have
 // internal linkage
 // (There is no equivalent in C99.)
-if (Context.getLangOpts().CPlusPlus &&
-Var->getType().isConstQualified() &&
-!Var->getType().isVolatileQualified() &&
-!Var->isInline() &&
-!isExportedFromModuleInterfaceUnit(Var) &&
+if (Context.getLangOpts().CPlusPlus && Var->getType().isConstQualified() &&
+!Var->getType().isVolatileQualified() && !Var->isInline() &&
+!isDeclaredInModuleInterfaceOrPartition(Var) &&
 !isa(Var) &&
 !Var->getDescribedVarTemplate()) {
   const VarDecl *PrevVar = Var->getPreviousDecl();


Index: clang/test/CXX/module/basic/basic.link/p3.cppm
===
--- clang/test/CXX/module/basic/basic.link/p3.cpp

[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-17 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked 10 inline comments as done.
iains added a comment.

General comments (at least my opinion).

1. One intention of this patch is to make Implementation Module Units regular 
(i.e. they should behave the same as any other module unit).  So I would tend 
to avoid changes that make this back into a "special case"

2. The lookup problems might be considered to be quite a serious bug, and so we 
should consider possible back porting and try to avoid making large changes in 
theses patches (once that problem is solved, then we can refactor, I think).

3. We do have tests for the initialiser in implementation units.



In D126959#4201152 , @ChuanqiXu wrote:

> 



> And I guess it may refer to the problem we are discussing. The spec says the 
> implementation unit will import the primary module interface implicitly.
> But the current implementation doesn't **import** it actually but loading it. 
> This is inconsistent with the wording and it is not consistent with the 
> design intention in clang.
> It resulted some problems we saw.

This patch implements the remaining pieces of that (including "as if by an 
`import`).




Comment at: clang/include/clang/Basic/Module.h:137
 ImplicitGlobalModuleFragment,
   };
 

ChuanqiXu wrote:
> We may be able to save 1 bit for ModuleKind by adding two field bits to 
> Module: `IsImplementation` and `IsPartition`. Then we can remove 
> `ModulePartitionInterface` and `ModulePartitionImplementation`. Then let's 
> rename `ModuleInterfaceUnit` to `NamedModuleUnit`.
> So we can judge module interface unit, implementation unit,  module partition 
> interface and module partition implementation by `NamedModuleUnit ` and the 
> two bits.
Yes I agree we could do this, but let's keep refactoring as a follow-on job.



Comment at: clang/lib/Frontend/FrontendActions.cpp:835
+  case Module::ModuleImplementationUnit:
+return "Implementation Unit (should never be serialized)";
   case Module::ModulePartitionInterface:

ChuanqiXu wrote:
> Since `ModuleKindName()` here is used as a helpful for printers, it looks odd 
> to contain the `should never be serialized` part. I think we should check 
> this when we try to generate PCM files for ModuleImplementationUnit.
OK. I can remove that

We do already check and refuse to generate a PCM for a module implementation 
(if you put `-emit-module-interface`, and the file contains `module Foo;` it 
will be rejected).




Comment at: clang/lib/Lex/ModuleMap.cpp:910
+  return Result;
+}
+

ChuanqiXu wrote:
> The implementation looks similar to `createModuleForInterfaceUnit` really. It 
> looks better to refactor it to `createModuleUnits` (or 
> createModuleForCXX20Modules)  which containing an additional argument 
> `Module::ModuleKind`. It would optimize the case for partitions too, which 
> uses `createModuleForInterfaceUnit ` now and it is a little bit odd.
OK I did think about refactoring that, but decided to keep the changes simple 
for now.  I am happy to look at refactoring.



Comment at: clang/lib/Sema/SemaDecl.cpp:1672-1677
+  // A module implementation unit has visibility of the decls in its implicitly
+  // imported interface.
+  if (getLangOpts().CPlusPlusModules && NewM && OldM &&
+  NewM->Kind == Module::ModuleImplementationUnit &&
+  OldM->Kind == Module::ModuleInterfaceUnit && NewM->Name == OldM->Name)
+return false;

ChuanqiXu wrote:
> I feel slightly better to add a field in Sema:
> 
> ```
> Module *PrimaryModuleInterface = nullptr; // Only valid if we're parsing a 
> module unit.
> ```
> 
> Then we can avoid the string compare here.  Also we can add it to 
> `Sema::isUsableModule`. Now `Sema::isUsableModule` works because it falls to 
> the string comparison.
I also thought about doing this, but decided that we should try to keep the 
interface regular - so that all modules are treated the same.

If we find that the string comparison for primary module name is a "hot spot" 
then we should address it a different way - by caching an identifier or similar 
(since we need to compare it in other places too).



Comment at: clang/lib/Sema/SemaModule.cpp:302
+  Module *Mod; // The module we are creating.
+  Module *Interface = nullptr; // The interface for an implementation.
   switch (MDK) {

ChuanqiXu wrote:
> Then we can avoid to declare this if we have `Sema::PrimaryModuleInterface `
see comment above.



Comment at: clang/lib/Sema/SemaModule.cpp:408-409
+// module, if any.
+if (!ModuleScopes.empty())
+  Context.addModuleInitializer(ModuleScopes.back().Module, Import);
+

ChuanqiXu wrote:
> ModuleScopes can't be empty here.
OK.



Comment at: clang/lib/Sema/SemaModule.cpp:306
+  Path[0].second);
+  //

[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-16 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

This was originally created (and @ChuanqiXu approved) for the work on module 
initialisers.  I did not apply it then, since it was possible to determine the 
correct state for the initialisers without it.

However, now we are trying to handle some of the details of different lookup 
requirements between same-module and same-TU, I think it is a foundation for 
that.  This also means that implementation units will get their own TU decl and 
have a distinct decl context (rather than the current case that we share the 
decl context of the interface).

The units are never serialised (as noted above) but we still need to allocate 
an extra bit for the enum (since we now have 9 values); this is not a 
significant load (since it adds only one bit to each module header).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

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


[PATCH] D126959: [C++20][Modules] Introduce an implementation module.

2023-03-16 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 505759.
iains added a comment.

rebased, and reworked for changes in main.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126959

Files:
  clang/include/clang/Basic/Module.h
  clang/include/clang/Lex/ModuleMap.h
  clang/lib/AST/Decl.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Frontend/FrontendActions.cpp
  clang/lib/Lex/ModuleMap.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CodeGenCXX/module-intializer.cpp

Index: clang/test/CodeGenCXX/module-intializer.cpp
===
--- clang/test/CodeGenCXX/module-intializer.cpp
+++ clang/test/CodeGenCXX/module-intializer.cpp
@@ -18,17 +18,17 @@
 // RUN: -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN: -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN: -fmodule-file=N=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:-emit-module-interface -o M.pcm
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.pcm -S -emit-llvm \
 // RUN:  -o - | FileCheck %s --check-prefix=CHECK-M
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 useM.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-USE
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M-impl.cpp \
-// RUN: -fmodule-file=M.pcm -S -emit-llvm  -o - \
+// RUN: -fmodule-file=M=M.pcm -S -emit-llvm  -o - \
 // RUN: | FileCheck %s --check-prefix=CHECK-IMPL
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 N.cpp -S -emit-llvm \
@@ -41,7 +41,7 @@
 // RUN:   -o - | FileCheck %s --check-prefix=CHECK-P
 
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 M.cpp \
-// RUN:   -fmodule-file=N.pcm -fmodule-file=O.pcm -fmodule-file=M-part.pcm \
+// RUN:   -fmodule-file=N.pcm -fmodule-file=O=O.pcm -fmodule-file=M:Part=M-part.pcm \
 // RUN:   -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-M
 
 //--- N-h.h
Index: clang/test/CXX/module/basic/basic.link/p2.cppm
===
--- clang/test/CXX/module/basic/basic.link/p2.cppm
+++ clang/test/CXX/module/basic/basic.link/p2.cppm
@@ -39,19 +39,21 @@
 }
 
 //--- M.cpp
-// expected-no-diagnostics
+
 module M;
 
-// FIXME: Use of internal linkage entities should be rejected.
 void use_from_module_impl() {
   external_linkage_fn();
   module_linkage_fn();
-  internal_linkage_fn();
+  internal_linkage_fn(); // expected-error {{no matching function for call to 'internal_linkage_fn'}}
   (void)external_linkage_class{};
   (void)module_linkage_class{};
-  (void)internal_linkage_class{};
   (void)external_linkage_var;
   (void)module_linkage_var;
+
+  // FIXME: Issue #61427 Internal-linkage declarations in the interface TU
+  // should not be not visible here.
+  (void)internal_linkage_class{};
   (void)internal_linkage_var;
 }
 
Index: clang/test/CXX/module/basic/basic.def.odr/p4.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p4.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p4.cppm
@@ -5,9 +5,9 @@
 // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %t/Module.cppm --implicit-check-not unused
 //
 // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple -emit-module-interface -o %t/Module.pcm
-// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple -fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp --implicit-check-not=unused --implicit-check-not=global_module
+// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple -fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp --implicit-check-not=unused --implicit-check-not=global_module
 //
-// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple -fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp --implicit-check-not=unused --implicit-check-not=global_module
+// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple -fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp --implicit-check-not=unused --implicit-check-not=global_module
 
 //--- Module.cppm
 // CHECK-DAG: @extern_var_global_module = external {{(dso_local )?}}global
@@ -143,9 +143,6 @@
   (void)&inline_var_exported;
   (void)&const_var_exported;
 
-  // CHECK: define {{.*}}@_ZL26used_static_module_linkagev
-  used_static_module_linkage();
-
   // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline

[PATCH] D144844: [C++20] [Modules] Offer -fno-import-inter-module-function-defs to avoid duplicated compilation in modules

2023-03-15 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D144844#4195633 , @ChuanqiXu wrote:

>> However, "performance" also includes compilation speed in the 'no 
>> optimisation, debug' case - that is also considered very important. So, 
>> perhaps, the short-term approach should be (as @dblaikie suggested) to 
>> include the bodies for -O >= 3?
>
> I don't think so. I think "performance" refers to the runtime performance 
> generally. I don't believe the normal users will be happy if modules will 
> decrease the performance of their program in any means. So I think we should 
> include the bodies by default.

I think I must be misunderstanding something here.

The default for clang is to compile without optimisation - this benefits the 
compile-edit-debug cycle, by providing output that is closest to the original 
source, and quickest to compile.

The user should not be expecting any optimisations to be applied unless they 
supply `-ON` (n fact, they might we complain if we optimise something that 
makes debugging harder).

So, we should try to ensure that adding modules supports that model - and 
provides the quickest and closest to the original sources for the default 
options.  If the user wants better optimisation (at the expense of longer 
compile times), then they provide `-ON`, right?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144844

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


[PATCH] D144844: [C++20] [Modules] Offer -fno-import-inter-module-function-defs to avoid duplicated compilation in modules

2023-03-15 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D144844#4195316 , @ChuanqiXu wrote:

> Got your points. Let's postpone this one.
>
> But I want to emphasize that this patch (and the thin PCM) will decrease the 
> performance. While LTO can save the regression, LTO is not widely used. 
> (ThinLTO can only mitigate this.) I mean the default behavior shouldn't cause 
> performance regression. We can offer a new alternative  for the users but we 
> can't enable that by default simply now.

Agree that we (ideally, at least) should not decrease performance with a new 
feature.
However, "performance" also includes compilation speed in the 'no optimisation, 
debug' case - that is also considered very important.  So, perhaps, the 
short-term approach should be (as @dblaikie suggested) to include the bodies 
for `-O` >= 3?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144844

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-03-14 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D145965#4192051 , @iains wrote:

> 



> I was thinking at one stage to add an 'Implementation' module Kind, but at 
> the moment I do not think it is worth extending the size of the ModuleKind 
> enum bit field for this (since we now have used up all the entries with the 
> new 'ExplicitGlobalModuleFragment' case).  That also has a large impact also 
> for relatively few uses.

I have changed my mind here.
It seems that we are getting confusing decl context entries without having a 
proper module for the implementation (even though we will never write such a 
module to a PCM, since it is not importable).

I was wondering if it would be possible to avoid having separate values for 
PartitionInterface/Implementation (since they both have a BMI - it is only a 
question of whether that can be re-exported).  We would have to add one bit to 
the PCM to deal with that, so that we might as well extend the ModuleKind enum 
to 4 bits.

So .. please wait for one or two days, I will try to refresh the implementation 
patch (D126959 ) and see if that resolves 
some of the issues I am seeing with `P1815`

(this does not alter the situation that you are going to revisit the 
`isModuleUnitOfCurrentTU` if that is needed - but it might not be; since having 
a separate module for the impl. will avoid some of the ambiguities anyway).

Additional Note:  we also have a situation in the lookups for dependent names 
during template instantiation that the visibility of decls can need to be 
assessed in a different module context from the current module.  So that we 
might also need to have a `areTheseModulesFromTheSameTU(Module *A. Module *B)`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D144844: [C++20] [Modules] Offer -fno-import-inter-module-function-defs to avoid duplicated compilation in modules

2023-03-14 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D144844#4193568 , @dblaikie wrote:

> Seem to recall @iains and others were concerned about the number of modules 
> flags - this one I'd be inclined to suggest we shouldn't add if possible. If 
> one way or the other is generally better - we should, at least initially, 
> dictate that behavior entirely until someone can demonstrate divergent use 
> cases that seem reasonable to support but must have different behavior here.

Agreed, [IMO, at least] we have a very large set of modules options, and 
expanding that should only be done if no sensible alternative can be found (we 
are already seeing users getting confused about which ones apply in each case).

A second point here - that (once we have the ability to generate object and PCM 
in the same compilation) that we will move to elide the function bodies for 
non-inline and non-dependent cases from the PCM, so that this problem will 
magically "go away" (to restore the current behaviour, we'd then be using some 
optimisation control to avoid the elision, I suppose).

> The performance of cross-module inlining could be achieved with something 
> like ThinLTO if we were to lean in favor of not allowing cross-module 
> inlining by default, for instance.

+1 this seems exactly what LTO is intended for (also there are folks who seem 
to have an expectation that the BMI somehow magically contains an optimised 
representation of the source - which again is the province of LTO).

> But if there are particular idioms where cross-module inlining is 
> disadvantageous, perhaps we can implement better ways for clang to detect 
> them (or if they're undetectable, offer users a way to annotate their code, 
> maybe).

I'd be interested to see an example where cross-module function body imports 
somehow beats the equivalent LTO.

> Could we key off -Os or -Oz or some other existing optimization/compile time 
> tradeoff flags instead of introducing a new flag?

That's an interesting idea .. I'd suggest we should default the behaviour to 
"off" (so that compilation speed is prioritised for default options, as usual) 
and then maybe enable import of function bodie at O3 
 or so? [maybe even an optimisation 
representative of LTO .. so that when we slim the BMIs down we do not get 
complaints about regression in code performance].


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144844

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-03-14 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D145965#4192072 , @ChuanqiXu wrote:

> In D145965#4192051 , @iains wrote:
>
>> 



>>
>>
>>
>> The checks for internal-linkage symbols and the improvements to diagnostics 
>> do not depend on **how** `Sema::isModuleUnitOfCurrentTU` is implemented, so 
>> that I think we could fix these problems and then deal with the refactoring 
>> later.
>>
>> In either case, I do not have much time to work more on this right now.
>
> I'll try to make it.

Perhaps then, we can split out the changes to `Sema::isModuleUnitOfCurrentTU` 
and see how much of the functionality is still working (with the intent that 
the full fix will come along  later).

So if this is split into two

1. the fix to `Sema::isModuleUnitOfCurrentTU`  (which you will be updating) and
2. the uses of that to fix the lookups and diagnostics?

(I can use both as a temporary fix ..  but 2 could be applied with the existing 
`isModuleUnitOfCurrentTU` implementation).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-03-14 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D145965#4191973 , @ChuanqiXu wrote:

> Yeah, it is indeed a problem that `Sema::isModuleUnitOfCurrentTU` doesn't 
> work for implementation units. And I have been thinking about this for a 
> while. My thought is that the root cause may be that we shouldn't push the 
> module interface to `Sema::ModuleScopes()` for the implementation unit. (We 
> need some other small refactoring).

I think it is not small refactoring - we make extensive use of 
"getCurrentModule()" to determine if we are processing a module and the 
interface to know which module the implementation belongs to.

If we add the implicitly imported interface to "imports" instead of the module 
scope we will need to make sure that we deal with all these cases where we rely 
on the interface module for this information.

I was thinking at one stage to add an 'Implementation' module Kind, but at the 
moment I do not think it is worth extending the size of the ModuleKind enum bit 
field for this (since we now have used up all the entries with the new 
'ExplicitGlobalModuleFragment' case).  That also has a large impact also for 
relatively few uses.

> I feel this is more natural and consistent.

Yes, if we were starting from 0, that is so - but we have an implementation 
with long history - we would need to see the impact. [I am not against making 
this cleaner, but concerned about the amount of change].

> I thought to take this one but we didn't use implementation units in the 
> downstream and there is no related issue reports.

I was wondering whether some of the reports filed naming duplicate and clashing 
symbols could be related, but I did not analyse.

> So I didn't start to work on it... If you are not hurry, I'd like to take 
> this. Otherwise I'd suggest you to try the above method I mentioned.

I was working on this because it was affecting my P1815 
 stuff - but I can use this patch as a 
temporary solution.

> BTW, I suggest we file an issue first if we want to do something. So that we 
> can avoid solving the same problem.

There are (I think your)  FIXMEs in the testcases (but I do not know if there 
is a corresponding PR).




The checks for internal-linkage symbols and the improvements to diagnostics do 
not depend on **how** `Sema::isModuleUnitOfCurrentTU` is implemented, so that I 
think we could fix these problems and then deal with the refactoring later.

In either case, I do not have much time to work more on this right now.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145965

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


[PATCH] D145965: [C++20][Modules] Fix incorrect visibilities in implementation units.

2023-03-14 Thread Iain Sandoe via Phabricator via cfe-commits
iains created this revision.
Herald added a subscriber: ChuanqiXu.
Herald added a project: All.
iains added a reviewer: ChuanqiXu.
iains added a comment.
iains published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

notes:
a) I need to update the commit log message so that it formats properly in the 
browser
b) since we are now seeing performance complaints against modules, and some of 
these routines are used many times (sometimes several time per name), I have 
tried to structure tests so that the cheapest ones execute first - and likewise 
the utility routines.


Some of the testcases committed during the merging of modules contain
FIXMEs concerning the visibility of declarations with internal-linkage in
module interface units as seen from module implementation units.

This is, in part, caused by an oversight in the utility routine that determines
whether a module is part of the current TU or not.

The lookup definition for `visible` was also too wide, failing to account
cases where a module was visible, but some declarations from it were not.

This patch has three components:
 1/ Fixing the behaviour of the `isModuleUnitOfCurrentTU` utility function to

  return the correct result for module implementation units.

2/ Checking for visibility of imported decls and excluding thsose with

  internal linkage (when from a different TU) or from a private module
  fragment.

3/ Updating the diagnostics in reponse to 1 and 2, in particular dealing

  better with the case that the user attempts to use a module-local linkage
  item in an importing TU (we now provide a fixit to indicate that the item
  needs to be exported to be used). When we search for possible "typos",
  which we do in response to failing to find an entity, we do so allowing
  finds of 'hidden' names.  Before we offer names found this as possible
  typo fixes, we need to check that they would be viable if not hidden.

There are a number of basically mechanical changes to tests to accommodate
the fixed rejection of relevant declarations and the improved diagnostic
messages.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145965

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Lookup.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaLookup.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p2.cppm
  clang/test/CXX/module/module.import/p2.cpp
  clang/test/CXX/module/module.interface/p2.cpp
  clang/test/CXX/module/module.interface/p7.cpp
  clang/test/CXX/module/module.reach/ex1.cpp
  clang/test/CXX/module/module.reach/p2.cpp
  clang/test/CXX/module/module.reach/p5.cpp
  clang/test/Modules/Reachability-template-default-arg.cpp
  clang/test/Modules/cxx20-10-1-ex2.cpp
  clang/test/Modules/deduction-guide3.cppm
  clang/test/Modules/diagnose-missing-import.m

Index: clang/test/Modules/diagnose-missing-import.m
===
--- clang/test/Modules/diagnose-missing-import.m
+++ clang/test/Modules/diagnose-missing-import.m
@@ -6,9 +6,9 @@
 
 void foo(void) {
   XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \
-  expected-error {{declaration of 'XYZLogEvent' must be imported}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \
-  expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
+  expected-error {{declaration of 'XYZLogEvent' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}} \
+  expected-error {{declaration of 'xyzRiskyCloseOpenParam' is internal to 'NCI.A'}}
 }
 
 // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}}
Index: clang/test/Modules/deduction-guide3.cppm
===
--- clang/test/Modules/deduction-guide3.cppm
+++ clang/test/Modules/deduction-guide3.cppm
@@ -19,8 +19,8 @@
 //--- Use.cpp
 import Templ;
 void func() {
-Templ t(5); // expected-error {{declaration of 'Templ' must be imported from module 'Templ' before it is required}}
+Templ t(5); // expected-error {{declaration of 'Templ' is private to module 'Templ'}}
 // expected-error@-1 {{unknown type

[PATCH] D145886: [C++2x][Modules] Amend module purview constant linkage [P2788R0].

2023-03-13 Thread Iain Sandoe via Phabricator via cfe-commits
iains created this revision.
Herald added a project: All.
iains added a reviewer: ChuanqiXu.
iains updated this revision to Diff 504524.
iains added a comment.
iains updated this revision to Diff 504591.
iains added a reviewer: rsmith.
iains published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

rebase, remove use of fmodule-file=X=path to attempt to resolve Windows fail.


iains added a comment.

rebased, try to fix Windows CI, take 2.


iains added a comment.

I should definitely check to make sure that this was adopted as a DR against 
C++20 (otherwise we would need to use the previous test conditionally on < 2b).


This paper has been applied to the working draft and is believed to be
a DR against C++20, so that the patch here makes the change unconditionally.

for:

  export module A;
  
  const int mod_cst = 10;

Before the change, mod_cst would have internal linkage; after the change it
has module linkage.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145886

Files:
  clang/lib/AST/Decl.cpp
  clang/test/CXX/module/basic/basic.def.odr/p4.cppm
  clang/test/CXX/module/basic/basic.link/p3.cppm


Index: clang/test/CXX/module/basic/basic.link/p3.cppm
===
--- clang/test/CXX/module/basic/basic.link/p3.cppm
+++ clang/test/CXX/module/basic/basic.link/p3.cppm
@@ -3,7 +3,7 @@
 
 export module M;
 
-// CHECK-NOT: @_ZW1M1a ={{.*}}
+// CHECK: @_ZW1M1a ={{.*}} constant i32 1
 const int a = 1;
 // CHECK: @_ZW1M1b ={{.*}} constant i32 2
 export const int b = 2;
Index: clang/test/CXX/module/basic/basic.def.odr/p4.cppm
===
--- clang/test/CXX/module/basic/basic.def.odr/p4.cppm
+++ clang/test/CXX/module/basic/basic.def.odr/p4.cppm
@@ -5,9 +5,9 @@
 // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple 
-emit-llvm -o - | FileCheck %t/Module.cppm --implicit-check-not unused
 //
 // RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple 
-emit-module-interface -o %t/Module.pcm
-// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple 
-fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
+// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple 
-fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
 //
-// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple 
-fmodule-file=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
+// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple 
-fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp 
--implicit-check-not=unused --implicit-check-not=global_module
 
 //--- Module.cppm
 // CHECK-DAG: @extern_var_global_module = external {{(dso_local )?}}global
@@ -30,7 +30,7 @@
 // permitted to run the initializer for this variable.
 // CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr 
{{(dso_local )?}}global
 // CHECK-DAG: @_ZL25static_var_module_linkage = internal
-// CHECK-DAG: @_ZL24const_var_module_linkage = internal
+// CHECK-DAG: @_ZW6Module24const_var_module_linkage = {{(dso_local )?}}constant
 //
 // CHECK-DAG: @_ZW6Module25unused_var_module_linkage = {{(dso_local )?}}global 
i32 4
 
@@ -129,7 +129,7 @@
 // CHECK-DAG: @_ZW6Module25extern_var_module_linkage = external {{(dso_local 
)?}}global
 // CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr 
{{(dso_local )?}}global
 // CHECK-DAG: @_ZL25static_var_module_linkage = internal {{(dso_local 
)?}}global i32 0,
-// CHECK-DAG: @_ZL24const_var_module_linkage = internal {{(dso_local 
)?}}constant i32 3,
+// CHECK-DAG: @_ZW6Module24const_var_module_linkage = available_externally 
{{(dso_local )?}}constant i32 3,
 
 module Module;
 
Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -600,6 +600,12 @@
   llvm_unreachable("unexpected module ownership kind");
 }
 
+static bool isDeclaredInModuleInterfaceOrPartition(const NamedDecl *D) {
+  if (auto *M = D->getOwningModule())
+return M->isInterfaceOrPartition();
+  return false;
+}
+
 static LinkageInfo getInternalLinkageFor(const NamedDecl *D) {
   return LinkageInfo::internal();
 }
@@ -642,15 +648,15 @@
   if (const auto *Var = dyn_cast(D)) {
 // - a non-template variable of non-volatile const-qualified type, unless
 //   - it is explicitly declared extern, or
-//   - it is inline or exported, or
+//   - it is declared in the purview of a module interface unit
+// (outside the private-module-fragment, if any) or module partition, 
or
+//   - it is inline, or
 //   - it was previously declar

[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-02-02 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGcdd44e2c8554: [C++20][Modules] Handle template declarations 
in header units. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -22,6 +22,8 @@
 
 int bad_var_definition = 3;  // expected-error {{non-inline external 
definitions are not permitted in C++ header units}}
 
+/* The cases below should compile without diagnostics.  */
+
 class A {
 public:
 // This is a declaration instead of definition.
@@ -36,3 +38,32 @@
   S(S&);
 };
 S::S(S&) = default;
+
+template 
+_X tmpl_var_ok_0 = static_cast<_X>(-1);
+
+template 
+constexpr _T tmpl_var_ok_1 = static_cast<_T>(42);
+
+inline int a = tmpl_var_ok_1;
+
+template  class _T>
+constexpr int tmpl_var_ok_2 = _T<_Tp>::value ? 42 : 6174 ;
+
+template
+int tmpl_OK (_Ep) { return 0; }
+
+template 
+bool
+operator==(_T1& , _T1& ) { return false; }
+
+constexpr long one_k = 1000L;
+
+template 
+void* tmpl_fn_ok
+(_Args ...__args) { return nullptr; }
+
+inline int foo (int a) {
+  return tmpl_OK (a);
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13090,9 +13090,10 @@
   // C++ [module.import/6] external definitions are not permitted in header
   // units.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  VDecl->isThisDeclarationADefinition() &&
+  !VDecl->isInvalidDecl() && VDecl->isThisDeclarationADefinition() &&
   VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !VDecl->isInline()) {
+  !VDecl->isInline() && !VDecl->isTemplated() &&
+  !isa(VDecl)) {
 Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
 VDecl->setInvalidDecl();
   }
@@ -15261,9 +15262,10 @@
   // FIXME: Consider an alternate location for the test where the inlined()
   // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  !FD->isInvalidDecl() && !FD->isInlined() &&
+  BodyKind != FnBodyKind::Delete && BodyKind != FnBodyKind::Default &&
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
-  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+  !FD->isTemplated() && !FD->isTemplateInstantiation()) {
 assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -22,6 +22,8 @@
 
 int bad_var_definition = 3;  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
 
+/* The cases below should compile without diagnostics.  */
+
 class A {
 public:
 // This is a declaration instead of definition.
@@ -36,3 +38,32 @@
   S(S&);
 };
 S::S(S&) = default;
+
+template 
+_X tmpl_var_ok_0 = static_cast<_X>(-1);
+
+template 
+constexpr _T tmpl_var_ok_1 = static_cast<_T>(42);
+
+inline int a = tmpl_var_ok_1;
+
+template  class _T>
+constexpr int tmpl_var_ok_2 = _T<_Tp>::value ? 42 : 6174 ;
+
+template
+int tmpl_OK (_Ep) { return 0; }
+
+template 
+bool
+operator==(_T1& , _T1& ) { return false; }
+
+constexpr long one_k = 1000L;
+
+template 
+void* tmpl_fn_ok
+(_Args ...__args) { return nullptr; }
+
+inline int foo (int a) {
+  return tmpl_OK (a);
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13090,9 +13090,10 @@
   // C++ [module.import/6] external definitions are not permitted in header
   // units.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  VDecl->isThisDeclarationADefinition() &&
+  !VDecl->isInvalidDecl() && VDecl->isThisDeclarationADefinition() &&
   VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !VDecl->isInline()) {
+  !VDecl->isInline() && !VDecl->isTemplated() &&
+  !isa(VDecl)) {
 Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
 VDecl->setInvalidDecl();
   }
@@ -15261,9 +15262,10 @@
   // FIXME: Consider an alternate location for the test where the inlined()
   // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  !FD->is

[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-31 Thread Iain Sandoe via Phabricator via cfe-commits
iains added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:15265
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  !FD->isInvalidDecl() && !IsFnTemplate && BodyKind != FnBodyKind::Delete 
&&
   BodyKind != FnBodyKind::Default && !FD->isInlined()) {

ChuanqiXu wrote:
> iains wrote:
> > iains wrote:
> > > ChuanqiXu wrote:
> > > > iains wrote:
> > > > > rsmith wrote:
> > > > > > Would it make sense to use `!isa(D)` here 
> > > > > > instead of adding `IsFnTemplate`?
> > > > > > Would it make sense to use `!isa(D)` here 
> > > > > > instead of adding `IsFnTemplate`?
> > > > > 
> > > > > I have changed this to use FD->isTemplated() to match the changes for 
> > > > > VarDecls - where the template decl is not available.  Would it be 
> > > > > better to use the isa<>() ?
> > > > > 
> > > > It looks not bad to me to use `isTemplated ()`. And it looks like 
> > > > `!FD->isTemplateInstantiation()` is not tested? And it looks a little 
> > > > bit odd since the instantiated template should be implicitly inline.
> > > > It looks not bad to me to use `isTemplated ()`. 
> > > 
> > > Hmm. now I am not sure what you prefer; in a previous review there was an 
> > > objection to not using the provided function in the decl class.  
> > > 
> > > What would be your suggestion here?
> > > 
> > > (we cannot use isa when testing the variables case 
> > > because the caller pulls out the templated decl before we get to test it) 
> > > - so it is more consistent (IMO) to use the same interface in both tests.
> > > 
> > > >And it looks like `!FD->isTemplateInstantiation()` is not tested?
> > > 
> > > Please could you expand a bit on what you mean here?
> > >  (the test is clearly required, in practice)
> > > 
> > > > And it looks a little bit odd since the instantiated template should be 
> > > > implicitly inline.
> > > 
> > > Did you see @dlaikie's comment on this topic above?
> > > 
> > > 
> > 
> > > Did you see @dlaikie's comment on this topic above?
> > 
> > sorry @dblaikie 's comment is in the PR 
> > (https://github.com/llvm/llvm-project/issues/60079#issuecomment-1406856501)
> > What would be your suggestion here?
> 
> I prefer `isTemplated ()` here. If I get things correct,  `isTemplated ()` 
> will cover the case that a non-template function decl inside a function 
> template. And `isa(D)` wouldn't handle the case. 
> According to my understanding problem, we should avoid all the dependent 
> cases.
> 
> > Please could you expand a bit on what you mean here?
> 
> I mean I didn't find function template instantiation in tests of this 
> revision page.
> 
> > sorry @dblaikie 's comment is in the PR 
> > (https://github.com/llvm/llvm-project/issues/60079#issuecomment-1406856501)
> 
> oh, this is because the inconsistent use of `inline` in different places.. 
> this may be the price we need to pay.

> > Please could you expand a bit on what you mean here?
> 
> I mean I didn't find function template instantiation in tests of this 
> revision page.

added.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

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


[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-31 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 493546.
iains marked 2 inline comments as done.
iains added a comment.

rebased, added tests for instantiated variable/function templates.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -22,6 +22,8 @@
 
 int bad_var_definition = 3;  // expected-error {{non-inline external 
definitions are not permitted in C++ header units}}
 
+/* The cases below should compile without diagnostics.  */
+
 class A {
 public:
 // This is a declaration instead of definition.
@@ -36,3 +38,32 @@
   S(S&);
 };
 S::S(S&) = default;
+
+template 
+_X tmpl_var_ok_0 = static_cast<_X>(-1);
+
+template 
+constexpr _T tmpl_var_ok_1 = static_cast<_T>(42);
+
+inline int a = tmpl_var_ok_1;
+
+template  class _T>
+constexpr int tmpl_var_ok_2 = _T<_Tp>::value ? 42 : 6174 ;
+
+template
+int tmpl_OK (_Ep) { return 0; }
+
+template 
+bool
+operator==(_T1& , _T1& ) { return false; }
+
+constexpr long one_k = 1000L;
+
+template 
+void* tmpl_fn_ok
+(_Args ...__args) { return nullptr; }
+
+inline int foo (int a) {
+  return tmpl_OK (a);
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13089,9 +13089,10 @@
   // C++ [module.import/6] external definitions are not permitted in header
   // units.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  VDecl->isThisDeclarationADefinition() &&
+  !VDecl->isInvalidDecl() && VDecl->isThisDeclarationADefinition() &&
   VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !VDecl->isInline()) {
+  !VDecl->isInline() && !VDecl->isTemplated() &&
+  !isa(VDecl)) {
 Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
 VDecl->setInvalidDecl();
   }
@@ -15260,9 +15261,10 @@
   // FIXME: Consider an alternate location for the test where the inlined()
   // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  !FD->isInvalidDecl() && !FD->isInlined() &&
+  BodyKind != FnBodyKind::Delete && BodyKind != FnBodyKind::Default &&
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
-  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+  !FD->isTemplated() && !FD->isTemplateInstantiation()) {
 assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -22,6 +22,8 @@
 
 int bad_var_definition = 3;  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
 
+/* The cases below should compile without diagnostics.  */
+
 class A {
 public:
 // This is a declaration instead of definition.
@@ -36,3 +38,32 @@
   S(S&);
 };
 S::S(S&) = default;
+
+template 
+_X tmpl_var_ok_0 = static_cast<_X>(-1);
+
+template 
+constexpr _T tmpl_var_ok_1 = static_cast<_T>(42);
+
+inline int a = tmpl_var_ok_1;
+
+template  class _T>
+constexpr int tmpl_var_ok_2 = _T<_Tp>::value ? 42 : 6174 ;
+
+template
+int tmpl_OK (_Ep) { return 0; }
+
+template 
+bool
+operator==(_T1& , _T1& ) { return false; }
+
+constexpr long one_k = 1000L;
+
+template 
+void* tmpl_fn_ok
+(_Args ...__args) { return nullptr; }
+
+inline int foo (int a) {
+  return tmpl_OK (a);
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13089,9 +13089,10 @@
   // C++ [module.import/6] external definitions are not permitted in header
   // units.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  VDecl->isThisDeclarationADefinition() &&
+  !VDecl->isInvalidDecl() && VDecl->isThisDeclarationADefinition() &&
   VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !VDecl->isInline()) {
+  !VDecl->isInline() && !VDecl->isTemplated() &&
+  !isa(VDecl)) {
 Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
 VDecl->setInvalidDecl();
   }
@@ -15260,9 +15261,10 @@
   // FIXME: Consider an alternate location for the test where the inlined()
   // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  !FD->isInvalidDecl() && !FD->isInlined() &&
+  BodyKind != FnBodyKind::Dele

[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-30 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

I think we need to find a way to proceed - because this causes a regression on 
the llvm-16 branch, and that should be resolved soon, if possible.
What is your suggestion for a way forward?




Comment at: clang/lib/Sema/SemaDecl.cpp:15265
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  !FD->isInvalidDecl() && !IsFnTemplate && BodyKind != FnBodyKind::Delete 
&&
   BodyKind != FnBodyKind::Default && !FD->isInlined()) {

iains wrote:
> ChuanqiXu wrote:
> > iains wrote:
> > > rsmith wrote:
> > > > Would it make sense to use `!isa(D)` here instead 
> > > > of adding `IsFnTemplate`?
> > > > Would it make sense to use `!isa(D)` here instead 
> > > > of adding `IsFnTemplate`?
> > > 
> > > I have changed this to use FD->isTemplated() to match the changes for 
> > > VarDecls - where the template decl is not available.  Would it be better 
> > > to use the isa<>() ?
> > > 
> > It looks not bad to me to use `isTemplated ()`. And it looks like 
> > `!FD->isTemplateInstantiation()` is not tested? And it looks a little bit 
> > odd since the instantiated template should be implicitly inline.
> > It looks not bad to me to use `isTemplated ()`. 
> 
> Hmm. now I am not sure what you prefer; in a previous review there was an 
> objection to not using the provided function in the decl class.  
> 
> What would be your suggestion here?
> 
> (we cannot use isa when testing the variables case because 
> the caller pulls out the templated decl before we get to test it) - so it is 
> more consistent (IMO) to use the same interface in both tests.
> 
> >And it looks like `!FD->isTemplateInstantiation()` is not tested?
> 
> Please could you expand a bit on what you mean here?
>  (the test is clearly required, in practice)
> 
> > And it looks a little bit odd since the instantiated template should be 
> > implicitly inline.
> 
> Did you see @dlaikie's comment on this topic above?
> 
> 

> Did you see @dlaikie's comment on this topic above?

sorry @dblaikie 's comment is in the PR 
(https://github.com/llvm/llvm-project/issues/60079#issuecomment-1406856501)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

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


[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-30 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

I think we need to find a way to proceed - because this causes a regression on 
the llvm-16 branch, and that should be resolved soon, if possible.
What is your suggestion for a way forward?




Comment at: clang/lib/Sema/SemaDecl.cpp:15265
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  !FD->isInvalidDecl() && !IsFnTemplate && BodyKind != FnBodyKind::Delete 
&&
   BodyKind != FnBodyKind::Default && !FD->isInlined()) {

ChuanqiXu wrote:
> iains wrote:
> > rsmith wrote:
> > > Would it make sense to use `!isa(D)` here instead 
> > > of adding `IsFnTemplate`?
> > > Would it make sense to use `!isa(D)` here instead 
> > > of adding `IsFnTemplate`?
> > 
> > I have changed this to use FD->isTemplated() to match the changes for 
> > VarDecls - where the template decl is not available.  Would it be better to 
> > use the isa<>() ?
> > 
> It looks not bad to me to use `isTemplated ()`. And it looks like 
> `!FD->isTemplateInstantiation()` is not tested? And it looks a little bit odd 
> since the instantiated template should be implicitly inline.
> It looks not bad to me to use `isTemplated ()`. 

Hmm. now I am not sure what you prefer; in a previous review there was an 
objection to not using the provided function in the decl class.  

What would be your suggestion here?

(we cannot use isa when testing the variables case because the 
caller pulls out the templated decl before we get to test it) - so it is more 
consistent (IMO) to use the same interface in both tests.

>And it looks like `!FD->isTemplateInstantiation()` is not tested?

Please could you expand a bit on what you mean here?
 (the test is clearly required, in practice)

> And it looks a little bit odd since the instantiated template should be 
> implicitly inline.

Did you see @dlaikie's comment on this topic above?




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

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


[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-29 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

AFAICT the failing test is unrelated to this patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

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


[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-28 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked an inline comment as done.
iains added a comment.

In D142704#4088217 , @Arthapz wrote:

> tried the patch and it seems to work with libstdc++ but not with libc++
>
>   
>   > rm -rf .xmake build; xmake f --toolchain=clang 
> --cxxflags="-stdlib=libc++"; xmake b  
>  
>   checking for platform ... linux
>   checking for architecture ... x86_64
>   
>   [ 88%]: compiling.release src/main.cpp
>   error: /usr/bin/../include/c++/v1/ostream:254:20: error: 
> 'std::basic_ostream::operator<<' from module 
> '/usr/bin/../include/c++/v1/complex' is not present in definition of 
> 'std::ostream' in module '/usr/bin/../include/c++/v1/iostream'
>   basic_ostream& operator<<(basic_streambuf* 
> __sb);
>  ^
>   /usr/bin/../include/c++/v1/ostream:221:20: note: declaration of 
> 'operator<<' does not match
>   basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&))
>  ^
>   
>   
>   using namespace std;
>   
>   int main(int argc, char** argv)
>   {
>   cout << "hello world!" << endl;
>   return 0;
>   }

These seem to be a different diagnostic, do you find that is in some way 
related to the changes in D140261  + follow 
on patches?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

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


[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-28 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked an inline comment as done.
iains added a comment.

in my local testing, I was able to consume all libc++ headers individually.




Comment at: clang/lib/Sema/SemaDecl.cpp:15265
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  !FD->isInvalidDecl() && !IsFnTemplate && BodyKind != FnBodyKind::Delete 
&&
   BodyKind != FnBodyKind::Default && !FD->isInlined()) {

rsmith wrote:
> Would it make sense to use `!isa(D)` here instead of 
> adding `IsFnTemplate`?
> Would it make sense to use `!isa(D)` here instead of 
> adding `IsFnTemplate`?

I have changed this to use FD->isTemplated() to match the changes for VarDecls 
- where the template decl is not available.  Would it be better to use the 
isa<>() ?



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

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


[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-28 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 493014.
iains added a comment.

rebased, and revised to handle variable templates and instantiations.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -22,6 +22,8 @@
 
 int bad_var_definition = 3;  // expected-error {{non-inline external 
definitions are not permitted in C++ header units}}
 
+/* The cases below should compile without diagnostics.  */
+
 class A {
 public:
 // This is a declaration instead of definition.
@@ -36,3 +38,26 @@
   S(S&);
 };
 S::S(S&) = default;
+
+template 
+_X tmpl_var_ok_0 = static_cast<_X>(-1);
+
+template 
+constexpr _T tmpl_var_ok_1 = static_cast<_T>(42);
+
+template  class _T>
+constexpr int tmpl_var_ok_2 = _T<_Tp>::value ? 42 : 6174 ;
+
+template
+int tmpl_OK (_Ep) { return 0; }
+
+template 
+bool
+operator==(_T1& , _T1& ) { return false; }
+
+constexpr long one_k = 1000L;
+
+template 
+void* tmpl_fn_ok
+(_Args ...__args) { return nullptr; }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13088,9 +13088,10 @@
   // C++ [module.import/6] external definitions are not permitted in header
   // units.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  VDecl->isThisDeclarationADefinition() &&
+  !VDecl->isInvalidDecl() && VDecl->isThisDeclarationADefinition() &&
   VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !VDecl->isInline()) {
+  !VDecl->isInline() && !VDecl->isTemplated() &&
+  !isa(VDecl)) {
 Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
 VDecl->setInvalidDecl();
   }
@@ -15259,9 +15260,10 @@
   // FIXME: Consider an alternate location for the test where the inlined()
   // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  !FD->isInvalidDecl() && !FD->isInlined() &&
+  BodyKind != FnBodyKind::Delete && BodyKind != FnBodyKind::Default &&
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
-  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+  !FD->isTemplated() && !FD->isTemplateInstantiation()) {
 assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -22,6 +22,8 @@
 
 int bad_var_definition = 3;  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
 
+/* The cases below should compile without diagnostics.  */
+
 class A {
 public:
 // This is a declaration instead of definition.
@@ -36,3 +38,26 @@
   S(S&);
 };
 S::S(S&) = default;
+
+template 
+_X tmpl_var_ok_0 = static_cast<_X>(-1);
+
+template 
+constexpr _T tmpl_var_ok_1 = static_cast<_T>(42);
+
+template  class _T>
+constexpr int tmpl_var_ok_2 = _T<_Tp>::value ? 42 : 6174 ;
+
+template
+int tmpl_OK (_Ep) { return 0; }
+
+template 
+bool
+operator==(_T1& , _T1& ) { return false; }
+
+constexpr long one_k = 1000L;
+
+template 
+void* tmpl_fn_ok
+(_Args ...__args) { return nullptr; }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13088,9 +13088,10 @@
   // C++ [module.import/6] external definitions are not permitted in header
   // units.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  VDecl->isThisDeclarationADefinition() &&
+  !VDecl->isInvalidDecl() && VDecl->isThisDeclarationADefinition() &&
   VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !VDecl->isInline()) {
+  !VDecl->isInline() && !VDecl->isTemplated() &&
+  !isa(VDecl)) {
 Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
 VDecl->setInvalidDecl();
   }
@@ -15259,9 +15260,10 @@
   // FIXME: Consider an alternate location for the test where the inlined()
   // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  !FD->isInvalidDecl() && !FD->isInlined() &&
+  BodyKind != FnBodyKind::Delete && BodyKind != FnBodyKind::Default &&
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
-  BodyKind != FnBodyKind::Default && !F

[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-27 Thread Iain Sandoe via Phabricator via cfe-commits
iains planned changes to this revision.
iains added a comment.

this is necessary, but not sufficient (I need to make additions)  .. no need to 
review yet.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142704

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


[PATCH] D142704: [C++20][Modules] Handle template declarations in header units.

2023-01-27 Thread Iain Sandoe via Phabricator via cfe-commits
iains created this revision.
Herald added a project: All.
iains added reviewers: dblaikie, ChuanqiXu.
iains published this revision for review.
iains added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

@dblaikie - I suspect that this would be useful on the llvm-16 release branch, 
and so I've added you as a reviewer, if you have some chance to look ..
 (I do not think @ChuanqiXu is available until February).

The issue here is that the function decl is extracted from function templates 
(and looks just like any other function definition at this point), so that we 
need to remember that it came from a template.


This addresses part of https://github.com/llvm/llvm-project/issues/60079

The test for external functions was not considering function templates.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142704

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -22,6 +22,8 @@
 
 int bad_var_definition = 3;  // expected-error {{non-inline external 
definitions are not permitted in C++ header units}}
 
+/* The cases below should compile without diagnostics.  */
+
 class A {
 public:
 // This is a declaration instead of definition.
@@ -36,3 +38,10 @@
   S(S&);
 };
 S::S(S&) = default;
+
+template
+int tmpl_OK (_Ep) { return 0; }
+
+template 
+bool
+operator==(_T1& , _T1& ) { return false; }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15108,10 +15108,12 @@
   }
 
   FunctionDecl *FD = nullptr;
+  bool IsFnTemplate = false;
 
-  if (FunctionTemplateDecl *FunTmpl = dyn_cast(D))
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast(D)) {
 FD = FunTmpl->getTemplatedDecl();
-  else
+IsFnTemplate = true;
+  } else
 FD = cast(D);
 
   // Do not push if it is a lambda because one is already pushed when building
@@ -15260,7 +15262,7 @@
   // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  !FD->isInvalidDecl() && !IsFnTemplate && BodyKind != FnBodyKind::Delete 
&&
   BodyKind != FnBodyKind::Default && !FD->isInlined()) {
 assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -22,6 +22,8 @@
 
 int bad_var_definition = 3;  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
 
+/* The cases below should compile without diagnostics.  */
+
 class A {
 public:
 // This is a declaration instead of definition.
@@ -36,3 +38,10 @@
   S(S&);
 };
 S::S(S&) = default;
+
+template
+int tmpl_OK (_Ep) { return 0; }
+
+template 
+bool
+operator==(_T1& , _T1& ) { return false; }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15108,10 +15108,12 @@
   }
 
   FunctionDecl *FD = nullptr;
+  bool IsFnTemplate = false;
 
-  if (FunctionTemplateDecl *FunTmpl = dyn_cast(D))
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast(D)) {
 FD = FunTmpl->getTemplatedDecl();
-  else
+IsFnTemplate = true;
+  } else
 FD = cast(D);
 
   // Do not push if it is a lambda because one is already pushed when building
@@ -15260,7 +15262,7 @@
   // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
   FD->getFormalLinkage() == Linkage::ExternalLinkage &&
-  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  !FD->isInvalidDecl() && !IsFnTemplate && BodyKind != FnBodyKind::Delete &&
   BodyKind != FnBodyKind::Default && !FD->isInlined()) {
 assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140927: [C++20][Modules] Fix named module import diagnostics.

2023-01-22 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG53a1314ed1b5: [C++20][Modules] Fix named module import 
diagnostics. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140927

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/Modules/cxx20-import-diagnostics-a.cpp
  clang/test/Modules/cxx20-import-diagnostics-b.cpp

Index: clang/test/Modules/cxx20-import-diagnostics-b.cpp
===
--- /dev/null
+++ clang/test/Modules/cxx20-import-diagnostics-b.cpp
@@ -0,0 +1,61 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/a.cpp -o %t/a.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/c.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/c.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/d.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/d.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/e.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/e.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/a-part.cpp \
+// RUN: -o %t/a-part.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/f.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/f.pcm -verify
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/g.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/g.pcm -verify
+
+//--- a.cpp
+export module a;
+
+//--- b.hpp
+import a;
+
+//--- c.cpp
+module;
+#include "b.hpp"
+export module c;
+
+//--- d.cpp
+module;
+import a;
+
+export module d;
+
+//--- e.cpp
+export module e;
+
+module :private;
+import a;
+
+//--- a-part.cpp
+export module a:part;
+
+//--- f.cpp
+module;
+import :part ; // expected-error {{module partition imports cannot be in the global module fragment}}
+
+export module f;
+
+//--- g.cpp
+
+export module g;
+module :private;
+import :part; // expected-error {{module partition imports cannot be in the private module fragment}}
Index: clang/test/Modules/cxx20-import-diagnostics-a.cpp
===
--- clang/test/Modules/cxx20-import-diagnostics-a.cpp
+++ clang/test/Modules/cxx20-import-diagnostics-a.cpp
@@ -95,14 +95,13 @@
 //--- import-diags-tu7.cpp
 
 module;
-// We can only have preprocessor directives here, which permits an include-
-// translated header unit.  However those are identified specifically by the
-// preprocessor; non-preprocessed user code should not contain an 'import' here.
-import B; // expected-error {{module imports cannot be in the global module fragment}}
-
+// We can only have preprocessor directives here, which permits
+// header units (include-translated or not) and named modules.
+import B;
 export module D;
 
 int delta ();
+// expected-no-diagnostics
 
 //--- import-diags-tu8.cpp
 
@@ -112,7 +111,7 @@
 
 module :private;
 
-import B; // expected-error {{module imports cannot be in the private module fragment}}
+import B; // expected-error {{imports must immediately follow the module declaration}}
 
 //--- import-diags-tu9.cpp
 
Index: clang/lib/Sema/SemaModule.cpp
===
--- clang/lib/Sema/SemaModule.cpp
+++ clang/lib/Sema/SemaModule.cpp
@@ -591,9 +591,6 @@
  (ModuleScopes.back().ModuleInterface ||
   (getLangOpts().CPlusPlusModules &&
ModuleScopes.back().Module->isGlobalModule( {
-assert((!ModuleScopes.back().Module->isGlobalModule() ||
-Mod->Kind == Module::ModuleKind::ModuleHeaderUnit) &&
-   "should only be importing a header unit into the GMF");
 // Re-export the module if the imported module is exported.
 // Note that we don't need to add re-exported module to Imports field
 // since `Exports` implies the module is imported already.
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -750,6 +750,10 @@
 else if (ImportState == Sema::ModuleImportState::ImportAllowed)
   // Non-imports disallow further imports.
   ImportState = Sema::ModuleImportState::ImportFinished;
+else if (ImportState ==
+ Sema::ModuleImportState::PrivateFragmentImportAllowed)
+  // Non-imports disallow further imports.
+  ImportState = Sema::ModuleImportState::PrivateFragmentImportFinished;
   }
   return false;
 }
@@ -2427,7 +2431,9 @@
 SourceLocation PrivateLoc = ConsumeToken();
 DiagnoseAndSkipCXX11Attributes();
 ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi);
-ImportState = Sema::ModuleImportState::PrivateFragment;
+ImportState = ImportState == Sema::ModuleImportState::ImportAllowe

[PATCH] D141908: [C++20][Modules] Handle defaulted and deleted functions in header units.

2023-01-21 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGff70e22f08d9: [C++20][Modules] Handle defaulted and deleted 
functions in header units. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141908

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,15 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
+  // FIXME: Consider an alternate location for the test where the inlined()
+  // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,15 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
+  // FIXME: Consider an alternate location for the test where the inlined()
+  // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141908: [C++20][Modules] Handle defaulted and deleted functions in header units.

2023-01-18 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 490383.
iains added a comment.

rebased.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141908

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,15 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
+  // FIXME: Consider an alternate location for the test where the inlined()
+  // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,15 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
+  // FIXME: Consider an alternate location for the test where the inlined()
+  // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140927: [C++20][Modules] Fix named module import diagnostics.

2023-01-18 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 490099.
iains added a comment.

rebased


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140927

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/Modules/cxx20-import-diagnostics-a.cpp
  clang/test/Modules/cxx20-import-diagnostics-b.cpp

Index: clang/test/Modules/cxx20-import-diagnostics-b.cpp
===
--- /dev/null
+++ clang/test/Modules/cxx20-import-diagnostics-b.cpp
@@ -0,0 +1,61 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/a.cpp -o %t/a.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/c.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/c.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/d.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/d.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/e.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/e.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/a-part.cpp \
+// RUN: -o %t/a-part.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/f.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/f.pcm -verify
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/g.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/g.pcm -verify
+
+//--- a.cpp
+export module a;
+
+//--- b.hpp
+import a;
+
+//--- c.cpp
+module;
+#include "b.hpp"
+export module c;
+
+//--- d.cpp
+module;
+import a;
+
+export module d;
+
+//--- e.cpp
+export module e;
+
+module :private;
+import a;
+
+//--- a-part.cpp
+export module a:part;
+
+//--- f.cpp
+module;
+import :part ; // expected-error {{module partition imports cannot be in the global module fragment}}
+
+export module f;
+
+//--- g.cpp
+
+export module g;
+module :private;
+import :part; // expected-error {{module partition imports cannot be in the private module fragment}}
Index: clang/test/Modules/cxx20-import-diagnostics-a.cpp
===
--- clang/test/Modules/cxx20-import-diagnostics-a.cpp
+++ clang/test/Modules/cxx20-import-diagnostics-a.cpp
@@ -95,14 +95,13 @@
 //--- import-diags-tu7.cpp
 
 module;
-// We can only have preprocessor directives here, which permits an include-
-// translated header unit.  However those are identified specifically by the
-// preprocessor; non-preprocessed user code should not contain an 'import' here.
-import B; // expected-error {{module imports cannot be in the global module fragment}}
-
+// We can only have preprocessor directives here, which permits
+// header units (include-translated or not) and named modules.
+import B;
 export module D;
 
 int delta ();
+// expected-no-diagnostics
 
 //--- import-diags-tu8.cpp
 
@@ -112,7 +111,7 @@
 
 module :private;
 
-import B; // expected-error {{module imports cannot be in the private module fragment}}
+import B; // expected-error {{imports must immediately follow the module declaration}}
 
 //--- import-diags-tu9.cpp
 
Index: clang/lib/Sema/SemaModule.cpp
===
--- clang/lib/Sema/SemaModule.cpp
+++ clang/lib/Sema/SemaModule.cpp
@@ -591,9 +591,6 @@
  (ModuleScopes.back().ModuleInterface ||
   (getLangOpts().CPlusPlusModules &&
ModuleScopes.back().Module->isGlobalModule( {
-assert((!ModuleScopes.back().Module->isGlobalModule() ||
-Mod->Kind == Module::ModuleKind::ModuleHeaderUnit) &&
-   "should only be importing a header unit into the GMF");
 // Re-export the module if the imported module is exported.
 // Note that we don't need to add re-exported module to Imports field
 // since `Exports` implies the module is imported already.
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -750,6 +750,10 @@
 else if (ImportState == Sema::ModuleImportState::ImportAllowed)
   // Non-imports disallow further imports.
   ImportState = Sema::ModuleImportState::ImportFinished;
+else if (ImportState ==
+ Sema::ModuleImportState::PrivateFragmentImportAllowed)
+  // Non-imports disallow further imports.
+  ImportState = Sema::ModuleImportState::PrivateFragmentImportFinished;
   }
   return false;
 }
@@ -2427,7 +2431,9 @@
 SourceLocation PrivateLoc = ConsumeToken();
 DiagnoseAndSkipCXX11Attributes();
 ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi);
-ImportState = Sema::ModuleImportState::PrivateFragment;
+ImportState = ImportState == Sema::ModuleImportState::ImportAllowed
+  ? Sema::ModuleImportState::PrivateFragmentImportAllowed
+  : Sema::ModuleImportState::PrivateFragmentImportFinished;

[PATCH] D141908: [C++20][Modules] Handle defaulted and deleted functions in header units.

2023-01-18 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D141908#4061451 , @ChuanqiXu wrote:

>> Well.. we have time for another iteration,
>
> I am going to take a vacation for the Chinese New Year since tomorrow to 
> February. So I am a little bit hurried : )

(I added the FIXME) Have a good holiday!




Comment at: clang/lib/Sema/SemaDecl.cpp:15258
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&

ChuanqiXu wrote:
> iains wrote:
> > ChuanqiXu wrote:
> > > iains wrote:
> > > > ChuanqiXu wrote:
> > > > > I prefer to add a FIXME here to say that we need to find a better 
> > > > > place for the check to eliminate the unnecessary check for `BodyKind 
> > > > > `. The current check for `BodyKind` looks a little bit hacky to me.
> > > > When the patch was originally done, this was found to be a good place 
> > > > to do the check (i.e. less duplication of testing and to avoid 
> > > > duplication of diagnostics) so I do not think I agree that there is a 
> > > > FIXME to move it.
> > > > 
> > > > BodyKind is already used elsewhere in this function for similar 
> > > > purposes - it does not look hacky to me.
> > > It looks hacky to me since we shouldn't care if it is deleted or 
> > > defaulted here and it should be enough to check `FD->isInlied()`.  And I 
> > > don't see similar usage of `BodyKind ` in this function.
> > > It looks hacky to me since we shouldn't care if it is deleted or 
> > > defaulted here and it should be enough to check `FD->isInlied()`. 
> > 
> > that means checking much later and in muliple places, I think - but if you 
> > want to make a follow-on patch, I will be happy to review.
> > 
> > > And I don't see similar usage of `BodyKind ` in this function.
> > 
> > line 15208?
> > 
> > 
> > line 15208?
> 
> line 15208 checks the wording `unless the function is deleted (C++ specifc, 
> C++ [dcl.fct.def.general]p2)`. So it is used to check if this is a delete 
> function, which looks fine. I mean it would be best if we can check 
> `FD->isInlined()` only.
> 
> > that means checking much later and in muliple places, I think - but if you 
> > want to make a follow-on patch, I will be happy to review.
> 
> I think I won't work on this. But it would be meaningful for future 
> developers. And it looks not impossible to refactor it. (I'm not asking you 
> to do the change)

> > that means checking much later and in muliple places, I think - but if you 
> > want to make a follow-on patch, I will be happy to review.
> 
> I think I won't work on this. But it would be meaningful for future 
> developers. 

I re-checked (to remind myself) .. essentially that state is set by 
SetFunctionBodyKind() which is called much later.  I still think we would most 
likely end up with having to place the diagnostic in multiple places.  However, 
I added the FIXME,

> And it looks not impossible to refactor it. (I'm not asking you to do the 
> change)

such a refactoring looks non-trivial and certainly not suitable for a few days 
before a branch ...



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141908

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


[PATCH] D141908: [C++20][Modules] Handle defaulted and deleted functions in header units.

2023-01-18 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 490079.
iains marked 5 inline comments as done.
iains added a comment.

address review commments, add an assert and a FIXME.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141908

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,15 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
+  // FIXME: Consider an alternate location for the test where the inlined()
+  // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,15 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
+  // FIXME: Consider an alternate location for the test where the inlined()
+  // state is complete.
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
+assert(FD->isThisDeclarationADefinition());
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141908: [C++20][Modules] Handle defaulted and deleted functions in header units.

2023-01-18 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked 2 inline comments as done.
iains added a comment.

In D141908#4061409 , @ChuanqiXu wrote:

> LGTM basically. I still feel we need a FIXME there. But I don't want to block 
> this for this reason especially we need to land this before the branch.

Well.. we have time for another iteration, I will add the assert...




Comment at: clang/lib/Sema/SemaDecl.cpp:15258
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&

ChuanqiXu wrote:
> iains wrote:
> > ChuanqiXu wrote:
> > > I prefer to add a FIXME here to say that we need to find a better place 
> > > for the check to eliminate the unnecessary check for `BodyKind `. The 
> > > current check for `BodyKind` looks a little bit hacky to me.
> > When the patch was originally done, this was found to be a good place to do 
> > the check (i.e. less duplication of testing and to avoid duplication of 
> > diagnostics) so I do not think I agree that there is a FIXME to move it.
> > 
> > BodyKind is already used elsewhere in this function for similar purposes - 
> > it does not look hacky to me.
> It looks hacky to me since we shouldn't care if it is deleted or defaulted 
> here and it should be enough to check `FD->isInlied()`.  And I don't see 
> similar usage of `BodyKind ` in this function.
> It looks hacky to me since we shouldn't care if it is deleted or defaulted 
> here and it should be enough to check `FD->isInlied()`. 

that means checking much later and in muliple places, I think - but if you want 
to make a follow-on patch, I will be happy to review.

> And I don't see similar usage of `BodyKind ` in this function.

line 15208?





Comment at: clang/lib/Sema/SemaDecl.cpp:15261
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind == FnBodyKind::Other &&
+  !FD->isInlined()) {

ChuanqiXu wrote:
> iains wrote:
> > ChuanqiXu wrote:
> > > It looks like we need to check `FD->isThisDeclarationADefinition()` too.
> > > 
> > > And personally, I prefer to check BodyKind explicitly. Otherwise the 
> > > readers need to checkout the definition of `FnBodyKind` to understand the 
> > > code. 
> > > It looks like we need to check `FD->isThisDeclarationADefinition()` too.
> > 
> > This is an unnecessary test, it will always return true at this point.
> > 
> > > And personally, I prefer to check BodyKind explicitly. Otherwise the 
> > > readers need to checkout the definition of `FnBodyKind` to understand the 
> > > code. 
> > 
> > You prefer two tests  instead of one?
> > OK, I guess
> > This is an unnecessary test, it will always return true at this point.
> 
> Oh, I found it now. It may be better to have an assertion 
> `assert(FD->isThisDeclarationADefinition())`.
yeah, I was thinking maybe to do that (it is kind of documenting that it is 
always true - perhaps a comment would be better?)



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141908

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


[PATCH] D141908: [C++20][Modules] Handle defaulted and deleted functions in header units.

2023-01-18 Thread Iain Sandoe via Phabricator via cfe-commits
iains added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:15258
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&

ChuanqiXu wrote:
> I prefer to add a FIXME here to say that we need to find a better place for 
> the check to eliminate the unnecessary check for `BodyKind `. The current 
> check for `BodyKind` looks a little bit hacky to me.
When the patch was originally done, this was found to be a good place to do the 
check (i.e. less duplication of testing and to avoid duplication of 
diagnostics) so I do not think I agree that there is a FIXME to move it.

BodyKind is already used elsewhere in this function for similar purposes - it 
does not look hacky to me.



Comment at: clang/lib/Sema/SemaDecl.cpp:15261
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind == FnBodyKind::Other &&
+  !FD->isInlined()) {

ChuanqiXu wrote:
> It looks like we need to check `FD->isThisDeclarationADefinition()` too.
> 
> And personally, I prefer to check BodyKind explicitly. Otherwise the readers 
> need to checkout the definition of `FnBodyKind` to understand the code. 
> It looks like we need to check `FD->isThisDeclarationADefinition()` too.

This is an unnecessary test, it will always return true at this point.

> And personally, I prefer to check BodyKind explicitly. Otherwise the readers 
> need to checkout the definition of `FnBodyKind` to understand the code. 

You prefer two tests  instead of one?
OK, I guess


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141908

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


[PATCH] D141908: [C++20][Modules] Handle defaulted and deleted functions in header units.

2023-01-18 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 490062.
iains added a comment.

rebased, address review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141908

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,12 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,12 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
+  BodyKind != FnBodyKind::Default && !FD->isInlined()) {
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141908: [C++20][Modules] Handle defaulted and deleted functions in header units.

2023-01-17 Thread Iain Sandoe via Phabricator via cfe-commits
iains created this revision.
Herald added a project: All.
iains added a reviewer: ChuanqiXu.
iains published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Address part of https://github.com/llvm/llvm-project/issues/60079.

Deleted and Defaulted functions are implicitly inline, but that state
is not set at the point that we perform the diagnostic checks for externally-
visible non-inline functions; check the function body type explicitly in the
diagnostic.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141908

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,12 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind == FnBodyKind::Other &&
+  !FD->isInlined()) {
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }


Index: clang/test/CXX/module/module.import/p6.cpp
===
--- clang/test/CXX/module/module.import/p6.cpp
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -28,3 +28,11 @@
 static const int value = 43; 
 };
 
+void deleted_fn_ok (void) = delete;
+
+struct S {
+   ~S() noexcept(false) = default;
+private:
+  S(S&);
+};
+S::S(S&) = default;
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15254,9 +15254,12 @@
   }
 
   // C++ [module.import/6] external definitions are not permitted in header
-  // units.
+  // units.  Deleted and Defaulted functions are implicitly inline (but the
+  // inline state is not set at this point, so check the BodyKind explicitly).
   if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
-  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+  FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !FD->isInvalidDecl() && BodyKind == FnBodyKind::Other &&
+  !FD->isInlined()) {
 Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
 FD->setInvalidDecl();
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140261: [C++20][Modules] Do not allow non-inline external definitions in header units.

2023-01-08 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG335668b11643: [C++20][Modules] Do not allow non-inline 
external definitions in header units. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140261

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp
  clang/test/CodeGenCXX/module-initializer-header.cppm

Index: clang/test/CodeGenCXX/module-initializer-header.cppm
===
--- clang/test/CodeGenCXX/module-initializer-header.cppm
+++ clang/test/CodeGenCXX/module-initializer-header.cppm
@@ -8,24 +8,24 @@
 //
 //--- header.h
 int foo();
-int i = foo();
+static int i = foo();
 
 //--- M.cppm
 module;
 import "header.h";
 export module M;
 
-// CHECK: @i = {{.*}}global i32 0
+// CHECK: @_ZL1i = {{.*}}global i32 0
 // CHECK: void @__cxx_global_var_init()
 // CHECK-NEXT: entry:
 // CHECK-NEXT:  %call = call noundef{{.*}} i32 @_Z3foov()
-// CHECK-NEXT:  store i32 %call, ptr @i  
+// CHECK-NEXT:  store i32 %call, ptr @_ZL1i
 
 //--- Use.cpp
 import "header.h";
 
-// CHECK: @i = {{.*}}global i32 0
+// CHECK: @_ZL1i = {{.*}}global i32 0
 // CHECK: void @__cxx_global_var_init()
 // CHECK-NEXT: entry:
 // CHECK-NEXT:  %call = call noundef{{.*}} i32 @_Z3foov()
-// CHECK-NEXT:  store i32 %call, ptr @i  
+// CHECK-NEXT:  store i32 %call, ptr @_ZL1i
Index: clang/test/CXX/module/module.import/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -0,0 +1,24 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -x c++-header %t/bad-header-unit.h \
+// RUN:  -emit-header-unit -o %t/bad-header-unit.pcm -verify
+
+//--- bad-header-unit.h
+
+inline int ok_foo () { return 0;}
+
+static int ok_bar ();
+
+int ok_decl ();
+
+int bad_def () { return 2;}  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
+
+inline int ok_inline_var = 1;
+
+static int ok_static_var;
+
+int ok_var_decl;
+
+int bad_var_definition = 3;  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
+
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13071,6 +13071,15 @@
   VDecl->setInvalidDecl();
   }
 
+  // C++ [module.import/6] external definitions are not permitted in header
+  // units.
+  if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !VDecl->isInline()) {
+Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
+VDecl->setInvalidDecl();
+  }
+
   // If adding the initializer will turn this declaration into a definition,
   // and we already have a definition for this variable, diagnose or otherwise
   // handle the situation.
@@ -15224,6 +15233,14 @@
 }
   }
 
+  // C++ [module.import/6] external definitions are not permitted in header
+  // units.
+  if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
+FD->setInvalidDecl();
+  }
+
   // Ensure that the function's exception specification is instantiated.
   if (const FunctionProtoType *FPT = FD->getType()->getAs())
 ResolveExceptionSpec(D->getLocation(), FPT);
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -2325,6 +2325,12 @@
 return ModuleScopes.empty() ? false : ModuleScopes.back().ModuleInterface;
   }
 
+  /// Is the module scope we are in a C++ Header Unit?
+  bool currentModuleIsHeaderUnit() const {
+return ModuleScopes.empty() ? false
+: ModuleScopes.back().Module->isHeaderUnit();
+  }
+
   /// Get the module owning an entity.
   Module *getOwningModule(const Decl *Entity) {
 return Entity->getOwningModule();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11236,6 +11236,8 @@
   "add 'export' here if this is intended to be a module interface unit">;
 def err_invalid_module_name : Error<
   "%0 is %select{an invalid|a reserved}1 name for a module">;
+def err_extern_def_in_header_unit : Error<
+  "non-inline external definitions are not permitted in C++ header units">;
 
 def ext_equivalent_internal_lin

[PATCH] D140261: [C++20][Modules] Do not allow non-inline external definitions in header units.

2023-01-04 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

how does that look?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140261

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


[PATCH] D140261: [C++20][Modules] Do not allow non-inline external definitions in header units.

2023-01-04 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 486202.
iains added a comment.

rebase, added release notes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140261

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp
  clang/test/CodeGenCXX/module-initializer-header.cppm

Index: clang/test/CodeGenCXX/module-initializer-header.cppm
===
--- clang/test/CodeGenCXX/module-initializer-header.cppm
+++ clang/test/CodeGenCXX/module-initializer-header.cppm
@@ -8,24 +8,24 @@
 //
 //--- header.h
 int foo();
-int i = foo();
+static int i = foo();
 
 //--- M.cppm
 module;
 import "header.h";
 export module M;
 
-// CHECK: @i = {{.*}}global i32 0
+// CHECK: @_ZL1i = {{.*}}global i32 0
 // CHECK: void @__cxx_global_var_init()
 // CHECK-NEXT: entry:
 // CHECK-NEXT:  %call = call noundef{{.*}} i32 @_Z3foov()
-// CHECK-NEXT:  store i32 %call, ptr @i  
+// CHECK-NEXT:  store i32 %call, ptr @_ZL1i
 
 //--- Use.cpp
 import "header.h";
 
-// CHECK: @i = {{.*}}global i32 0
+// CHECK: @_ZL1i = {{.*}}global i32 0
 // CHECK: void @__cxx_global_var_init()
 // CHECK-NEXT: entry:
 // CHECK-NEXT:  %call = call noundef{{.*}} i32 @_Z3foov()
-// CHECK-NEXT:  store i32 %call, ptr @i  
+// CHECK-NEXT:  store i32 %call, ptr @_ZL1i
Index: clang/test/CXX/module/module.import/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -0,0 +1,24 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -x c++-header %t/bad-header-unit.h \
+// RUN:  -emit-header-unit -o %t/bad-header-unit.pcm -verify
+
+//--- bad-header-unit.h
+
+inline int ok_foo () { return 0;}
+
+static int ok_bar ();
+
+int ok_decl ();
+
+int bad_def () { return 2;}  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
+
+inline int ok_inline_var = 1;
+
+static int ok_static_var;
+
+int ok_var_decl;
+
+int bad_var_definition = 3;  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
+
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -13071,6 +13071,15 @@
   VDecl->setInvalidDecl();
   }
 
+  // C++ [module.import/6] external definitions are not permitted in header
+  // units.
+  if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !VDecl->isInline()) {
+Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
+VDecl->setInvalidDecl();
+  }
+
   // If adding the initializer will turn this declaration into a definition,
   // and we already have a definition for this variable, diagnose or otherwise
   // handle the situation.
@@ -15229,6 +15238,14 @@
 }
   }
 
+  // C++ [module.import/6] external definitions are not permitted in header
+  // units.
+  if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
+FD->setInvalidDecl();
+  }
+
   // Ensure that the function's exception specification is instantiated.
   if (const FunctionProtoType *FPT = FD->getType()->getAs())
 ResolveExceptionSpec(D->getLocation(), FPT);
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -2306,6 +2306,12 @@
 return ModuleScopes.empty() ? false : ModuleScopes.back().ModuleInterface;
   }
 
+  /// Is the module scope we are in a C++ Header Unit?
+  bool currentModuleIsHeaderUnit() const {
+return ModuleScopes.empty() ? false
+: ModuleScopes.back().Module->isHeaderUnit();
+  }
+
   /// Get the module owning an entity.
   Module *getOwningModule(const Decl *Entity) {
 return Entity->getOwningModule();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11235,6 +11235,8 @@
   "add 'export' here if this is intended to be a module interface unit">;
 def err_invalid_module_name : Error<
   "%0 is %select{an invalid|a reserved}1 name for a module">;
+def err_extern_def_in_header_unit : Error<
+  "non-inline external definitions are not permitted in C++ header units">;
 
 def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
   "ambiguous use of internal linkage declaration %0 defined in multiple module

[PATCH] D140927: [C++20][Modules] Fix named module import diagnostics.

2023-01-04 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D140927#4024648 , @ChuanqiXu wrote:

> [module.import]p1 says:
>
>> In a module unit, all module-import-declarations and export-declarations 
>> exporting module-import-declarations shall appear before all other 
>> declarations in the declaration-seq of the translation-unit and of the 
>> private-module-fragment (if any).
>
> So the following case is invalid:
>
>   //--- b.hpp
>   void func() {}
>   import a;
>   
>   //--- c.cpp
>   module;
>   #include "b.hpp"
>   export module c;
>
> I feel we'd better to address such cases in the test.

I am not sure about this - what you are suggesting above would seem to make 
modules useless when there is a GMF (since there is almost no point to having a 
GMF that has no decls).

https://eel.is/c++draft/basic.link#1

Make the declaration-see of a module unit specifically follow the module 
keyword.

https://eel.is/c++draft/module#import-1 (which you quoted from above) makes 
adds to this the PMF - but I do not see that it includes the GMF (since that is 
neither the declaration-seq of the module unit nor is it the PMF.

(this + 15.5 named Header Unit import is why the original bug is there .. )


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140927

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


[PATCH] D140927: [C++20][Modules] Fix named module import diagnostics.

2023-01-03 Thread Iain Sandoe via Phabricator via cfe-commits
iains created this revision.
Herald added a subscriber: ChuanqiXu.
Herald added a project: All.
iains added reviewers: ChuanqiXu, dblaikie.
iains added a subscriber: clang-modules.
iains published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

We have been incorrectly disallowing imports of named modules in the
global and private module fragments.

This addresses: https://github.com/llvm/llvm-project/issues/59688


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140927

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaModule.cpp
  clang/test/Modules/cxx20-import-diagnostics-a.cpp
  clang/test/Modules/cxx20-import-diagnostics-b.cpp

Index: clang/test/Modules/cxx20-import-diagnostics-b.cpp
===
--- /dev/null
+++ clang/test/Modules/cxx20-import-diagnostics-b.cpp
@@ -0,0 +1,61 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/a.cpp -o %t/a.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/c.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/c.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/d.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/d.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/e.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/e.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/a-part.cpp \
+// RUN: -o %t/a-part.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/f.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/f.pcm -verify
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface  %t/g.cpp \
+// RUN: -fmodule-file=%t/a.pcm -o %t/g.pcm -verify
+
+//--- a.cpp
+export module a;
+
+//--- b.hpp
+import a;
+
+//--- c.cpp
+module;
+#include "b.hpp"
+export module c;
+
+//--- d.cpp
+module;
+import a;
+
+export module d;
+
+//--- e.cpp
+export module e;
+
+module :private;
+import a;
+
+//--- a-part.cpp
+export module a:part;
+
+//--- f.cpp
+module;
+import :part ; // expected-error {{module partition imports cannot be in the global module fragment}}
+
+export module f;
+
+//--- g.cpp
+
+export module g;
+module :private;
+import :part; // expected-error {{module partition imports cannot be in the private module fragment}}
Index: clang/test/Modules/cxx20-import-diagnostics-a.cpp
===
--- clang/test/Modules/cxx20-import-diagnostics-a.cpp
+++ clang/test/Modules/cxx20-import-diagnostics-a.cpp
@@ -95,14 +95,13 @@
 //--- import-diags-tu7.cpp
 
 module;
-// We can only have preprocessor directives here, which permits an include-
-// translated header unit.  However those are identified specifically by the
-// preprocessor; non-preprocessed user code should not contain an 'import' here.
-import B; // expected-error {{module imports cannot be in the global module fragment}}
-
+// We can only have preprocessor directives here, which permits
+// header units (include-translated or not) and named modules.
+import B;
 export module D;
 
 int delta ();
+// expected-no-diagnostics
 
 //--- import-diags-tu8.cpp
 
@@ -112,7 +111,7 @@
 
 module :private;
 
-import B; // expected-error {{module imports cannot be in the private module fragment}}
+import B; // expected-error {{imports must immediately follow the module declaration}}
 
 //--- import-diags-tu9.cpp
 
Index: clang/lib/Sema/SemaModule.cpp
===
--- clang/lib/Sema/SemaModule.cpp
+++ clang/lib/Sema/SemaModule.cpp
@@ -590,9 +590,6 @@
  (ModuleScopes.back().ModuleInterface ||
   (getLangOpts().CPlusPlusModules &&
ModuleScopes.back().Module->isGlobalModule( {
-assert((!ModuleScopes.back().Module->isGlobalModule() ||
-Mod->Kind == Module::ModuleKind::ModuleHeaderUnit) &&
-   "should only be importing a header unit into the GMF");
 // Re-export the module if the imported module is exported.
 // Note that we don't need to add re-exported module to Imports field
 // since `Exports` implies the module is imported already.
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -750,6 +750,10 @@
 else if (ImportState == Sema::ModuleImportState::ImportAllowed)
   // Non-imports disallow further imports.
   ImportState = Sema::ModuleImportState::ImportFinished;
+else if (ImportState ==
+ Sema::ModuleImportState::PrivateFragmentImportAllowed)
+  // Non-imports disallow further imports.
+  ImportState = Sema::ModuleImportState::PrivateFragmentImportFinished;
   }
   return false;
 }
@@ -2427,7 +2431,9 @@
 SourceLocation PrivateLoc = ConsumeToken();
 DiagnoseAndSkipCXX11Attributes();
 ExpectAndConsumeSemi(diag::err_private_m

[PATCH] D140261: [C++20][Modules] Do not allow non-inline external definitions in header units.

2022-12-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked an inline comment as done.
iains added a comment.

In D140261#4006653 , @ChuanqiXu wrote:

> In D140261#4004542 , @iains wrote:
>
>> OK so this is what I plan to land assuming testing goes OK.
>> I suspect that this might cause some user code to flag errors - there are 
>> quite a number of ODR violations "in the wild".
>
> I forgot we need to mention such changes in 
> https://clang.llvm.org/docs/ReleaseNotes.html#potentially-breaking-changes.

It will not break any existing compilation (we accept headers with non-inline 
external definitions as textual includes, that has not changed).   What I mean 
is that such headers will not be accepted as Header Units - and I am sure some 
users will consider that to be a bug (even though the problem is that the 
header is not ODR safe).
So it's not a change that breaks existing code - because no-one has Header 
Units in existing code.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140261

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


[PATCH] D140261: [C++20][Modules] Do not allow non-inline external definitions in header units.

2022-12-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains marked 2 inline comments as done.
iains added a comment.

OK so this is what I plan to land assuming testing goes OK.
I suspect that this might cause some user code to flag errors - there are quite 
a number of ODR violations "in the wild".




Comment at: clang/lib/Sema/SemaDecl.cpp:12957-12958
+  // units.
+  if (getLangOpts().CPlusPlus20 && getLangOpts().CPlusPlusModules &&
+  !ModuleScopes.empty() && ModuleScopes.back().Module->isHeaderUnit()) {
+if (VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&

ChuanqiXu wrote:
> iains wrote:
> > ChuanqiXu wrote:
> > > `getLangOpts().CPlusPlus20` is redundant. It is also good to define a 
> > > helper interface `withinHeaderUnit` in Sema (not required).
> > I do not mind making this change - but note that the constraint is specific 
> > to C++20 and there are some people who want to remove it (the constraint).  
> > I guess  you meant `getCurrentModule()` ?
> > I do not mind making this change - but note that the constraint is specific 
> > to C++20 and there are some people who want to remove it (the constraint).
> 
> Got it. Let's make it when it comes true. It won't be a big deal.
> 
> > I guess you meant getCurrentModule() ?
> 
> It looks **a little bit** better to me to not access `ModuleScopes` directly.
revised now (I added the helper).



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140261

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


[PATCH] D140261: [C++20][Modules] Do not allow non-inline external definitions in header units.

2022-12-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 483909.
iains added a comment.

rebased, addressed comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140261

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp
  clang/test/CodeGenCXX/module-initializer-header.cppm

Index: clang/test/CodeGenCXX/module-initializer-header.cppm
===
--- clang/test/CodeGenCXX/module-initializer-header.cppm
+++ clang/test/CodeGenCXX/module-initializer-header.cppm
@@ -8,24 +8,24 @@
 //
 //--- header.h
 int foo();
-int i = foo();
+static int i = foo();
 
 //--- M.cppm
 module;
 import "header.h";
 export module M;
 
-// CHECK: @i = {{.*}}global i32 0
+// CHECK: @_ZL1i = {{.*}}global i32 0
 // CHECK: void @__cxx_global_var_init()
 // CHECK-NEXT: entry:
 // CHECK-NEXT:  %call = call noundef{{.*}} i32 @_Z3foov()
-// CHECK-NEXT:  store i32 %call, ptr @i  
+// CHECK-NEXT:  store i32 %call, ptr @_ZL1i  
 
 //--- Use.cpp
 import "header.h";
 
-// CHECK: @i = {{.*}}global i32 0
+// CHECK: @_ZL1i = {{.*}}global i32 0
 // CHECK: void @__cxx_global_var_init()
 // CHECK-NEXT: entry:
 // CHECK-NEXT:  %call = call noundef{{.*}} i32 @_Z3foov()
-// CHECK-NEXT:  store i32 %call, ptr @i  
+// CHECK-NEXT:  store i32 %call, ptr @_ZL1i  
Index: clang/test/CXX/module/module.import/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -0,0 +1,24 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -x c++-header %t/bad-header-unit.h \
+// RUN:  -emit-header-unit -o %t/bad-header-unit.pcm -verify
+
+//--- bad-header-unit.h
+
+inline int ok_foo () { return 0;}
+
+static int ok_bar ();
+
+int ok_decl ();
+
+int bad_def () { return 2;}  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
+
+inline int ok_inline_var = 1;
+
+static int ok_static_var;
+
+int ok_var_decl;
+
+int bad_var_definition = 3;  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
+
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -12952,6 +12952,15 @@
   VDecl->setInvalidDecl();
   }
 
+  // C++ [module.import/6] external definitions are not permitted in header
+  // units.
+  if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
+  !VDecl->isInline()) {
+Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
+VDecl->setInvalidDecl();
+  }
+
   // If adding the initializer will turn this declaration into a definition,
   // and we already have a definition for this variable, diagnose or otherwise
   // handle the situation.
@@ -15100,6 +15109,14 @@
 }
   }
 
+  // C++ [module.import/6] external definitions are not permitted in header
+  // units.
+  if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
+  FD->getFormalLinkage() == Linkage::ExternalLinkage && !FD->isInlined()) {
+Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
+FD->setInvalidDecl();
+  }
+
   // Ensure that the function's exception specification is instantiated.
   if (const FunctionProtoType *FPT = FD->getType()->getAs())
 ResolveExceptionSpec(D->getLocation(), FPT);
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -2306,6 +2306,12 @@
 return ModuleScopes.empty() ? false : ModuleScopes.back().ModuleInterface;
   }
 
+  /// Is the module scope we are in a C++ Header Unit?
+  bool currentModuleIsHeaderUnit() const {
+return ModuleScopes.empty() ? false
+: ModuleScopes.back().Module->isHeaderUnit();
+  }
+
   /// Get the module owning an entity.
   Module *getOwningModule(const Decl *Entity) {
 return Entity->getOwningModule();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11233,6 +11233,8 @@
   "add 'export' here if this is intended to be a module interface unit">;
 def err_invalid_module_name : Error<
   "%0 is %select{an invalid|a reserved}1 name for a module">;
+def err_extern_def_in_header_unit : Error<
+  "non-inline external definitions are not permitted in C++ header units">;
 
 def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
   "ambiguous use of internal linkage declaration %0 defined in multiple modules">,

[PATCH] D140261: [C++20][Modules] Do not allow non-inline external definitions in header units.

2022-12-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:12957-12958
+  // units.
+  if (getLangOpts().CPlusPlus20 && getLangOpts().CPlusPlusModules &&
+  !ModuleScopes.empty() && ModuleScopes.back().Module->isHeaderUnit()) {
+if (VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&

ChuanqiXu wrote:
> `getLangOpts().CPlusPlus20` is redundant. It is also good to define a helper 
> interface `withinHeaderUnit` in Sema (not required).
I do not mind making this change - but note that the constraint is specific to 
C++20 and there are some people who want to remove it (the constraint).  I 
guess  you meant `getCurrentModule()` ?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140261

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


[PATCH] D134589: [C++20][Modules] Elide unused guard variables in Itanium ABI module initializers.

2022-12-18 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbd7f4c561f5e: [C++20][Modules] Elide unused guard variables 
in Itanium ABI moduleā€¦ (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134589

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/test/CodeGenCXX/module-initializer-guard-elision.cpp

Index: clang/test/CodeGenCXX/module-initializer-guard-elision.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/module-initializer-guard-elision.cpp
@@ -0,0 +1,69 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 O.cpp \
+// RUN:-emit-module-interface -o O.pcm
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 O.pcm -S -emit-llvm \
+// RUN:  -o - | FileCheck %s --check-prefix=CHECK-O
+
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 P.cpp \
+// RUN:-emit-module-interface -fmodule-file=O.pcm -o P.pcm
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 P.pcm -S -emit-llvm \
+// RUN:  -o - | FileCheck %s --check-prefix=CHECK-P
+
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 Q.cpp \
+// RUN:-emit-module-interface -fmodule-file=O.pcm -o Q.pcm
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 Q.pcm -S -emit-llvm \
+// RUN:  -o - | FileCheck %s --check-prefix=CHECK-Q
+
+// Testing cases where we can elide the module initializer guard variable.
+
+// This module has no global inits and does not import any other module
+//--- O.cpp
+
+export module O;
+
+export int foo ();
+
+// CHECK-O: define void @_ZGIW1O
+// CHECK-O-LABEL: entry
+// CHECK-O-NEXT: ret void
+// CHECK-O-NOT: @_ZGIW1O__in_chrg
+
+// This has no global inits but imports a module, and therefore needs a guard
+// variable.
+//--- P.cpp
+
+export module P;
+
+export import O;
+export int bar ();
+
+// CHECK-P: define void @_ZGIW1P
+// CHECK-P-LABEL: init
+// CHECK-P: store i8 1, ptr @_ZGIW1P__in_chrg
+// CHECK-P: call void @_ZGIW1O()
+// CHECK-P-NOT: call void @__cxx_global_var_init
+
+// This imports a module and has global inits, so needs a guard.
+//--- Q.cpp
+
+export module Q;
+export import O;
+
+export struct Quack {
+  Quack(){};
+};
+
+export Quack Duck;
+
+export int baz ();
+
+// CHECK-Q: define internal void @__cxx_global_var_init
+// CHECK-Q: call {{.*}} @_ZNW1Q5QuackC1Ev
+// CHECK-Q: define void @_ZGIW1Q
+// CHECK-Q: store i8 1, ptr @_ZGIW1Q__in_chrg
+// CHECK-Q: call void @_ZGIW1O()
+// CHECK-Q: call void @__cxx_global_var_init
+
Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -640,7 +640,12 @@
 
 /* Build the initializer for a C++20 module:
This is arranged to be run only once regardless of how many times the module
-   might be included transitively.  This arranged by using a control variable.
+   might be included transitively.  This arranged by using a guard variable.
+
+   If there are no initalizers at all (and also no imported modules) we reduce
+   this to an empty function (since the Itanium ABI requires that this function
+   be available to a caller, which might be produced by a different
+   implementation).
 
First we call any initializers for imported modules.
We then call initializers for the Global Module Fragment (if present)
@@ -652,13 +657,10 @@
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
 CXXGlobalInits.pop_back();
 
-  // We create the function, even if it is empty, since an importer of this
-  // module will refer to it unconditionally (for the current implementation
-  // there is no way for the importer to know that an importee does not need
-  // an initializer to be run).
-
+  // As noted above, we create the function, even if it is empty.
   // Module initializers for imported modules are emitted first.
-  // Collect the modules that we import
+
+  // Collect all the modules that we import
   SmallVector AllImports;
   // Ones that we export
   for (auto I : Primary->Exports)
@@ -685,7 +687,6 @@
 FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());
 ModuleInits.push_back(Fn);
   }
-  AllImports.clear();
 
   // Add any initializers with specified priority; this uses the same  approach
   // as EmitCXXGlobalInitFunc().
@@ -703,13 +704,11 @@
   for (; I < PrioE; ++I)
 ModuleInits.push_back(I->second);
 }
-PrioritizedCXXGlobalInits.clear();
   }
 
   // Now append the ones without specified priority.
   for (auto *F : CXXGlobalInits)
 ModuleInits.push_back(F);
-  CXXGlobalInits.clear();
 
   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
   const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
@@ -719,7 +718,6 @@
   // each init is run just once (

[PATCH] D134589: [C++20][Modules] Elide unused guard variables in Itanium ABI module initializers.

2022-12-17 Thread Iain Sandoe via Phabricator via cfe-commits
iains updated this revision to Diff 483770.
iains added a comment.

rebased, amended a comment as suggested


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134589

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/test/CodeGenCXX/module-initializer-guard-elision.cpp

Index: clang/test/CodeGenCXX/module-initializer-guard-elision.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/module-initializer-guard-elision.cpp
@@ -0,0 +1,69 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 O.cpp \
+// RUN:-emit-module-interface -o O.pcm
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 O.pcm -S -emit-llvm \
+// RUN:  -o - | FileCheck %s --check-prefix=CHECK-O
+
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 P.cpp \
+// RUN:-emit-module-interface -fmodule-file=O.pcm -o P.pcm
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 P.pcm -S -emit-llvm \
+// RUN:  -o - | FileCheck %s --check-prefix=CHECK-P
+
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 Q.cpp \
+// RUN:-emit-module-interface -fmodule-file=O.pcm -o Q.pcm
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 Q.pcm -S -emit-llvm \
+// RUN:  -o - | FileCheck %s --check-prefix=CHECK-Q
+
+// Testing cases where we can elide the module initializer guard variable.
+
+// This module has no global inits and does not import any other module
+//--- O.cpp
+
+export module O;
+
+export int foo ();
+
+// CHECK-O: define void @_ZGIW1O
+// CHECK-O-LABEL: entry
+// CHECK-O-NEXT: ret void
+// CHECK-O-NOT: @_ZGIW1O__in_chrg
+
+// This has no global inits but imports a module, and therefore needs a guard
+// variable.
+//--- P.cpp
+
+export module P;
+
+export import O;
+export int bar ();
+
+// CHECK-P: define void @_ZGIW1P
+// CHECK-P-LABEL: init
+// CHECK-P: store i8 1, ptr @_ZGIW1P__in_chrg
+// CHECK-P: call void @_ZGIW1O()
+// CHECK-P-NOT: call void @__cxx_global_var_init
+
+// This imports a module and has global inits, so needs a guard.
+//--- Q.cpp
+
+export module Q;
+export import O;
+
+export struct Quack {
+  Quack(){};
+};
+
+export Quack Duck;
+
+export int baz ();
+
+// CHECK-Q: define internal void @__cxx_global_var_init
+// CHECK-Q: call {{.*}} @_ZNW1Q5QuackC1Ev
+// CHECK-Q: define void @_ZGIW1Q
+// CHECK-Q: store i8 1, ptr @_ZGIW1Q__in_chrg
+// CHECK-Q: call void @_ZGIW1O()
+// CHECK-Q: call void @__cxx_global_var_init
+
Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -640,7 +640,12 @@
 
 /* Build the initializer for a C++20 module:
This is arranged to be run only once regardless of how many times the module
-   might be included transitively.  This arranged by using a control variable.
+   might be included transitively.  This arranged by using a guard variable.
+
+   If there are no initalizers at all (and also no imported modules) we reduce
+   this to an empty function (since the Itanium ABI requires that this function
+   be available to a caller, which might be produced by a different
+   implementation).
 
First we call any initializers for imported modules.
We then call initializers for the Global Module Fragment (if present)
@@ -652,13 +657,10 @@
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
 CXXGlobalInits.pop_back();
 
-  // We create the function, even if it is empty, since an importer of this
-  // module will refer to it unconditionally (for the current implementation
-  // there is no way for the importer to know that an importee does not need
-  // an initializer to be run).
-
+  // As noted above, we create the function, even if it is empty.
   // Module initializers for imported modules are emitted first.
-  // Collect the modules that we import
+
+  // Collect all the modules that we import
   SmallVector AllImports;
   // Ones that we export
   for (auto I : Primary->Exports)
@@ -685,7 +687,6 @@
 FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());
 ModuleInits.push_back(Fn);
   }
-  AllImports.clear();
 
   // Add any initializers with specified priority; this uses the same  approach
   // as EmitCXXGlobalInitFunc().
@@ -703,13 +704,11 @@
   for (; I < PrioE; ++I)
 ModuleInits.push_back(I->second);
 }
-PrioritizedCXXGlobalInits.clear();
   }
 
   // Now append the ones without specified priority.
   for (auto *F : CXXGlobalInits)
 ModuleInits.push_back(F);
-  CXXGlobalInits.clear();
 
   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
   const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
@@ -719,7 +718,6 @@
   // each init is run just once (even though a module might be imported
   // multiple times via nested use).
   llvm::Fun

[PATCH] D140261: [C++20][Modules] Do not allow non-inline external definitions in header units.

2022-12-17 Thread Iain Sandoe via Phabricator via cfe-commits
iains created this revision.
Herald added a project: All.
iains added a reviewer: ChuanqiXu.
iains added a subscriber: clang-modules.
iains published this revision for review.
iains added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

this came up during discussion of other header unit constraints, we had not 
implemented it yet.
found a test case where we'd accidentally broken this rule too.


[module.import/6] last sentence:
A header unit shall not contain a definition of a non-inline function or
variable whose name has external linkage.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140261

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.import/p6.cpp
  clang/test/CodeGenCXX/module-initializer-header.cppm

Index: clang/test/CodeGenCXX/module-initializer-header.cppm
===
--- clang/test/CodeGenCXX/module-initializer-header.cppm
+++ clang/test/CodeGenCXX/module-initializer-header.cppm
@@ -8,24 +8,24 @@
 //
 //--- header.h
 int foo();
-int i = foo();
+static int i = foo();
 
 //--- M.cppm
 module;
 import "header.h";
 export module M;
 
-// CHECK: @i = {{.*}}global i32 0
+// CHECK: @_ZL1i = {{.*}}global i32 0
 // CHECK: void @__cxx_global_var_init()
 // CHECK-NEXT: entry:
 // CHECK-NEXT:  %call = call noundef{{.*}} i32 @_Z3foov()
-// CHECK-NEXT:  store i32 %call, ptr @i  
+// CHECK-NEXT:  store i32 %call, ptr @_ZL1i  
 
 //--- Use.cpp
 import "header.h";
 
-// CHECK: @i = {{.*}}global i32 0
+// CHECK: @_ZL1i = {{.*}}global i32 0
 // CHECK: void @__cxx_global_var_init()
 // CHECK-NEXT: entry:
 // CHECK-NEXT:  %call = call noundef{{.*}} i32 @_Z3foov()
-// CHECK-NEXT:  store i32 %call, ptr @i  
+// CHECK-NEXT:  store i32 %call, ptr @_ZL1i  
Index: clang/test/CXX/module/module.import/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/module/module.import/p6.cpp
@@ -0,0 +1,24 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -x c++-header %t/bad-header-unit.h \
+// RUN:  -emit-header-unit -o %t/bad-header-unit.pcm -verify
+
+//--- bad-header-unit.h
+
+inline int ok_foo () { return 0;}
+
+static int ok_bar ();
+
+int ok_decl ();
+
+int bad_def () { return 2;}  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
+
+inline int ok_inline_var = 1;
+
+static int ok_static_var;
+
+int ok_var_decl;
+
+int bad_var_definition = 3;  // expected-error {{non-inline external definitions are not permitted in C++ header units}}
+
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -12952,6 +12952,17 @@
   VDecl->setInvalidDecl();
   }
 
+  // C++ [module.import/6] external definitions are not permitted in header
+  // units.
+  if (getLangOpts().CPlusPlus20 && getLangOpts().CPlusPlusModules &&
+  !ModuleScopes.empty() && ModuleScopes.back().Module->isHeaderUnit()) {
+if (VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
+!VDecl->isInline()) {
+  Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
+  VDecl->setInvalidDecl();
+}
+  }
+
   // If adding the initializer will turn this declaration into a definition,
   // and we already have a definition for this variable, diagnose or otherwise
   // handle the situation.
@@ -15100,6 +15111,17 @@
 }
   }
 
+  // C++ [module.import/6] external definitions are not permitted in header
+  // units.
+  if (getLangOpts().CPlusPlus20 && getLangOpts().CPlusPlusModules &&
+  !ModuleScopes.empty() && ModuleScopes.back().Module->isHeaderUnit()) {
+if (FD->getFormalLinkage() == Linkage::ExternalLinkage &&
+!FD->isInlined()) {
+  Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
+  FD->setInvalidDecl();
+}
+  }
+
   // Ensure that the function's exception specification is instantiated.
   if (const FunctionProtoType *FPT = FD->getType()->getAs())
 ResolveExceptionSpec(D->getLocation(), FPT);
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11233,6 +11233,8 @@
   "add 'export' here if this is intended to be a module interface unit">;
 def err_invalid_module_name : Error<
   "%0 is %select{an invalid|a reserved}1 name for a module">;
+def err_extern_def_in_header_unit : Error<
+  "non-inline external definitions are not permitted in C++ header units">;
 
 def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
   "ambiguous use of internal linkage declaration %0 defined in multiple modules">,
___
cfe-commits mailing list
cfe-commits@lists.

[PATCH] D137059: [Driver] [C++20] [Modules] Support -fmodule-output= (2/2)

2022-12-09 Thread Iain Sandoe via Phabricator via cfe-commits
iains accepted this revision.
iains added a comment.
This revision is now accepted and ready to land.

this LGTM ( but please wait for an ack from @dblaikie ) and again thanks for 
patience in seeing this through.


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

https://reviews.llvm.org/D137059

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


[PATCH] D137058: [Driver] [Modules] Support -fmodule-output (1/2)

2022-12-09 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

thanks all for the patience on this one - and for the collaborative discussion 
- I do think the outcome is going to be an easier to remember option name ;)


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

https://reviews.llvm.org/D137058

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


[PATCH] D137059: [Driver] [Modules] Introduce -fsave-std-c++-module-file= to specify the path of the module file (2/2)

2022-12-05 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D137059#3973016 , @ben.boeckel 
wrote:

> In D137059#3934448 , @dblaikie 
> wrote:
>
>> I'm still curious what about the details of other compilers - I think from 
>> the sounds of it, @iains suggested GCC doesn't support this yet so we'll 
>> need to pick/name the flag ourselves & he's happy to implement whatever we 
>> pick? I guess Microsoft's flag naming is sufficiently differently styled as 
>> to offer no useful inspiration? Though wouldn't hurt to know what they name 
>> it.
>>
>> Any other examples you had in mind, Ben?
>
> GCC supports naming the output file by asking the "module mapper" where a 
> module with a given name lives (also used for finding imported modules).

This is using the "P1184 " interface for both 
tasks - which I think we should keep as a separate mechanism (at least 
mentally) since we can also use that with clang when we implement it.  What the 
interface returns for the name (via P1184 ) is 
decoupled from how the name is determined (potentially by a command line 
argument or from some other build system component).

Currently, GCC does not have a command line spelling for specifying the output 
module name, which is why I say it's still "up for grabs" (actually it would be 
polite to ask on g...@gcc.gnu.org for opinions on the spelling, since it would 
be crazy to have different on at least these two platforms).  The spelling of 
command line options is not IMO bike shedding, it affects day-to-day use of the 
tools.


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

https://reviews.llvm.org/D137059

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


[PATCH] D137609: [C++20] [Modules] Remove unmaintained header modules

2022-11-08 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

I think that (if this change is approved) there will be also some 
simplifications possible in the driver (since the mode that produces a wrapper 
header for multiple command-line headers is different from the mode where 
multiple command line headers would each produce a single C++ standard header 
unit) ..


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

https://reviews.llvm.org/D137609

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


[PATCH] D137058: [Driver] [Modules] Support -fsave-std-c++-module-file (1/2)

2022-11-03 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D137058#3906579 , @dblaikie wrote:

> I realize I got this jumbled up and the thread about "why do we need to name 
> things" is meant to be over in D137059  
> (sorry @ben.boeckel :/ I know this is all confusing to follow at the best of 
> times) so I'll pick that up there.
>
> But maybe a relevant question /here/ (maybe @iains has some context here, and 
> @ben.boeckel ): What are GCC's (& any other implementations) command line 
> interfaces for things like this? How're the command line flags spelled? To 
> see about inspiration for this.

.. the state I have is ...
As you note there are two parts to this:

1. the ability to emit a BMI and object from one invocation of the compiler 
(which can be done as in this series by the driver - or with alternate patches 
in the FE - which allows for the improvements we want in the BMI) 2, How to 
name the BMI.
- in my experimentation with GCC, for this part, it defers the decision 
until the module name is known, and then queries an interface to ask for the 
BMI filename for that named module.  The interface can be internal (e.g. 
choosing a simple default like source.pcm) or it could get the mapping from 
some other place, like a build system.  The FE side of the transaction does not 
need to know how the name was chosen (so it _could_ be specified from a 
command-line flag).
  - but, AFAIR, GCC does not currently have such a flag.

> (judging from the discourse thread with @rsmith it seems like "the ability to 
> generate a .o from a .pcm" is disfavored, he didn't outright say "we should 
> remove that functionality" but pretty close to it - in favor of ".cppm -> 
> {.o, .pcm}" and ".ccpm -> .o" + ".cppm -> .pcm" (without the ability to 
> generate the .o from the .pcm) - in which case we could change the existing 
> driver behavior sooner or later to address that third action (.cppm -> .pcm 
> but it's only a minimal pcm).

This is the strategy my draft patches for the FE aims for (apologies, for 
repeatedly mentioning a patch set that is not yet up for review ...)

Maybe we should have two flags one that says "produce a .pcm" (which we already 
have `--precompile` for that) and another that says "produce a .o" (I guess 
that's the default, so maybe we want a way to opt /out/ of that behavior?))

> Eh, sorry, just talking myself around in circles.
> Currently we have:
> `.cppm` -> `.o` (no extra flags)
> `.cppm` -> `.pcm` (`--precompile`)
> `.cppm` -> `.pcm` + `.o` (unsupported)
>
> I'm not sure that `--precompile` is the best flag name to be inspired by 
> (it's unqualified by any `-f` or other prefix, which usually feels a bit 
> weird, and it's a very generic term, doesn't mention modules, etc) -

GCC has "-fmodule-only" for which I have a patch (also unpublished)  that 
aliases that to --precompile in the driver.
(I think we could possibly see a reason to have -fobject-only for symmetry and 
to cover the cases you mention here)

> so I can appreciate the `-fsave-std-c++-module-file` name here, but it does 
> sound a bit verbose? Wouldn't mind hearing other people's thoughts on flag 
> names, especially any prior art/other implementation choices we could look 
> for for inspiration.

What was the objection to "-fc++-module-filename[=]" ?

As noted above, if my memory is not too faulty, GCC does not have this specific 
[name the BMI] flag yet (I think this is the case because GCC essentially uses 
a simple in-process P1184  interface as the 
fallback when there's no external build system), then this flag name is up for 
grabs - and what is chosen here could, presumably, be implemented for GCC too.

Actually, in some ways clang does something pretty similar in that there's the 
in-process module-mapper - which is where the filenames probably should be 
decided, we just tend to bypass it with specific command line input for output 
filenames (which does not work where there are two names needed, except by 
providing some simplified fallback - like the "just change the extension" 
approach).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137058

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


[PATCH] D137059: [Driver] [Modules] Introduce -fsave-std-c++-module-file= to specify the path of the module file (2/2)

2022-11-01 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D137059#3898482 , @ChuanqiXu wrote:

> In D137059#3898463 , @iains wrote:
>
>> In D137059#3898239 , @ChuanqiXu 
>> wrote:
>>
>>> In D137059#3896661 , @dblaikie 
>>> wrote:
>>>
 Could you link to the email/discourse discussion about supporting this 
 mode (I think you've linked it in other discussions, be good to have it 
 for reference here & Probably in the other review)? (I'm wondering if we 
 need a new flag for this, or if it'll be OK to change the driver behavior 
 to always coalesce the .cppm->.pcm->.o path into a single step, for 
 instance - I realize this is a somewhat breaking change but may be 
 acceptable given that modules aren't widely deployed yet)
>>>
>>> Done. From my reading, in that discourse discussing, we're not talking 
>>> about to add the new flags. I add the flag since I don't want the `.pcm` 
>>> file pollutes the user space accidentally.
>>>
 if it'll be OK to change the driver behavior to always coalesce the 
 .cppm->.pcm->.o path into a single step
>>>
>>> I am not sure what you mean. Do you talk about to forbidden the original 
>>> 2-phase compilation model? If so, I think it is definitely the wrong 
>>> direction. The 2-phase compilation model should be the correct direction in 
>>> the long term since it has higher parallelism.
>>
>> I am not convinced about this second point as motivation for this direction; 
>> it comes with some significant resource tradeoffs (compared with the 
>> proposed [near] future version of producing the PCM and the object from one 
>> invocation of the FE):
>>
>> - it requires multiple instantiations of the FE
>> - it blocks the objective of reducing the content of module interfaces (so 
>> that they only contain the information that pertains to the interface) - 
>> since requiring source -> pcm, pcm -> object means that the PCM has to 
>> contain all the information necessary to generate the object.
>> - in terms of parallelism, the interface PCM has to be generated and 
>> distributed - the parsing and serialisation has to be complete before the 
>> PCM can be distributed; that process is the same regardless of whether the 
>> FE invocation also produces an object.
>>
>> So, I would suggest that we would move to a single invocation of the 
>> compiler to produce the PCM and object as the default; if the user has a 
>> specific reason to want to do the two jobs separately then thay could still 
>> do so ( -fmodule-only / --precompile ) at the expense of two invocations as 
>> now,
>
>
>
>> (so that they only contain the information that pertains to the interface)
>
> No, we can't do this. It hurts the performance.
>
>> it requires multiple instantiations of the FE
>
> Agreed. But if we care about this, I think it may be best to allow the 
> current 2 phase compilation model only.  And we forbid the compilation from 
> module unit to object files directly. This is cleanest approach.
>
>> in terms of parallelism, the interface PCM has to be generated and 
>> distributed - the parsing and serialisation has to be complete before the 
>> PCM can be distributed; that process is the same regardless of whether the 
>> FE invocation also produces an object.
>
> I think the distribution doesn't matter with parallelism. For parallelism, I 
> mean, for the scan-based build systems, the compilation of A must wait until 
> the dependent module B compiles to object files, which is significantly worse 
> than the 2 phase compilation.

Not sure what you mean here;  If there is only one user of a PCM then it does 
not need to be produced (waste of disk space and CPU cycles);
If there are many uses of it (as we might expect in a massively parallel 
distributed build system) then distributing the PCM is important and its 
availability predicates  progress of other builds - from previous discussions 
in WG21 there are users that care very much about the size of distributed 
artefacts.

> ---
>
>> So, I would suggest that we would move to a single invocation of the 
>> compiler to produce the PCM and object as the default;
>
> So the question would be where is the destination place? And if we would 
> offer an option to allow the user to specify the place? This question is 
> discussed in https://reviews.llvm.org/D137058.

Having a mechanism to specify the place for the file is fine by me ( I was only 
commenting on the motivation point for separate pcm and object phases ).

(I think we should move this discussion somewhere else, again - unless it is 
considered a key factor in deciding on this patch, I have no further comments).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137059

___
cfe-commits mailing list

[PATCH] D137059: [Driver] [Modules] Introduce -fsave-std-c++-module-file= to specify the path of the module file (2/2)

2022-11-01 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D137059#3898239 , @ChuanqiXu wrote:

> In D137059#3896661 , @dblaikie 
> wrote:
>
>> Could you link to the email/discourse discussion about supporting this mode 
>> (I think you've linked it in other discussions, be good to have it for 
>> reference here & Probably in the other review)? (I'm wondering if we need a 
>> new flag for this, or if it'll be OK to change the driver behavior to always 
>> coalesce the .cppm->.pcm->.o path into a single step, for instance - I 
>> realize this is a somewhat breaking change but may be acceptable given that 
>> modules aren't widely deployed yet)
>
> Done. From my reading, in that discourse discussing, we're not talking about 
> to add the new flags. I add the flag since I don't want the `.pcm` file 
> pollutes the user space accidentally.
>
>> if it'll be OK to change the driver behavior to always coalesce the 
>> .cppm->.pcm->.o path into a single step
>
> I am not sure what you mean. Do you talk about to forbidden the original 
> 2-phase compilation model? If so, I think it is definitely the wrong 
> direction. The 2-phase compilation model should be the correct direction in 
> the long term since it has higher parallelism.

I am not convinced about this second point as motivation for this direction; it 
comes with some significant resource tradeoffs (compared with the proposed 
[near] future version of producing the PCM and the object from one invocation 
of the FE):

- it requires multiple instantiations of the FE
- it blocks the objective of reducing the content of module interfaces (so that 
they only contain the information that pertains to the interface) - since 
requiring source -> pcm, pcm -> object means that the PCM has to contain all 
the information necessary to generate the object.
- in terms of parallelism, the interface PCM has to be generated and 
distributed - the parsing and serialisation has to be complete before the PCM 
can be distributed; that process is the same regardless of whether the FE 
invocation also produces an object.

So, I would suggest that we would move to a single invocation of the compiler 
to produce the PCM and object as the default; if the user has a specific reason 
to want to do the two jobs separately then thay could still do so ( 
-fmodule-only / --precompile ) at the expense of two invocations as now,


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137059

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


[PATCH] D134267: [C++] [Modules] Support one phase compilation model for named modules

2022-10-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D134267#3870064 , @ChuanqiXu wrote:

> I grepped `options.td` and got (incomplete) list for options to take a output 
> name:
>
>   # -o and its alias
>   -o
>   -object_file_name=
>   --output=
>   
>   /Fa (windows for assembly output filename)
>   /Fe (windows for output executable file name)
>   /Fi (windows for preprocessed output filename)
>   /Fo (Windows for object file)
>   
>   -dependency-dot (for DOT-formatted header dependencies)
>   -dependency-file (to write dependency output to)
>   
>   -header-include-file (Filename to write header include output to)
>   
>   -opt-record-file (Filename to use for YAML optimization record output)
>   
>   -split-dwarf-output (Filename to use for split dwarf debug info output)
>   
>   -stack-usage-file (to write stack usage output to)
>   -coverage-data-file (Emit coverage data to this filename)
>   -coverage-notes-file (Emit coverage notes to this filename)
>
> And it looks like the `-file` appears a lot. So may be the suggestion 
> (`-fc++-module-file-output`) may be better. And for the default location, I 
> feel like my explanation above makes sense. If the end user wants to produce 
> .pcm files, they can use `--precompile` just like what they do with `-c` to 
> get the object files. This only matters with end users since the build 
> systems should/would chose other positions.

OK. I guess the idea about `-fmodule-file==filename` was that, because 
the FE will not try to read `filename` (for module-generation cases) we could 
use it to describe the output file.  However, it seems that might be too 
complex... so `-fc++-module-file-output` seems OK to me.


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

https://reviews.llvm.org/D134267

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


[PATCH] D134267: [C++] [Modules] Support one phase compilation model for named modules

2022-10-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D134267#3869678 , @dblaikie wrote:

> In D134267#3869643 , @iains wrote:
>
>> In D134267#3869614 , @dblaikie 
>> wrote:
>>
>>> In D134267#3869162 , @iains wrote:
>>>
 In D134267#3868830 , @dblaikie 
 wrote:

> I'm OK with sticking with the existing `-fmodule-file` if that works for 
> everyone. Yeah, it's short and ambiguous in a space with many concepts of 
> what a "module file" is, but also the fact that it's a `-f` flag might 
> help disambiguate it a bit - it's probably not the way anyone would 
> think/expect to be passing source files, those just get passed without 
> flags on the command line. And any use of it will show the .pcm extension 
> or whatever that should make it clear enough what's going on.

 hmm (I realise I mentioned this, and hope it has not complicated things) ..

 .. I was thinking of the `-fmodule-file==filename` variant.  The 
 problem with using it without (the ) is that -fmodule-file= can (and 
 does) appear multiple times on the command line to specify dependent 
 modules - so that one would have to specify which (named) module was 
 related to the filename.
>>
>>
>>
>>> I /think/ currently `-fmodule-file` works with Clang header modules 
>>> presumably because the module files contain within them enough information 
>>> to enable the compiler to substitute the module for an include where 
>>> necessary? I'm not sure the `=` part is necessary, as such, if the 
>>> BMIs can reasonably contain enough identifying info to make their use clear 
>>> to the consumer.
>>
>> `-fmodule-file=` works with both `clang` modules  and standard C++ ones.  
>> What it does (as of now) is cause the FE to open the named file and to 
>> pre-load the module name - so that when the FE tries to find a module the 
>> lookup mechanism can associate the module name with the module data.  So, if 
>> we need 3 dependent modules to be available when building a new source .. we 
>> would specify the PCM files containing those modules.
>>
>> At present, if you try to specify a non-existent PCM using `-fmodule-file=` 
>> the compile will fail early on (it is expecting this to indicate a source 
>> module, not a destination one).
>>
>> However, the second syntax `-fmodule-file==filename` I think should be 
>> able to work around this (since it says that the named module  is 
>> associated with the PCM `filename` which would allow us to cater for that 
>> file being missing (when we are creating it).
>
> Would the intent be that this might write out multiple different module 
> files? I would hope we don't need to support that - that we only generate the 
> module file for the single source module passed to the compiler. I guess 
> maybe to support `clang++ x.cppm y.cppm` you might have multiple output 
> files? But in that case you don't get to use `-o` so maybe you don't get to 
> specify the module paths either and just get the default "same as .o but with 
> .pcm suffix" behavior?
>
>> Does that clarify at all ?
>>
>> It would be great not to add more modules options flags, there are already 
>> way to many :/ - but if this seems too complex then one of the spellings 
>> suggested by @ChuanqiXu would work.
>
> Oh, right, super sorry - this is about how to specify the output filename. OK.
>
> (I'd still sort of lean towards "make it the same as the .o, but with the 
> .pcm suffix" and if the build system wants to put things in other places, it 
> can move them around - but I understand why that's not something everyone's 
> on board with)

Actually, I would think that to be a great default (and put it in the CWD just 
like the object),
.. but it seems (in addition to the default) we do need a way to place specific 
module files - and I could imagine needing to make different places for 
different command line option sets.  Asking the driver or build system to move 
the file seems like spawning more processes and we'd still need a user-visible 
way to say where we wanted the file to be put.

> Yeah, if the `-fmodule-file` syntax is currently only for input I don't think 
> we need to try to overload it for output as well.

My understanding [which could be flawed] is that the second syntax (which 
already exists, it's not an invention of this discussion) is intended to allow 
specification of output files.

> Perhaps we could extend the --precompile flag to take a filename? (but then 
> that'd potentially confuse things when you want to produce both PCM and .o, 
> passing `--precompile` currently only produces the .pcm on the main output 
> path... ).

yeah, --precompile is well-defined to produce only the module (and I have a 
patch to alias it to -fmodule-only to match the GCC equivalent), it would not 

[PATCH] D134267: [C++] [Modules] Support one phase compilation model for named modules

2022-10-19 Thread Iain Sandoe via Phabricator via cfe-commits
iains added a comment.

In D134267#3869614 , @dblaikie wrote:

> In D134267#3869162 , @iains wrote:
>
>> In D134267#3868830 , @dblaikie 
>> wrote:
>>
>>> I'm OK with sticking with the existing `-fmodule-file` if that works for 
>>> everyone. Yeah, it's short and ambiguous in a space with many concepts of 
>>> what a "module file" is, but also the fact that it's a `-f` flag might help 
>>> disambiguate it a bit - it's probably not the way anyone would think/expect 
>>> to be passing source files, those just get passed without flags on the 
>>> command line. And any use of it will show the .pcm extension or whatever 
>>> that should make it clear enough what's going on.
>>
>> hmm (I realise I mentioned this, and hope it has not complicated things) ..
>>
>> .. I was thinking of the `-fmodule-file==filename` variant.  The 
>> problem with using it without (the ) is that -fmodule-file= can (and 
>> does) appear multiple times on the command line to specify dependent modules 
>> - so that one would have to specify which (named) module was related to the 
>> filename.



> I /think/ currently `-fmodule-file` works with Clang header modules 
> presumably because the module files contain within them enough information to 
> enable the compiler to substitute the module for an include where necessary? 
> I'm not sure the `=` part is necessary, as such, if the BMIs can 
> reasonably contain enough identifying info to make their use clear to the 
> consumer.

`-fmodule-file=` works with both `clang` modules  and standard C++ ones.  What 
it does (as of now) is cause the FE to open the named file and to pre-load the 
module name - so that when the FE tries to find a module the lookup mechanism 
can associate the module name with the module data.  So, if we need 3 dependent 
modules to be available when building a new source .. we would specify the PCM 
files containing those modules.

At present, if you try to specify a non-existent PCM using `-fmodule-file=` the 
compile will fail early on (it is expecting this to indicate a source module, 
not a destination one).

However, the second syntax `-fmodule-file==filename` I think should be 
able to work around this (since it says that the named module  is 
associated with the PCM `filename` which would allow us to cater for that file 
being missing (when we are creating it).

Does that clarify at all ?

It would be great not to add more modules options flags, there are already way 
to many :/ - but if this seems too complex then one of the spellings suggested 
by @ChuanqiXu would work.


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

https://reviews.llvm.org/D134267

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


  1   2   3   4   5   >