[libc-commits] [libc] c6bc106 - [libc] Add a library of standalone C++ utilities.
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Wed Jan 29 13:44:30 PST 2020
Author: Siva Chandra Reddy
Date: 2020-01-29T13:44:02-08:00
New Revision: c6bc10636cf3c48c947a4759d2e9648639cdfa71
URL: https://github.com/llvm/llvm-project/commit/c6bc10636cf3c48c947a4759d2e9648639cdfa71
DIFF: https://github.com/llvm/llvm-project/commit/c6bc10636cf3c48c947a4759d2e9648639cdfa71.diff
LOG: [libc] Add a library of standalone C++ utilities.
Some of the existing utils in utils/UnitTest/Test.h have been moved to
this new library.
Reviewers: abrachet, gchatelet
Tags: #libc-project
Differential Revision: https://reviews.llvm.org/D73530
Added:
libc/utils/CPP/Array.h
libc/utils/CPP/ArrayRef.h
libc/utils/CPP/CMakeLists.txt
libc/utils/CPP/README.md
libc/utils/CPP/StringRef.h
libc/utils/CPP/TypeTraits.h
Modified:
libc/CMakeLists.txt
libc/cmake/modules/LLVMLibCRules.cmake
libc/utils/CMakeLists.txt
libc/utils/UnitTest/CMakeLists.txt
libc/utils/UnitTest/Test.cpp
libc/utils/UnitTest/Test.h
Removed:
################################################################################
diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index ee57e5d313c4..a4c95eec9c05 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.4.3)
+# Use old version of target_sources command which converts the source
+# file paths to full paths.
+cmake_policy(SET CMP0076 OLD)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
# The top-level source directory of libc.
diff --git a/libc/cmake/modules/LLVMLibCRules.cmake b/libc/cmake/modules/LLVMLibCRules.cmake
index cef667313c61..f24b96a4e98f 100644
--- a/libc/cmake/modules/LLVMLibCRules.cmake
+++ b/libc/cmake/modules/LLVMLibCRules.cmake
@@ -375,3 +375,47 @@ function(add_libc_testsuite suite_name)
add_custom_target(${suite_name})
add_dependencies(check-libc ${suite_name})
endfunction(add_libc_testsuite)
+
+# Rule to add header only libraries.
+# Usage
+# add_header_library(
+# <target name>
+# HDRS <list of .h files part of the library>
+# DEPENDS <list of dependencies>
+# )
+function(add_header_library target_name)
+ cmake_parse_arguments(
+ "ADD_HEADER"
+ "" # No optional arguments
+ "" # No Single value arguments
+ "HDRS;DEPENDS" # Multi-value arguments
+ ${ARGN}
+ )
+
+ if(NOT ADD_HEADER_HDRS)
+ message(FATAL_ERROR "'add_header_library' target requires a HDRS list of .h files.")
+ endif()
+
+ set(FULL_HDR_PATHS "")
+ # TODO: Remove this foreach block when we can switch to the new
+ # version of the CMake policy CMP0076.
+ foreach(hdr IN LISTS ADD_HEADER_HDRS)
+ list(APPEND FULL_HDR_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/${hdr})
+ endforeach()
+
+ set(interface_target_name "${target_name}_header_library__")
+
+ add_library(${interface_target_name} INTERFACE)
+ target_sources(${interface_target_name} INTERFACE ${FULL_HDR_PATHS})
+ if(ADD_HEADER_DEPENDS)
+ add_dependencies(${interface_target_name} ${ADD_HEADER_DEPENDS})
+ endif()
+
+ add_custom_target(${target_name})
+ add_dependencies(${target_name} ${interface_target_name})
+ set_target_properties(
+ ${target_name}
+ PROPERTIES
+ "TARGET_TYPE" "HDR_LIBRARY"
+ )
+endfunction(add_header_library)
diff --git a/libc/utils/CMakeLists.txt b/libc/utils/CMakeLists.txt
index 3b9dfedc7c21..cbc551bca9f8 100644
--- a/libc/utils/CMakeLists.txt
+++ b/libc/utils/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(CPP)
add_subdirectory(HdrGen)
add_subdirectory(UnitTest)
add_subdirectory(benchmarks)
diff --git a/libc/utils/CPP/Array.h b/libc/utils/CPP/Array.h
new file mode 100644
index 000000000000..f81eeb253566
--- /dev/null
+++ b/libc/utils/CPP/Array.h
@@ -0,0 +1,47 @@
+//===--------- A self contained equivalent of std::array --------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <stddef.h> // For size_t.
+
+namespace __llvm_libc {
+namespace cpp {
+
+template <class T, size_t N> struct Array {
+ static_assert(N != 0, "Cannot create a __llvm_libc::cpp::Array of size 0.");
+
+ T Data[N];
+
+ using iterator = T *;
+ using const_iterator = const T *;
+
+ constexpr T *data() { return Data; }
+ constexpr const T *data() const { return Data; }
+
+ constexpr T &front() { return Data[0]; }
+ constexpr T &front() const { return Data[0]; }
+
+ constexpr T &back() { return Data[N - 1]; }
+ constexpr T &back() const { return Data[N - 1]; }
+
+ constexpr T &operator[](size_t Index) { return Data[Index]; }
+
+ constexpr const T &operator[](size_t Index) const { return Data[Index]; }
+
+ constexpr size_t size() const { return N; }
+
+ constexpr bool empty() const { return N == 0; }
+
+ constexpr iterator begin() { return Data; }
+ constexpr const_iterator begin() const { return Data; }
+
+ constexpr iterator end() { return Data + N; }
+ const_iterator end() const { return Data + N; }
+};
+
+} // namespace cpp
+} // namespace __llvm_libc
diff --git a/libc/utils/CPP/ArrayRef.h b/libc/utils/CPP/ArrayRef.h
new file mode 100644
index 000000000000..ad6e25d00e08
--- /dev/null
+++ b/libc/utils/CPP/ArrayRef.h
@@ -0,0 +1,90 @@
+//===----------------- Self contained ArrayRef type -------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "Array.h"
+
+#include <stddef.h> // For size_t.
+
+namespace __llvm_libc {
+namespace cpp {
+
+// The implementations of ArrayRef and MutualArrayRef in this file are based
+// on the implementations of the types with the same names in
+// llvm/ADT/ArrayRef.h. The implementations in this file are of a limited
+// functionality, but can be extended in an as needed basis.
+
+template <typename T> class ArrayRef {
+public:
+ using iterator = const T *;
+
+private:
+ const T *Data = nullptr;
+ size_t Length = 0;
+
+public:
+ ArrayRef() = default;
+
+ // From Array.
+ template <size_t N>
+ ArrayRef(const Array<T, N> &Arr) : Data(Arr.Data), Length(N) {}
+
+ // Construct an ArrayRef from a single element.
+ explicit ArrayRef(const T &OneElt) : Data(&OneElt), Length(1) {}
+
+ // Construct an ArrayRef from a pointer and length.
+ ArrayRef(const T *data, size_t length) : Data(data), Length(length) {}
+
+ // Construct an ArrayRef from a range.
+ ArrayRef(const T *begin, const T *end) : Data(begin), Length(end - begin) {}
+
+ // Construct an ArrayRef from a C array.
+ template <size_t N>
+ constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {}
+
+ iterator begin() const { return Data; }
+ iterator end() const { return Data + Length; }
+
+ bool empty() const { return Length == 0; }
+
+ const T *data() const { return Data; }
+
+ size_t size() const { return Length; }
+
+ const T &operator[](size_t Index) const { return Data[Index]; }
+};
+
+template <typename T> class MutableArrayRef : public ArrayRef<T> {
+public:
+ using iterator = T *;
+
+ // From Array.
+ template <size_t N> MutableArrayRef(Array<T, N> &Arr) : ArrayRef<T>(Arr) {}
+
+ // Construct from a single element.
+ explicit MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
+
+ // Construct from a pointer and length.
+ MutableArrayRef(T *data, size_t length) : ArrayRef<T>(data, length) {}
+
+ // Construct from a range.
+ MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
+
+ // Construct from a C array.
+ template <size_t N>
+ constexpr MutableArrayRef(T (&Arr)[N]) : ArrayRef<T>(Arr) {}
+
+ T *data() const { return const_cast<T *>(ArrayRef<T>::data()); }
+
+ iterator begin() const { return data(); }
+ iterator end() const { return data() + size(); }
+
+ T &operator[](size_t Index) const { return data()[Index]; }
+};
+
+} // namespace cpp
+} // namespace __llvm_libc
diff --git a/libc/utils/CPP/CMakeLists.txt b/libc/utils/CPP/CMakeLists.txt
new file mode 100644
index 000000000000..5cbfec2498f8
--- /dev/null
+++ b/libc/utils/CPP/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_header_library(
+ standalone_cpp
+ HDRS
+ Array.h
+ ArrayRef.h
+ TypeTraits.h
+)
diff --git a/libc/utils/CPP/README.md b/libc/utils/CPP/README.md
new file mode 100644
index 000000000000..756663e8cc16
--- /dev/null
+++ b/libc/utils/CPP/README.md
@@ -0,0 +1,12 @@
+This directory contains re-implementations of some C++ standard library as well
+as some LLVM utilities. These are to be used with internal LLVM libc code and
+tests. More utilities will be added on an as needed basis. There are certain
+rules to be followed for future changes and additions:
+
+1. Only two kind of headers can be included: Other headers from this directory,
+and free standing C headers.
+2. Free standing C headers are to be included as C headers and not as C++
+headers. That is, use `#include <stddef.h>` and not `#include <cstddef>`.
+3. The utilities should be defined in the namespace `__llvm_libc::cpp`. The
+higher level namespace should have a `__` prefix to avoid symbol name pollution
+when the utilities are used in implementation of public functions.
diff --git a/libc/utils/CPP/StringRef.h b/libc/utils/CPP/StringRef.h
new file mode 100644
index 000000000000..60f43b595e03
--- /dev/null
+++ b/libc/utils/CPP/StringRef.h
@@ -0,0 +1,19 @@
+//===----------------- A standalone StringRef type -------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "ArrayRef.h"
+
+namespace __llvm_libc {
+namespace cpp {
+
+class StringRef : public ArrayRef<char> {
+ // More methods like those in llvm::StringRef can be added as needed.
+};
+
+} // namespace cpp
+} // namespace __llvm_libc
diff --git a/libc/utils/CPP/TypeTraits.h b/libc/utils/CPP/TypeTraits.h
new file mode 100644
index 000000000000..9f5576259540
--- /dev/null
+++ b/libc/utils/CPP/TypeTraits.h
@@ -0,0 +1,50 @@
+//===----------------- Self contained C++ type traits -----------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+namespace __llvm_libc {
+namespace cpp {
+
+template <bool B, typename T> struct EnableIf;
+template <typename T> struct EnableIf<true, T> { typedef T Type; };
+
+template <bool B, typename T>
+using EnableIfType = typename EnableIf<B, T>::Type;
+
+struct TrueValue {
+ static constexpr bool Value = true;
+};
+
+struct FalseValue {
+ static constexpr bool Value = false;
+};
+
+template <typename Type> struct IsIntegral : public FalseValue {};
+template <> struct IsIntegral<char> : public TrueValue {};
+template <> struct IsIntegral<signed char> : public TrueValue {};
+template <> struct IsIntegral<unsigned char> : public TrueValue {};
+template <> struct IsIntegral<short> : public TrueValue {};
+template <> struct IsIntegral<unsigned short> : public TrueValue {};
+template <> struct IsIntegral<int> : public TrueValue {};
+template <> struct IsIntegral<unsigned int> : public TrueValue {};
+template <> struct IsIntegral<long> : public TrueValue {};
+template <> struct IsIntegral<unsigned long> : public TrueValue {};
+template <> struct IsIntegral<long long> : public TrueValue {};
+template <> struct IsIntegral<unsigned long long> : public TrueValue {};
+template <> struct IsIntegral<bool> : public TrueValue {};
+
+template <typename Type> struct IsIntegralNotBool : public IsIntegral<Type> {};
+template <> struct IsIntegralNotBool<bool> : public FalseValue {};
+
+template <typename T> struct IsPointerType : public FalseValue {};
+template <typename T> struct IsPointerType<T *> : public TrueValue {};
+
+template <typename T1, typename T2> struct IsSame : public FalseValue {};
+template <typename T> struct IsSame<T, T> : public TrueValue {};
+
+} // namespace cpp
+} // namespace __llvm_libc
diff --git a/libc/utils/UnitTest/CMakeLists.txt b/libc/utils/UnitTest/CMakeLists.txt
index 9d1ea10af6fd..c6e5d9a11824 100644
--- a/libc/utils/UnitTest/CMakeLists.txt
+++ b/libc/utils/UnitTest/CMakeLists.txt
@@ -4,3 +4,5 @@ add_llvm_library(
Test.h
LINK_COMPONENTS Support
)
+target_include_directories(LibcUnitTest PUBLIC ${LIBC_SOURCE_DIR})
+add_dependencies(LibcUnitTest standalone_cpp)
diff --git a/libc/utils/UnitTest/Test.cpp b/libc/utils/UnitTest/Test.cpp
index 4b089060bd34..1532922e9d4c 100644
--- a/libc/utils/UnitTest/Test.cpp
+++ b/libc/utils/UnitTest/Test.cpp
@@ -11,7 +11,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
-namespace llvm_libc {
+namespace __llvm_libc {
namespace testing {
// This need not be a class as all it has is a single read-write state variable.
@@ -224,6 +224,6 @@ bool Test::testStrNe(RunContext &Ctx, const char *LHS, const char *RHS,
}
} // namespace testing
-} // namespace llvm_libc
+} // namespace __llvm_libc
-int main() { return llvm_libc::testing::Test::runTests(); }
+int main() { return __llvm_libc::testing::Test::runTests(); }
diff --git a/libc/utils/UnitTest/Test.h b/libc/utils/UnitTest/Test.h
index 3bdf6f06c080..fc1002a56453 100644
--- a/libc/utils/UnitTest/Test.h
+++ b/libc/utils/UnitTest/Test.h
@@ -6,61 +6,20 @@
//
//===----------------------------------------------------------------------===//
-// This file should stricly not include any other file. Not even standard
-// library headers.
+// This file can only include headers from utils/CPP/. No other header should be
+// included.
-namespace llvm_libc {
-namespace testing {
-
-// We define our own EnableIf and IsIntegerType traits because we do not want to
-// include even the standard header <type_traits>.
-template <bool B, typename T> struct EnableIf;
-template <typename T> struct EnableIf<true, T> { typedef T Type; };
-
-template <bool B, typename T>
-using EnableIfType = typename EnableIf<B, T>::Type;
-
-template <typename Type> struct IsIntegerType {
- static const bool Value = false;
-};
-
-template <> struct IsIntegerType<char> { static const bool Value = true; };
-template <> struct IsIntegerType<unsigned char> {
- static const bool Value = true;
-};
-
-template <> struct IsIntegerType<short> { static const bool Value = true; };
-template <> struct IsIntegerType<unsigned short> {
- static const bool Value = true;
-};
+#include "utils/CPP/TypeTraits.h"
-template <> struct IsIntegerType<int> { static const bool Value = true; };
-template <> struct IsIntegerType<unsigned int> {
- static const bool Value = true;
-};
-
-template <> struct IsIntegerType<long> { static const bool Value = true; };
-template <> struct IsIntegerType<unsigned long> {
- static const bool Value = true;
-};
-
-template <> struct IsIntegerType<long long> { static const bool Value = true; };
-template <> struct IsIntegerType<unsigned long long> {
- static const bool Value = true;
-};
-
-template <typename T> struct IsPointerType;
-
-template <typename T> struct IsPointerType<T *> {
- static const bool Value = true;
-};
+namespace __llvm_libc {
+namespace testing {
class RunContext;
// Only the following conditions are supported. Notice that we do not have
// a TRUE or FALSE condition. That is because, C library funtions do not
-// return, but use integral return values to indicate true or false
-// conditions. Hence, it is more appropriate to use the other comparison
+// return boolean values, but use integral return values to indicate true or
+// false conditions. Hence, it is more appropriate to use the other comparison
// condtions for such cases.
enum TestCondition {
Cond_None,
@@ -98,22 +57,24 @@ class Test {
static void addTest(Test *T);
// We make use of a template function, with |LHS| and |RHS| as explicit
- // parameters, for enhanced type checking. Other gtest like test unittest
- // frameworks have a similar functions which takes a boolean argument
+ // parameters, for enhanced type checking. Other gtest like unittest
+ // frameworks have a similar function which takes a boolean argument
// instead of the explicit |LHS| and |RHS| arguments. This boolean argument
// is the result of the |Cond| operation on |LHS| and |RHS|. Though not bad,
- // mismatched |LHS| and |RHS| types can potentially succeed because of type
- // promotion.
- template <typename ValType,
- EnableIfType<IsIntegerType<ValType>::Value, ValType> = 0>
+ // |Cond| on mismatched |LHS| and |RHS| types can potentially succeed because
+ // of type promotion.
+ template <
+ typename ValType,
+ cpp::EnableIfType<cpp::IsIntegralNotBool<ValType>::Value, ValType> = 0>
static bool test(RunContext &Ctx, TestCondition Cond, ValType LHS,
ValType RHS, const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line) {
return internal::test(Ctx, Cond, LHS, RHS, LHSStr, RHSStr, File, Line);
}
- template <typename ValType,
- EnableIfType<IsPointerType<ValType>::Value, ValType> = nullptr>
+ template <
+ typename ValType,
+ cpp::EnableIfType<cpp::IsPointerType<ValType>::Value, ValType> = nullptr>
static bool test(RunContext &Ctx, TestCondition Cond, ValType LHS,
ValType RHS, const char *LHSStr, const char *RHSStr,
const char *File, unsigned long Line) {
@@ -138,80 +99,80 @@ class Test {
};
} // namespace testing
-} // namespace llvm_libc
+} // namespace __llvm_libc
#define TEST(SuiteName, TestName) \
- class SuiteName##_##TestName : public llvm_libc::testing::Test { \
+ class SuiteName##_##TestName : public __llvm_libc::testing::Test { \
public: \
SuiteName##_##TestName() { addTest(this); } \
- void Run(llvm_libc::testing::RunContext &) override; \
+ void Run(__llvm_libc::testing::RunContext &) override; \
const char *getName() const override { return #SuiteName "." #TestName; } \
}; \
SuiteName##_##TestName SuiteName##_##TestName##_Instance; \
- void SuiteName##_##TestName::Run(llvm_libc::testing::RunContext &Ctx)
+ void SuiteName##_##TestName::Run(__llvm_libc::testing::RunContext &Ctx)
#define TEST_F(SuiteClass, TestName) \
class SuiteClass##_##TestName : public SuiteClass { \
public: \
SuiteClass##_##TestName() { addTest(this); } \
- void Run(llvm_libc::testing::RunContext &) override; \
+ void Run(__llvm_libc::testing::RunContext &) override; \
const char *getName() const override { return #SuiteClass "." #TestName; } \
}; \
SuiteClass##_##TestName SuiteClass##_##TestName##_Instance; \
- void SuiteClass##_##TestName::Run(llvm_libc::testing::RunContext &Ctx)
+ void SuiteClass##_##TestName::Run(__llvm_libc::testing::RunContext &Ctx)
#define EXPECT_EQ(LHS, RHS) \
- llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_EQ, (LHS), \
- (RHS), #LHS, #RHS, __FILE__, __LINE__)
+ __llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_EQ, (LHS), \
+ (RHS), #LHS, #RHS, __FILE__, __LINE__)
#define ASSERT_EQ(LHS, RHS) \
if (!EXPECT_EQ(LHS, RHS)) \
return
#define EXPECT_NE(LHS, RHS) \
- llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_NE, (LHS), \
- (RHS), #LHS, #RHS, __FILE__, __LINE__)
+ __llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_NE, (LHS), \
+ (RHS), #LHS, #RHS, __FILE__, __LINE__)
#define ASSERT_NE(LHS, RHS) \
if (!EXPECT_NE(LHS, RHS)) \
return
#define EXPECT_LT(LHS, RHS) \
- llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_LT, (LHS), \
- (RHS), #LHS, #RHS, __FILE__, __LINE__)
+ __llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_LT, (LHS), \
+ (RHS), #LHS, #RHS, __FILE__, __LINE__)
#define ASSERT_LT(LHS, RHS) \
if (!EXPECT_LT(LHS, RHS)) \
return
#define EXPECT_LE(LHS, RHS) \
- llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_LE, (LHS), \
- (RHS), #LHS, #RHS, __FILE__, __LINE__)
+ __llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_LE, (LHS), \
+ (RHS), #LHS, #RHS, __FILE__, __LINE__)
#define ASSERT_LE(LHS, RHS) \
if (!EXPECT_LE(LHS, RHS)) \
return
#define EXPECT_GT(LHS, RHS) \
- llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_GT, (LHS), \
- (RHS), #LHS, #RHS, __FILE__, __LINE__)
+ __llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_GT, (LHS), \
+ (RHS), #LHS, #RHS, __FILE__, __LINE__)
#define ASSERT_GT(LHS, RHS) \
if (!EXPECT_GT(LHS, RHS)) \
return
#define EXPECT_GE(LHS, RHS) \
- llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_GE, (LHS), \
- (RHS), #LHS, #RHS, __FILE__, __LINE__)
+ __llvm_libc::testing::Test::test(Ctx, __llvm_libc::testing::Cond_GE, (LHS), \
+ (RHS), #LHS, #RHS, __FILE__, __LINE__)
#define ASSERT_GE(LHS, RHS) \
if (!EXPECT_GE(LHS, RHS)) \
return
#define EXPECT_STREQ(LHS, RHS) \
- llvm_libc::testing::Test::testStrEq(Ctx, (LHS), (RHS), #LHS, #RHS, __FILE__, \
- __LINE__)
+ __llvm_libc::testing::Test::testStrEq(Ctx, (LHS), (RHS), #LHS, #RHS, \
+ __FILE__, __LINE__)
#define ASSERT_STREQ(LHS, RHS) \
if (!EXPECT_STREQ(LHS, RHS)) \
return
#define EXPECT_STRNE(LHS, RHS) \
- llvm_libc::testing::Test::testStrNe(Ctx, (LHS), (RHS), #LHS, #RHS, __FILE__, \
- __LINE__)
+ __llvm_libc::testing::Test::testStrNe(Ctx, (LHS), (RHS), #LHS, #RHS, \
+ __FILE__, __LINE__)
#define ASSERT_STRNE(LHS, RHS) \
if (!EXPECT_STRNE(LHS, RHS)) \
return
More information about the libc-commits
mailing list