Skip to content

Commit ecc56c7

Browse files
authored
Merge branch 'main' into dag-always-push-freeze
2 parents f30ba4e + 592f203 commit ecc56c7

File tree

17 files changed

+427
-196
lines changed

17 files changed

+427
-196
lines changed

clang/test/ClangScanDeps/P1689.cppm

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,65 @@
11
// UNSUPPORTED: target={{.*}}-aix{{.*}}
22
//
3-
// The slash direction in linux and windows are different.
4-
// UNSUPPORTED: system-windows
5-
//
63
// RUN: rm -fr %t
74
// RUN: mkdir -p %t
85
// RUN: split-file %s %t
96
//
107
// RUN: sed "s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json
118
// RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/Checks.cpp -DPREFIX=%/t
12-
// RUN: clang-scan-deps --mode=preprocess-dependency-directives -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/Checks.cpp -DPREFIX=%/t
9+
// RUN: clang-scan-deps --mode=preprocess-dependency-directives -compilation-database %t/P1689.json -format=p1689 \
10+
// RUN: | sed 's:\\\\\?:/:g' \
11+
// RUN: | FileCheck %t/Checks.cpp -DPREFIX=%/t
1312
//
1413
// Check the separated dependency format. This is required by CMake for the case
1514
// that we have non-exist files in a fresh build and potentially out-of-date after that.
1615
// So the build system need to wrtie a compilation database just for scanning purposes,
1716
// which is not so good. So here is the per file mode for P1689.
1817
// RUN: clang-scan-deps -format=p1689 \
1918
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/M.cppm -o %t/M.o \
19+
// RUN: | sed 's:\\\\\?:/:g' \
2020
// RUN: | FileCheck %t/M.cppm -DPREFIX=%/t
2121
// RUN: clang-scan-deps -format=p1689 \
2222
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/Impl.cpp -o %t/Impl.o \
23+
// RUN: | sed 's:\\\\\?:/:g' \
2324
// RUN: | FileCheck %t/Impl.cpp -DPREFIX=%/t
2425
// RUN: clang-scan-deps -format=p1689 \
2526
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/impl_part.cppm -o %t/impl_part.o \
27+
// RUN: | sed 's:\\\\\?:/:g' \
2628
// RUN: | FileCheck %t/impl_part.cppm -DPREFIX=%/t
2729
// RUN: clang-scan-deps -format=p1689 \
2830
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/interface_part.cppm -o %t/interface_part.o \
31+
// RUN: | sed 's:\\\\\?:/:g' \
2932
// RUN: | FileCheck %t/interface_part.cppm -DPREFIX=%/t
3033
// RUN: clang-scan-deps -format=p1689 \
3134
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/User.cpp -o %t/User.o \
35+
// RUN: | sed 's:\\\\\?:/:g' \
3236
// RUN: | FileCheck %t/User.cpp -DPREFIX=%/t
3337
//
3438
// Check we can generate the make-style dependencies as expected.
3539
// RUN: clang-scan-deps -format=p1689 \
3640
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/impl_part.cppm -o %t/impl_part.o \
3741
// RUN: -MT %t/impl_part.o.ddi -MD -MF %t/impl_part.dep
38-
// RUN: cat %t/impl_part.dep | FileCheck %t/impl_part.cppm -DPREFIX=%/t --check-prefix=CHECK-MAKE
42+
// RUN: cat %t/impl_part.dep \
43+
// RUN: | sed 's:\\\\\?:/:g' \
44+
// RUN: | FileCheck %t/impl_part.cppm -DPREFIX=%/t --check-prefix=CHECK-MAKE
3945
//
4046
// Check that we can generate multiple make-style dependency information with compilation database.
4147
// RUN: cat %t/P1689.dep | FileCheck %t/Checks.cpp -DPREFIX=%/t --check-prefix=CHECK-MAKE
4248
//
4349
// Check that we can mix the use of -format=p1689 and -fmodules.
4450
// RUN: clang-scan-deps -format=p1689 \
4551
// RUN: -- %clang++ -std=c++20 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -c %t/impl_part.cppm -o %t/impl_part.o \
52+
// RUN: | sed 's:\\\\\?:/:g' \
4653
// RUN: | FileCheck %t/impl_part.cppm -DPREFIX=%/t
4754
//
4855
// Check the path in the make style dependencies are generated in relative path form
4956
// RUN: cd %t
5057
// RUN: clang-scan-deps -format=p1689 \
5158
// RUN: -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t impl_part.cppm -o impl_part.o \
5259
// RUN: -MT impl_part.o.ddi -MD -MF impl_part.dep
53-
// RUN: cat impl_part.dep | FileCheck impl_part.cppm -DPREFIX=%/t --check-prefix=CHECK-MAKE-RELATIVE
60+
// RUN: cat impl_part.dep \
61+
// RUN: | sed 's:\\\\\?:/:g' \
62+
// RUN: | FileCheck impl_part.cppm -DPREFIX=%/t --check-prefix=CHECK-MAKE-RELATIVE
5463

5564

5665
//--- P1689.json.in

libcxx/include/__hash_table

Lines changed: 80 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <__memory/unique_ptr.h>
3030
#include <__new/launder.h>
3131
#include <__type_traits/can_extract_key.h>
32+
#include <__type_traits/copy_cvref.h>
3233
#include <__type_traits/enable_if.h>
3334
#include <__type_traits/invoke.h>
3435
#include <__type_traits/is_const.h>
@@ -108,9 +109,22 @@ struct __hash_node_base {
108109
_LIBCPP_HIDE_FROM_ABI explicit __hash_node_base(__next_pointer __next) _NOEXCEPT : __next_(__next) {}
109110
};
110111

112+
template <class _Tp>
113+
struct __get_hash_node_value_type {
114+
using type _LIBCPP_NODEBUG = _Tp;
115+
};
116+
117+
template <class _Key, class _Tp>
118+
struct __get_hash_node_value_type<__hash_value_type<_Key, _Tp> > {
119+
using type _LIBCPP_NODEBUG = pair<const _Key, _Tp>;
120+
};
121+
122+
template <class _Tp>
123+
using __get_hash_node_value_type_t _LIBCPP_NODEBUG = typename __get_hash_node_value_type<_Tp>::type;
124+
111125
template <class _Tp, class _VoidPtr>
112126
struct __hash_node : public __hash_node_base< __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > > {
113-
typedef _Tp __node_value_type;
127+
using __node_value_type _LIBCPP_NODEBUG = __get_hash_node_value_type_t<_Tp>;
114128
using _Base _LIBCPP_NODEBUG = __hash_node_base<__rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > >;
115129
using __next_pointer _LIBCPP_NODEBUG = typename _Base::__next_pointer;
116130

@@ -122,18 +136,20 @@ struct __hash_node : public __hash_node_base< __rebind_pointer_t<_VoidPtr, __has
122136

123137
private:
124138
union {
125-
_Tp __value_;
139+
__node_value_type __value_;
126140
};
127141

128142
public:
129-
_LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; }
143+
_LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
130144
#else
131145

132146
private:
133-
_ALIGNAS_TYPE(_Tp) char __buffer_[sizeof(_Tp)];
147+
_ALIGNAS_TYPE(__node_value_type) char __buffer_[sizeof(__node_value_type)];
134148

135149
public:
136-
_LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); }
150+
_LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() {
151+
return *std::__launder(reinterpret_cast<__node_value_type*>(&__buffer_));
152+
}
137153
#endif
138154

139155
_LIBCPP_HIDE_FROM_ABI explicit __hash_node(__next_pointer __next, size_t __hash) : _Base(__next), __hash_(__hash) {}
@@ -201,8 +217,8 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
201217
return __t;
202218
}
203219

204-
_LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) {
205-
return std::addressof(__n.__get_value());
220+
_LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__container_value_type& __n) {
221+
return std::addressof(__n);
206222
}
207223
_LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { return __v.__move(); }
208224
};
@@ -242,7 +258,7 @@ public:
242258

243259
typedef typename __node_base_type::__next_pointer __next_pointer;
244260

245-
typedef _Tp __node_value_type;
261+
using __node_value_type _LIBCPP_NODEBUG = __get_hash_node_value_type_t<_Tp>;
246262
typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer;
247263
typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer;
248264

@@ -667,14 +683,14 @@ int __diagnose_unordered_container_requirements(void*);
667683
template <class _Tp, class _Hash, class _Equal, class _Alloc>
668684
class __hash_table {
669685
public:
670-
typedef _Tp value_type;
686+
using value_type = __get_hash_node_value_type_t<_Tp>;
671687
typedef _Hash hasher;
672688
typedef _Equal key_equal;
673689
typedef _Alloc allocator_type;
674690

675691
private:
676692
typedef allocator_traits<allocator_type> __alloc_traits;
677-
typedef typename __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type _NodeTypes;
693+
typedef typename __make_hash_node_types<_Tp, typename __alloc_traits::void_pointer>::type _NodeTypes;
678694

679695
public:
680696
typedef typename _NodeTypes::__node_value_type __node_value_type;
@@ -845,6 +861,22 @@ public:
845861
return __emplace_unique(std::forward<_Pp>(__x));
846862
}
847863

864+
template <class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
865+
_LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(value_type&& __value) {
866+
using __key_type = typename _NodeTypes::key_type;
867+
868+
__node_holder __h = __construct_node(const_cast<__key_type&&>(__value.first), std::move(__value.second));
869+
__node_insert_unique(__h.get());
870+
__h.release();
871+
}
872+
873+
template <class _ValueT = _Tp, __enable_if_t<!__is_hash_value_type<_ValueT>::value, int> = 0>
874+
_LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(value_type&& __value) {
875+
__node_holder __h = __construct_node(std::move(__value));
876+
__node_insert_unique(__h.get());
877+
__h.release();
878+
}
879+
848880
template <class _Pp>
849881
_LIBCPP_HIDE_FROM_ABI iterator __insert_multi(_Pp&& __x) {
850882
return __emplace_multi(std::forward<_Pp>(__x));
@@ -855,6 +887,22 @@ public:
855887
return __emplace_hint_multi(__p, std::forward<_Pp>(__x));
856888
}
857889

890+
template <class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
891+
_LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(value_type&& __value) {
892+
using __key_type = typename _NodeTypes::key_type;
893+
894+
__node_holder __h = __construct_node(const_cast<__key_type&&>(__value.first), std::move(__value.second));
895+
__node_insert_multi(__h.get());
896+
__h.release();
897+
}
898+
899+
template <class _ValueT = _Tp, __enable_if_t<!__is_hash_value_type<_ValueT>::value, int> = 0>
900+
_LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(value_type&& __value) {
901+
__node_holder __h = __construct_node(std::move(__value));
902+
__node_insert_multi(__h.get());
903+
__h.release();
904+
}
905+
858906
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(const __container_value_type& __x) {
859907
return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
860908
}
@@ -1020,6 +1068,21 @@ private:
10201068
_LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT;
10211069
_LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT;
10221070

1071+
template <class _From, class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
1072+
_LIBCPP_HIDE_FROM_ABI void __assign_value(__get_hash_node_value_type_t<_Tp>& __lhs, _From&& __rhs) {
1073+
using __key_type = typename _NodeTypes::key_type;
1074+
1075+
// This is technically UB, since the object was constructed as `const`.
1076+
// Clang doesn't optimize on this currently though.
1077+
const_cast<__key_type&>(__lhs.first) = const_cast<__copy_cvref_t<_From, __key_type>&&>(__rhs.first);
1078+
__lhs.second = std::forward<_From>(__rhs).second;
1079+
}
1080+
1081+
template <class _From, class _ValueT = _Tp, __enable_if_t<!__is_hash_value_type<_ValueT>::value, int> = 0>
1082+
_LIBCPP_HIDE_FROM_ABI void __assign_value(_Tp& __lhs, _From&& __rhs) {
1083+
__lhs = std::forward<_From>(__rhs);
1084+
}
1085+
10231086
template <class, class, class, class, class>
10241087
friend class unordered_map;
10251088
template <class, class, class, class, class>
@@ -1216,8 +1279,8 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u,
12161279
#endif // _LIBCPP_HAS_EXCEPTIONS
12171280
const_iterator __i = __u.begin();
12181281
while (__cache != nullptr && __u.size() != 0) {
1219-
__cache->__upcast()->__get_value() = std::move(__u.remove(__i++)->__get_value());
1220-
__next_pointer __next = __cache->__next_;
1282+
__assign_value(__cache->__upcast()->__get_value(), std::move(__u.remove(__i++)->__get_value()));
1283+
__next_pointer __next = __cache->__next_;
12211284
__node_insert_multi(__cache->__upcast());
12221285
__cache = __next;
12231286
}
@@ -1230,11 +1293,8 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u,
12301293
__deallocate_node(__cache);
12311294
}
12321295
const_iterator __i = __u.begin();
1233-
while (__u.size() != 0) {
1234-
__node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__get_value()));
1235-
__node_insert_multi(__h.get());
1236-
__h.release();
1237-
}
1296+
while (__u.size() != 0)
1297+
__insert_multi_from_orphaned_node(std::move(__u.remove(__i++)->__get_value()));
12381298
}
12391299
}
12401300

@@ -1262,8 +1322,8 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __
12621322
try {
12631323
#endif // _LIBCPP_HAS_EXCEPTIONS
12641324
for (; __cache != nullptr && __first != __last; ++__first) {
1265-
__cache->__upcast()->__get_value() = *__first;
1266-
__next_pointer __next = __cache->__next_;
1325+
__assign_value(__cache->__upcast()->__get_value(), *__first);
1326+
__next_pointer __next = __cache->__next_;
12671327
__node_insert_unique(__cache->__upcast());
12681328
__cache = __next;
12691329
}
@@ -1294,7 +1354,7 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __f
12941354
try {
12951355
#endif // _LIBCPP_HAS_EXCEPTIONS
12961356
for (; __cache != nullptr && __first != __last; ++__first) {
1297-
__cache->__upcast()->__get_value() = *__first;
1357+
__assign_value(__cache->__upcast()->__get_value(), *__first);
12981358
__next_pointer __next = __cache->__next_;
12991359
__node_insert_multi(__cache->__upcast());
13001360
__cache = __next;

0 commit comments

Comments
 (0)