diff --git a/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt b/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt index 3bd4a6e21bee7..35082387b46e9 100644 --- a/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt +++ b/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt @@ -12,6 +12,7 @@ add_clang_unittest(ClangAnalysisFlowSensitiveTests LoggerTest.cpp MapLatticeTest.cpp MatchSwitchTest.cpp + MockHeaders.cpp MultiVarConstantPropagationTest.cpp RecordOpsTest.cpp SignAnalysisTest.cpp diff --git a/clang/unittests/Analysis/FlowSensitive/MockHeaders.cpp b/clang/unittests/Analysis/FlowSensitive/MockHeaders.cpp new file mode 100644 index 0000000000000..e70a0c3644e83 --- /dev/null +++ b/clang/unittests/Analysis/FlowSensitive/MockHeaders.cpp @@ -0,0 +1,1259 @@ +//===--- MockHeaders.cpp - Mock headers for dataflow analyses -*- C++ ---*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines utilities to simplify testing of dataflow analyses. +// +//===----------------------------------------------------------------------===// + +#include "MockHeaders.h" + +namespace clang { +namespace dataflow { +namespace test { +static constexpr char CSDtdDefHeader[] = R"( +#ifndef CSTDDEF_H +#define CSTDDEF_H + +namespace std { + +typedef decltype(sizeof(char)) size_t; + +using nullptr_t = decltype(nullptr); + +} // namespace std + +#endif // CSTDDEF_H +)"; + +static constexpr char StdTypeTraitsHeader[] = R"( +#ifndef STD_TYPE_TRAITS_H +#define STD_TYPE_TRAITS_H + +#include "cstddef.h" + +namespace std { + +template +struct integral_constant { + static constexpr T value = V; +}; + +using true_type = integral_constant; +using false_type = integral_constant; + +template< class T > struct remove_reference {typedef T type;}; +template< class T > struct remove_reference {typedef T type;}; +template< class T > struct remove_reference {typedef T type;}; + +template + using remove_reference_t = typename remove_reference::type; + +template +struct remove_extent { + typedef T type; +}; + +template +struct remove_extent { + typedef T type; +}; + +template +struct remove_extent { + typedef T type; +}; + +template +struct is_array : false_type {}; + +template +struct is_array : true_type {}; + +template +struct is_array : true_type {}; + +template +struct is_function : false_type {}; + +template +struct is_function : true_type {}; + +namespace detail { + +template +struct type_identity { + using type = T; +}; // or use type_identity (since C++20) + +template +auto try_add_pointer(int) -> type_identity::type*>; +template +auto try_add_pointer(...) -> type_identity; + +} // namespace detail + +template +struct add_pointer : decltype(detail::try_add_pointer(0)) {}; + +template +struct conditional { + typedef T type; +}; + +template +struct conditional { + typedef F type; +}; + +template +struct remove_cv { + typedef T type; +}; +template +struct remove_cv { + typedef T type; +}; +template +struct remove_cv { + typedef T type; +}; +template +struct remove_cv { + typedef T type; +}; + +template +using remove_cv_t = typename remove_cv::type; + +template +struct decay { + private: + typedef typename remove_reference::type U; + + public: + typedef typename conditional< + is_array::value, typename remove_extent::type*, + typename conditional::value, typename add_pointer::type, + typename remove_cv::type>::type>::type type; +}; + +template +struct enable_if {}; + +template +struct enable_if { + typedef T type; +}; + +template +using enable_if_t = typename enable_if::type; + +template +struct is_same : false_type {}; + +template +struct is_same : true_type {}; + +template +struct is_void : is_same::type> {}; + +namespace detail { + +template +auto try_add_lvalue_reference(int) -> type_identity; +template +auto try_add_lvalue_reference(...) -> type_identity; + +template +auto try_add_rvalue_reference(int) -> type_identity; +template +auto try_add_rvalue_reference(...) -> type_identity; + +} // namespace detail + +template +struct add_lvalue_reference : decltype(detail::try_add_lvalue_reference(0)) { +}; + +template +struct add_rvalue_reference : decltype(detail::try_add_rvalue_reference(0)) { +}; + +template +typename add_rvalue_reference::type declval() noexcept; + +namespace detail { + +template +auto test_returnable(int) + -> decltype(void(static_cast(nullptr)), true_type{}); +template +auto test_returnable(...) -> false_type; + +template +auto test_implicitly_convertible(int) + -> decltype(void(declval()(declval())), true_type{}); +template +auto test_implicitly_convertible(...) -> false_type; + +} // namespace detail + +template +struct is_convertible + : integral_constant(0))::value && + decltype(detail::test_implicitly_convertible( + 0))::value) || + (is_void::value && is_void::value)> {}; + +template +inline constexpr bool is_convertible_v = is_convertible::value; + +template +using void_t = void; + +template +struct is_constructible_ : false_type {}; + +template +struct is_constructible_()...))>, T, Args...> + : true_type {}; + +template +using is_constructible = is_constructible_, T, Args...>; + +template +inline constexpr bool is_constructible_v = is_constructible::value; + +template +struct __uncvref { + typedef typename remove_cv::type>::type type; +}; + +template +using __uncvref_t = typename __uncvref<_Tp>::type; + +template +using _BoolConstant = integral_constant; + +template +using _IsSame = _BoolConstant<__is_same(_Tp, _Up)>; + +template +using _IsNotSame = _BoolConstant; + +template +struct _MetaBase; +template <> +struct _MetaBase { + template + using _SelectImpl = _Tp; + template