Author: Chuanqi Xu Date: 2022-09-23T15:20:46+08:00 New Revision: 1aaba40dcbe8fdc93d825d1f4e22edaa3e9aa5b1
URL: https://github.com/llvm/llvm-project/commit/1aaba40dcbe8fdc93d825d1f4e22edaa3e9aa5b1 DIFF: https://github.com/llvm/llvm-project/commit/1aaba40dcbe8fdc93d825d1f4e22edaa3e9aa5b1.diff LOG: [C++] [Modules] Add a test case for mocking implementation for std modules I found this with the patch: https://reviews.llvm.org/D131858. It breaks my local implementation but not the in-tree test cases. So I reduce the failure and submit the test case. The more testing should be always good. Added: clang/test/Modules/pair-unambiguous-ctor.cppm Modified: Removed: ################################################################################ diff --git a/clang/test/Modules/pair-unambiguous-ctor.cppm b/clang/test/Modules/pair-unambiguous-ctor.cppm new file mode 100644 index 0000000000000..8022f34f3aafa --- /dev/null +++ b/clang/test/Modules/pair-unambiguous-ctor.cppm @@ -0,0 +1,265 @@ +// Test case reduced from an experimental std modules implementation. +// Tests that the compiler don't emit confusing error about the ambiguous ctor +// about std::pair. +// +// RUN: rm -fr %t +// RUN: mkdir %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/string.cppm -I%t -emit-module-interface -o %t/std-string.pcm +// RUN: %clang_cc1 -std=c++20 %t/algorithm.cppm -I%t -emit-module-interface -o %t/std-algorithm.pcm +// RUN: %clang_cc1 -std=c++20 %t/Use.cppm -I%t -fprebuilt-module-path=%t -emit-module-interface -verify -o %t/Use.pcm + +//--- Use.cppm +// expected-no-diagnostics +module; +#include "config.h" +export module std:M; +import :string; +import :algorithm; + +auto check() { + return std::string(); +} + +//--- string.cppm +module; +#include "string.h" +export module std:string; +export namespace std { + using std::string; +} + +//--- algorithm.cppm +module; +#include "algorithm.h" +export module std:algorithm; + +//--- pair.h +namespace std __attribute__ ((__visibility__ ("default"))) +{ + typedef long unsigned int size_t; + typedef long int ptr diff _t; + + typedef decltype(nullptr) nullptr_t; + + template<typename _Tp, _Tp __v> + struct integral_constant + { + static constexpr _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant<_Tp, __v> type; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } + }; + + template<typename _Tp, _Tp __v> + constexpr _Tp integral_constant<_Tp, __v>::value; + + typedef integral_constant<bool, true> true_type; + typedef integral_constant<bool, false> false_type; + + template<bool __v> + using __bool_constant = integral_constant<bool, __v>; + + + template<bool, typename, typename> + struct conditional; + + template<bool _Cond, typename _Iftrue, typename _Iffalse> + struct conditional + { typedef _Iftrue type; }; + + template<typename _Iftrue, typename _Iffalse> + struct conditional<false, _Iftrue, _Iffalse> + { typedef _Iffalse type; }; + + + template<bool, typename _Tp = void> + struct enable_if + { }; + + + template<typename _Tp> + struct enable_if<true, _Tp> + { typedef _Tp type; }; + + template<typename _Tp, typename... _Args> + struct __is_constructible_impl + : public __bool_constant<__is_constructible(_Tp, _Args...)> + { }; + + + template<typename _Tp, typename... _Args> + struct is_constructible + : public __is_constructible_impl<_Tp, _Args...> + {}; + + template<typename> + struct __is_void_helper + : public false_type { }; + + template<> + struct __is_void_helper<void> + : public true_type { }; + + template<typename _Tp> + struct is_void + : public __is_void_helper<_Tp>::type + { }; + + template<typename...> + class tuple; + + template<std::size_t...> + struct _Index_tuple; + + template <bool, typename _T1, typename _T2> + struct _PCC + { + template <typename _U1, typename _U2> + static constexpr bool _ConstructiblePair() + { + return is_constructible<_T1, const _U1&>::value; + } + + }; + + template<typename _T1, typename _T2> + struct pair + { + typedef _T1 first_type; + typedef _T2 second_type; + + _T1 first; + _T2 second; + + using _PCCP = _PCC<true, _T1, _T2>; + + template<typename _U1 = _T1, typename _U2=_T2, typename + enable_if<_PCCP::template + _ConstructiblePair<_U1, _U2>(), + bool>::type=true> + constexpr pair(const _T1& __a, const _T2& __b) + : first(__a), second(__b) { } + + constexpr pair& + operator=(typename conditional< + is_constructible<_T2>::value, + const pair&, nullptr_t>::type __p) + { + first = __p.first; + second = __p.second; + return *this; + } + + private: + template<typename... _Args1, std::size_t... _Indexes1, + typename... _Args2, std::size_t... _Indexes2> + constexpr + pair(tuple<_Args1...>&, tuple<_Args2...>&, + _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>); + + }; + + template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>; +} + +//--- string.h +#include "pair.h" + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + class __undefined; + + template<typename _Tp> + using __make_not_void + = typename conditional<is_void<_Tp>::value, __undefined, _Tp>::type; + + template <typename Ptr> + struct pointer_traits {}; + + template<typename _Tp> + struct pointer_traits<_Tp*> + { + + typedef _Tp* pointer; + + typedef _Tp element_type; + + static constexpr pointer + pointer_to(__make_not_void<element_type>& __r) noexcept + { return __builtin_addressof(__r); } + }; + + template<typename _Tp> + class allocator; + + template<typename _Alloc> + struct allocator_traits; + + template<typename _Tp> + struct allocator_traits<allocator<_Tp>> + { + using pointer = _Tp*; + }; + + template<typename _Alloc> + struct __alloc_traits + : std::allocator_traits<_Alloc> + { + typedef std::allocator_traits<_Alloc> _Base_type; + typedef typename _Base_type::pointer pointer; + }; + + template<class _CharT> + struct char_traits; + + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_string + { + typedef std::__alloc_traits<_Alloc> _Alloc_traits; + + public: + typedef typename _Alloc_traits::pointer pointer; + + private: + pointer _M_dataplus; + _CharT _M_local_buf[16]; + + pointer + _M_local_data() + { + return std::pointer_traits<pointer>::pointer_to(*_M_local_buf); + } + public: + basic_string() + : _M_dataplus(_M_local_data()) + { } + + }; + + typedef basic_string<char> string; +} + +//--- algorithm.h +#include "pair.h" +namespace std { + struct _Power2_rehash_policy + { + std::pair<bool, std::size_t> + _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, + std::size_t __n_ins) noexcept + { + return { false, 0 }; + } + }; +} + +//--- config.h +namespace std +{ + typedef __SIZE_TYPE__ size_t; +} + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits