Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revert "[C++20] [Modules] Use CanonicalType for base classes"
- Loading branch information
1 parent
5cc4b10
commit 8a86f85
Showing
3 changed files
with
195 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |