[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / test / Modules / pr64091.cpp
blob6ff45e3c41ae6c3105cff1ccda566067026eab1a
1 // RUN: rm -rf %t
2 // RUN: mkdir %t
3 // RUN: split-file %s %t
4 //
5 // RUN: cd %t
6 //
7 // RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=c \
8 // RUN: -fmodule-map-file=c.cppmap -xc++ c.cppmap -emit-module -o c.pcm
9 // RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=a \
10 // RUN: -fmodule-map-file=a.cppmap -fmodule-map-file=c.cppmap -xc++ a.cppmap \
11 // RUN: -emit-module -o a.pcm
12 // RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=b \
13 // RUN: -fmodule-map-file=b.cppmap -fmodule-map-file=c.cppmap -xc++ b.cppmap \
14 // RUN: -emit-module -o b.pcm
15 // RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=test \
16 // RUN: -fmodule-map-file=test.cppmap -fmodule-map-file=a.cppmap \
17 // RUN: -fmodule-map-file=b.cppmap -fmodule-file=a.pcm -fmodule-file=b.pcm -xc++ \
18 // RUN: test.cc -S -emit-llvm -o - | FileCheck test.cc
20 //--- a.cppmap
21 module "a" {
22 export *
23 module "a.h" {
24 export *
25 header "a.h"
27 use "c"
30 //--- b.cppmap
31 module "b" {
32 export *
33 module "b.h" {
34 export *
35 header "b.h"
37 use "c"
40 //--- c.cppmap
41 module "c" {
42 export *
43 module "c1.h" {
44 export *
45 textual header "c1.h"
47 module "c2.h" {
48 export *
49 textual header "c2.h"
51 module "c3.h" {
52 export *
53 textual header "c3.h"
57 //--- test.cppmap
58 module "test" {
59 export *
60 use "a"
61 use "b"
64 //--- a.h
65 #ifndef A_H_
66 #define A_H_
68 #include "c1.h"
70 namespace q {
71 template <typename T,
72 typename std::enable_if<::p::P<T>::value>::type>
73 class X {};
74 } // namespace q
76 #include "c3.h"
78 #endif // A_H_
80 //--- b.h
81 #ifndef B_H_
82 #define B_H_
84 #include "c2.h"
86 #endif // B_H_
88 //--- c1.h
89 #ifndef C1_H_
90 #define C1_H_
92 namespace std {
93 template <class _Tp, _Tp __v>
94 struct integral_constant {
95 static constexpr const _Tp value = __v;
96 typedef _Tp value_type;
97 typedef integral_constant type;
98 constexpr operator value_type() const noexcept { return value; }
99 constexpr value_type operator()() const noexcept { return value; }
102 template <class _Tp, _Tp __v>
103 constexpr const _Tp integral_constant<_Tp, __v>::value;
105 typedef integral_constant<bool, true> true_type;
106 typedef integral_constant<bool, false> false_type;
108 template <bool, class _Tp = void>
109 struct enable_if {};
110 template <class _Tp>
111 struct enable_if<true, _Tp> {
112 typedef _Tp type;
114 } // namespace std
116 namespace p {
117 template <typename T>
118 struct P : ::std::false_type {};
121 #endif // C1_H_
123 //--- c2.h
124 #ifndef C2_H_
125 #define C2_H_
127 #include "c3.h"
129 enum E {};
130 namespace p {
131 template <>
132 struct P<E> : std::true_type {};
133 } // namespace proto2
135 inline void f(::util::EnumErrorSpace<E>) {}
137 #endif // C2_H_
139 //--- c3.h
140 #ifndef C3_H_
141 #define C3_H_
143 #include "c1.h"
145 namespace util {
147 template <typename T>
148 class ErrorSpaceImpl;
150 class ErrorSpace {
151 protected:
152 template <bool* addr>
153 struct OdrUse {
154 constexpr OdrUse() : b(*addr) {}
155 bool& b;
157 template <typename T>
158 struct Registerer {
159 static bool register_token;
160 static constexpr OdrUse<&register_token> kRegisterTokenUse{};
163 private:
164 template <typename T>
165 static const ErrorSpace* GetBase() {
166 return 0;
169 static bool Register(const ErrorSpace* (*space)()) { return true; }
172 template <typename T>
173 bool ErrorSpace::Registerer<T>::register_token =
174 Register(&ErrorSpace::GetBase<T>);
176 template <typename T>
177 class ErrorSpaceImpl : public ErrorSpace {
178 private:
179 static constexpr Registerer<ErrorSpaceImpl> kRegisterer{};
182 template <typename T, typename = typename std::enable_if<p::P<T>::value>::type>
183 class EnumErrorSpace : public ErrorSpaceImpl<EnumErrorSpace<T>> {};
185 } // namespace util
186 #endif // C3_H_
188 //--- test.cc
189 #include "a.h"
190 #include "b.h"
192 int main(int, char**) {}
194 // CHECK-NOT: error