[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / test / Modules / pair-unambiguous-ctor.cppm
blobeb242244260cbdf64792c0ce2b4bdf9eb99ad693
1 // Test case reduced from an experimental std modules implementation.
2 // Tests that the compiler don't emit confusing error about the ambiguous ctor
3 // about std::pair.
4 //
5 // RUN: rm -fr %t
6 // RUN: mkdir %t
7 // RUN: split-file %s %t
8 //
9 // RUN: %clang_cc1 -std=c++20 %t/string.cppm -I%t -emit-module-interface -o %t/std-string.pcm
10 // RUN: %clang_cc1 -std=c++20 %t/algorithm.cppm -I%t -emit-module-interface -o %t/std-algorithm.pcm
11 // RUN: %clang_cc1 -std=c++20 %t/Use.cppm -I%t -fprebuilt-module-path=%t -emit-module-interface -verify -o %t/Use.pcm
13 //--- Use.cppm
14 // expected-no-diagnostics
15 module;
16 #include "config.h"
17 # 3 "pair-unambiguous-ctor.cppm" 1 3
18 export module std:M;
19 # 3 "pair-unambiguous-ctor.cppm" 2 3
20 import :string;
21 import :algorithm;
23 auto check() {
24     return std::string();
27 //--- string.cppm
28 module;
29 #include "string.h"
30 # 28 "pair-unambiguous-ctor.cppm" 1 3
31 export module std:string;
32 export namespace std {
33     using std::string;
35 # 28 "pair-unambiguous-ctor.cppm" 2 3
37 //--- algorithm.cppm
38 module;
39 #include "algorithm.h"
40 # 38 "pair-unambiguous-ctor.cppm" 1 3
41 export module std:algorithm;
42 # 38 "pair-unambiguous-ctor.cppm" 2 3
44 //--- pair.h
45 namespace std __attribute__ ((__visibility__ ("default")))
46
47   typedef long unsigned int size_t;
48   typedef long int ptrdiff_t;
50   typedef decltype(nullptr) nullptr_t;
52   template<typename _Tp, _Tp __v>
53     struct integral_constant
54     {
55       static constexpr _Tp value = __v;
56       typedef _Tp value_type;
57       typedef integral_constant<_Tp, __v> type;
58       constexpr operator value_type() const noexcept { return value; }
59       constexpr value_type operator()() const noexcept { return value; }
60     };
62   template<typename _Tp, _Tp __v>
63     constexpr _Tp integral_constant<_Tp, __v>::value;
65   typedef integral_constant<bool, true> true_type;
66   typedef integral_constant<bool, false> false_type;
68   template<bool __v>
69     using __bool_constant = integral_constant<bool, __v>;
72   template<bool, typename, typename>
73     struct conditional;
75   template<bool _Cond, typename _Iftrue, typename _Iffalse>
76     struct conditional
77     { typedef _Iftrue type; };
79   template<typename _Iftrue, typename _Iffalse>
80     struct conditional<false, _Iftrue, _Iffalse>
81     { typedef _Iffalse type; };
84   template<bool, typename _Tp = void>
85     struct enable_if
86     { };
89   template<typename _Tp>
90     struct enable_if<true, _Tp>
91     { typedef _Tp type; };
93   template<typename _Tp, typename... _Args>
94     struct __is_constructible_impl
95     : public __bool_constant<__is_constructible(_Tp, _Args...)>
96     { };
99   template<typename _Tp, typename... _Args>
100     struct is_constructible
101       : public __is_constructible_impl<_Tp, _Args...>
102     {};
104   template<typename>
105     struct __is_void_helper
106     : public false_type { };
108   template<>
109     struct __is_void_helper<void>
110     : public true_type { };
112   template<typename _Tp>
113     struct is_void
114     : public __is_void_helper<_Tp>::type
115     { };
117   template<typename...>
118     class tuple;
120   template<std::size_t...>
121     struct _Index_tuple;
123   template <bool, typename _T1, typename _T2>
124     struct _PCC
125     {
126       template <typename _U1, typename _U2>
127       static constexpr bool _ConstructiblePair()
128       {
129  return is_constructible<_T1, const _U1&>::value;
130       }
132   };
134   template<typename _T1, typename _T2>
135     struct pair
136     {
137       typedef _T1 first_type;
138       typedef _T2 second_type;
140       _T1 first;
141       _T2 second;
143       using _PCCP = _PCC<true, _T1, _T2>;
145       template<typename _U1 = _T1, typename _U2=_T2, typename
146         enable_if<_PCCP::template
147       _ConstructiblePair<_U1, _U2>(),
148                          bool>::type=true>
149       constexpr pair(const _T1& __a, const _T2& __b)
150       : first(__a), second(__b) { }
152       constexpr pair&
153       operator=(typename conditional<
154          is_constructible<_T2>::value,
155   const pair&, nullptr_t>::type __p)
156       {
157  first = __p.first;
158  second = __p.second;
159  return *this;
160       }
162     private:
163       template<typename... _Args1, std::size_t... _Indexes1,
164                typename... _Args2, std::size_t... _Indexes2>
165       constexpr
166       pair(tuple<_Args1...>&, tuple<_Args2...>&,
167            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
169     };
171   template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
174 //--- string.h
175 #include "pair.h"
177 namespace std __attribute__ ((__visibility__ ("default")))
179   class __undefined;
181   template<typename _Tp>
182     using __make_not_void
183       = typename conditional<is_void<_Tp>::value, __undefined, _Tp>::type;
185   template <typename Ptr>
186   struct pointer_traits {};
187   
188   template<typename _Tp>
189     struct pointer_traits<_Tp*>
190     {
192       typedef _Tp* pointer;
194       typedef _Tp element_type;
196       static constexpr pointer
197       pointer_to(__make_not_void<element_type>& __r) noexcept
198       { return __builtin_addressof(__r); }
199     };
201   template<typename _Tp>
202     class allocator;
204   template<typename _Alloc>
205     struct allocator_traits;
207   template<typename _Tp>
208     struct allocator_traits<allocator<_Tp>>
209     {
210       using pointer = _Tp*;
211     };
213   template<typename _Alloc>
214   struct __alloc_traits
215   : std::allocator_traits<_Alloc>
216   {
217     typedef std::allocator_traits<_Alloc> _Base_type;
218     typedef typename _Base_type::pointer pointer;
219   };
221   template<class _CharT>
222     struct char_traits;
224   template<typename _CharT, typename _Traits = char_traits<_CharT>,
225            typename _Alloc = allocator<_CharT> >
226     class basic_string
227     {
228       typedef std::__alloc_traits<_Alloc> _Alloc_traits;
230     public:
231       typedef typename _Alloc_traits::pointer pointer;
233     private:
234       pointer _M_dataplus;
235       _CharT _M_local_buf[16];
237       pointer
238       _M_local_data()
239       {
240         return std::pointer_traits<pointer>::pointer_to(*_M_local_buf);
241       }
242     public:
243       basic_string()
244       : _M_dataplus(_M_local_data())
245       { }
247     };
249     typedef basic_string<char> string;
252 //--- algorithm.h
253 #include "pair.h"
254 namespace std {
255     struct _Power2_rehash_policy
256   {
257     std::pair<bool, std::size_t>
258     _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
259      std::size_t __n_ins) noexcept
260     {
261         return { false, 0 };
262     }
263   };
266 //--- config.h
267 namespace std
269   typedef __SIZE_TYPE__         size_t;