1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 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
|