aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2023-07-25 10:55:15 +0800
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>2023-07-25 11:03:57 +0800
commit8a86f85ab1e65fb5c148d7a645197b4634a2e2fc (patch)
treeb0992691eb99ff20b6262d65c3e2f87c602e0813
parent5cc4b1059b2842418514a54599a37900b8c608a0 (diff)
downloadllvm-8a86f85ab1e65fb5c148d7a645197b4634a2e2fc.zip
llvm-8a86f85ab1e65fb5c148d7a645197b4634a2e2fc.tar.gz
llvm-8a86f85ab1e65fb5c148d7a645197b4634a2e2fc.tar.bz2
Revert "[C++20] [Modules] Use CanonicalType for base classes"
Close https://github.com/llvm/llvm-project/issues/64091 This reverts commit f82df0b285acd8a7115f0bfc55ce44474251c2d1 and add a test from https://github.com/llvm/llvm-project/issues/64091
-rw-r--r--clang/lib/AST/ODRHash.cpp2
-rw-r--r--clang/test/Modules/pr63595.cppm46
-rw-r--r--clang/test/Modules/pr64091.cpp194
3 files changed, 195 insertions, 47 deletions
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 40d68a3..507fb0b 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -593,7 +593,7 @@ void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
ID.AddInteger(Record->getNumBases());
auto Bases = Record->bases();
for (const auto &Base : Bases) {
- AddQualType(Base.getType().getCanonicalType());
+ AddQualType(Base.getType());
ID.AddInteger(Base.isVirtual());
ID.AddInteger(Base.getAccessSpecifierAsWritten());
}
diff --git a/clang/test/Modules/pr63595.cppm b/clang/test/Modules/pr63595.cppm
deleted file mode 100644
index d1729da..0000000
--- a/clang/test/Modules/pr63595.cppm
+++ /dev/null
@@ -1,46 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir %t
-// RUN: split-file %s %t
-//
-// RUN: %clang_cc1 -std=c++20 -emit-module-interface -I%t %t/module1.cppm -o %t/module1.pcm
-// RUN: %clang_cc1 -std=c++20 -emit-module-interface -I%t %t/module2.cppm -o %t/module2.pcm
-// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/merge.cpp -verify -fsyntax-only
-
-//--- header.h
-namespace NS {
-template <int I>
-class A {
-};
-
-template <template <int I_> class T>
-class B {
-};
-}
-
-//--- module1.cppm
-// inside NS, using C = B<A>
-module;
-#include "header.h"
-export module module1;
-
-namespace NS {
-using C = B<A>;
-}
-export struct D : NS::C {};
-
-//--- module2.cppm
-// inside NS, using C = B<NS::A>
-module;
-#include "header.h"
-export module module2;
-
-namespace NS {
-using C = B<NS::A>;
-}
-export struct D : NS::C {};
-
-//--- merge.cpp
-// expected-no-diagnostics
-import module1;
-import module2;
-D d;
diff --git a/clang/test/Modules/pr64091.cpp b/clang/test/Modules/pr64091.cpp
new file mode 100644
index 0000000..6ff45e3
--- /dev/null
+++ b/clang/test/Modules/pr64091.cpp
@@ -0,0 +1,194 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// RUN: cd %t
+//
+// RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=c \
+// RUN: -fmodule-map-file=c.cppmap -xc++ c.cppmap -emit-module -o c.pcm
+// RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=a \
+// RUN: -fmodule-map-file=a.cppmap -fmodule-map-file=c.cppmap -xc++ a.cppmap \
+// RUN: -emit-module -o a.pcm
+// RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=b \
+// RUN: -fmodule-map-file=b.cppmap -fmodule-map-file=c.cppmap -xc++ b.cppmap \
+// RUN: -emit-module -o b.pcm
+// RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=test \
+// RUN: -fmodule-map-file=test.cppmap -fmodule-map-file=a.cppmap \
+// RUN: -fmodule-map-file=b.cppmap -fmodule-file=a.pcm -fmodule-file=b.pcm -xc++ \
+// RUN: test.cc -S -emit-llvm -o - | FileCheck test.cc
+
+//--- a.cppmap
+module "a" {
+ export *
+ module "a.h" {
+ export *
+ header "a.h"
+ }
+ use "c"
+}
+
+//--- b.cppmap
+module "b" {
+ export *
+ module "b.h" {
+ export *
+ header "b.h"
+ }
+ use "c"
+}
+
+//--- c.cppmap
+module "c" {
+ export *
+ module "c1.h" {
+ export *
+ textual header "c1.h"
+ }
+ module "c2.h" {
+ export *
+ textual header "c2.h"
+ }
+ module "c3.h" {
+ export *
+ textual header "c3.h"
+ }
+}
+
+//--- test.cppmap
+module "test" {
+ export *
+ use "a"
+ use "b"
+}
+
+//--- a.h
+#ifndef A_H_
+#define A_H_
+
+#include "c1.h"
+
+namespace q {
+template <typename T,
+ typename std::enable_if<::p::P<T>::value>::type>
+class X {};
+} // namespace q
+
+#include "c3.h"
+
+#endif // A_H_
+
+//--- b.h
+#ifndef B_H_
+#define B_H_
+
+#include "c2.h"
+
+#endif // B_H_
+
+//--- c1.h
+#ifndef C1_H_
+#define C1_H_
+
+namespace std {
+template <class _Tp, _Tp __v>
+struct integral_constant {
+ static constexpr const _Tp value = __v;
+ typedef _Tp value_type;
+ typedef integral_constant type;
+ constexpr operator value_type() const noexcept { return value; }
+ constexpr value_type operator()() const noexcept { return value; }
+};
+
+template <class _Tp, _Tp __v>
+constexpr const _Tp integral_constant<_Tp, __v>::value;
+
+typedef integral_constant<bool, true> true_type;
+typedef integral_constant<bool, false> false_type;
+
+template <bool, class _Tp = void>
+struct enable_if {};
+template <class _Tp>
+struct enable_if<true, _Tp> {
+ typedef _Tp type;
+};
+} // namespace std
+
+namespace p {
+template <typename T>
+struct P : ::std::false_type {};
+}
+
+#endif // C1_H_
+
+//--- c2.h
+#ifndef C2_H_
+#define C2_H_
+
+#include "c3.h"
+
+enum E {};
+namespace p {
+template <>
+struct P<E> : std::true_type {};
+} // namespace proto2
+
+inline void f(::util::EnumErrorSpace<E>) {}
+
+#endif // C2_H_
+
+//--- c3.h
+#ifndef C3_H_
+#define C3_H_
+
+#include "c1.h"
+
+namespace util {
+
+template <typename T>
+class ErrorSpaceImpl;
+
+class ErrorSpace {
+ protected:
+ template <bool* addr>
+ struct OdrUse {
+ constexpr OdrUse() : b(*addr) {}
+ bool& b;
+ };
+ template <typename T>
+ struct Registerer {
+ static bool register_token;
+ static constexpr OdrUse<&register_token> kRegisterTokenUse{};
+ };
+
+ private:
+ template <typename T>
+ static const ErrorSpace* GetBase() {
+ return 0;
+ }
+
+ static bool Register(const ErrorSpace* (*space)()) { return true; }
+};
+
+template <typename T>
+bool ErrorSpace::Registerer<T>::register_token =
+ Register(&ErrorSpace::GetBase<T>);
+
+template <typename T>
+class ErrorSpaceImpl : public ErrorSpace {
+ private:
+ static constexpr Registerer<ErrorSpaceImpl> kRegisterer{};
+};
+
+template <typename T, typename = typename std::enable_if<p::P<T>::value>::type>
+class EnumErrorSpace : public ErrorSpaceImpl<EnumErrorSpace<T>> {};
+
+} // namespace util
+#endif // C3_H_
+
+//--- test.cc
+#include "a.h"
+#include "b.h"
+
+int main(int, char**) {}
+
+// CHECK-NOT: error