mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-05-14 01:46:41 +00:00

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
195 lines
3.7 KiB
C++
195 lines
3.7 KiB
C++
// 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
|