mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-05-14 18:06:32 +00:00

[module.unit]p1 specifies that module and import are invalid components of a module name, that module names cannot contain reserved identifiers, and that std followed by zero or more digits is reserved. The first issue (module and import pseudo-keywords) requires a diagnostic, the second issue (use of reserved identifiers) does not require a diagnostic. We diagnose both the same -- the code is ill- formed unless the module declaration is in a system "header". This allows STL implementations to use the reserved module names while preventing users from stealing them out from under us. Differential Revision: https://reviews.llvm.org/D136953
272 lines
6.1 KiB
C++
272 lines
6.1 KiB
C++
// 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"
|
|
# 3 "pair-unambiguous-ctor.cppm" 1 3
|
|
export module std:M;
|
|
# 3 "pair-unambiguous-ctor.cppm" 2 3
|
|
import :string;
|
|
import :algorithm;
|
|
|
|
auto check() {
|
|
return std::string();
|
|
}
|
|
|
|
//--- string.cppm
|
|
module;
|
|
#include "string.h"
|
|
# 28 "pair-unambiguous-ctor.cppm" 1 3
|
|
export module std:string;
|
|
export namespace std {
|
|
using std::string;
|
|
}
|
|
# 28 "pair-unambiguous-ctor.cppm" 2 3
|
|
|
|
//--- algorithm.cppm
|
|
module;
|
|
#include "algorithm.h"
|
|
# 38 "pair-unambiguous-ctor.cppm" 1 3
|
|
export module std:algorithm;
|
|
# 38 "pair-unambiguous-ctor.cppm" 2 3
|
|
|
|
//--- pair.h
|
|
namespace std __attribute__ ((__visibility__ ("default")))
|
|
{
|
|
typedef long unsigned int size_t;
|
|
typedef long int ptrdiff_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;
|
|
}
|
|
|