ChuanqiXu created this revision.
ChuanqiXu added reviewers: rsmith, vsapsai, ilya-biryukov, erichkeane, iains, 
v.g.vassilev.
ChuanqiXu added a project: clang-modules.
Herald added a reviewer: aaron.ballman.
Herald added a project: All.
ChuanqiXu requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This is a workaround for https://github.com/llvm/llvm-project/issues/56490. The 
problem is pretty hard and it blocks implementing std modules. After we applied 
this patch, we could implement std modules in this style: 
https://github.com/ChuanqiXu9/stdmodules, which looks much better.

I totally understand the style is not good in general. But given that it blocks 
something important and `preferred_name` is primarily used for printers. I'm 
wondering if it is OK to handle it specially.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129748

Files:
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/Modules/preferred_name.cppm


Index: clang/test/Modules/preferred_name.cppm
===================================================================
--- /dev/null
+++ clang/test/Modules/preferred_name.cppm
@@ -0,0 +1,40 @@
+// Tests that the ODR check wouldn't produce false-positive result for 
preferred_name attribute.
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use.cppm 
-verify -fsyntax-only
+//
+
+//--- foo.h
+template<class _CharT>
+class foo_templ;
+
+typedef foo_templ<char> foo;
+
+template<class _CharT>
+class
+__attribute__((__preferred_name__(foo)))
+foo_templ {
+public:
+    foo_templ() {}
+};
+
+inline foo_templ<char> bar()
+{
+  return foo_templ<char>();
+}
+
+//--- A.cppm
+module;
+#include "foo.h"
+export module A;
+
+//--- Use.cppm
+// expected-no-diagnostics
+module;
+#include "foo.h"
+export module Use;
+import A;
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1424,6 +1424,12 @@
 }
 
 static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
+  // FIXME: Workaround to make preferred_name to not block the ODR checks
+  // for Modules. See https://github.com/llvm/llvm-project/issues/56490 for
+  // details.
+  if (S.getLangOpts().CPlusPlusModules && D->getOwningModule())
+    return;
+
   auto *RD = cast<CXXRecordDecl>(D);
   ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
   assert(CTD && "attribute does not appertain to this declaration");


Index: clang/test/Modules/preferred_name.cppm
===================================================================
--- /dev/null
+++ clang/test/Modules/preferred_name.cppm
@@ -0,0 +1,40 @@
+// Tests that the ODR check wouldn't produce false-positive result for preferred_name attribute.
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use.cppm -verify -fsyntax-only
+//
+
+//--- foo.h
+template<class _CharT>
+class foo_templ;
+
+typedef foo_templ<char> foo;
+
+template<class _CharT>
+class
+__attribute__((__preferred_name__(foo)))
+foo_templ {
+public:
+    foo_templ() {}
+};
+
+inline foo_templ<char> bar()
+{
+  return foo_templ<char>();
+}
+
+//--- A.cppm
+module;
+#include "foo.h"
+export module A;
+
+//--- Use.cppm
+// expected-no-diagnostics
+module;
+#include "foo.h"
+export module Use;
+import A;
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1424,6 +1424,12 @@
 }
 
 static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
+  // FIXME: Workaround to make preferred_name to not block the ODR checks
+  // for Modules. See https://github.com/llvm/llvm-project/issues/56490 for
+  // details.
+  if (S.getLangOpts().CPlusPlusModules && D->getOwningModule())
+    return;
+
   auto *RD = cast<CXXRecordDecl>(D);
   ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
   assert(CTD && "attribute does not appertain to this declaration");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to