diff options
author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2023-07-25 10:55:15 +0800 |
---|---|---|
committer | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2023-07-25 11:03:57 +0800 |
commit | 8a86f85ab1e65fb5c148d7a645197b4634a2e2fc (patch) | |
tree | b0992691eb99ff20b6262d65c3e2f87c602e0813 | |
parent | 5cc4b1059b2842418514a54599a37900b8c608a0 (diff) | |
download | llvm-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.cpp | 2 | ||||
-rw-r--r-- | clang/test/Modules/pr63595.cppm | 46 | ||||
-rw-r--r-- | clang/test/Modules/pr64091.cpp | 194 |
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<®ister_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 |