1 //===-- Unittests for ArgList ---------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/__support/arg_list.h" 10 #include "src/__support/macros/properties/os.h" 11 12 #include "test/UnitTest/Test.h" 13 14 int get_nth_int(int n, ...) { 15 va_list vlist; 16 va_start(vlist, n); 17 LIBC_NAMESPACE::internal::ArgList v(vlist); 18 va_end(vlist); 19 20 for (int i = 0; i < n; ++i) { 21 v.next_var<int>(); 22 } 23 return v.next_var<int>(); 24 } 25 26 TEST(LlvmLibcArgListTest, BasicUsage) { 27 ASSERT_EQ(get_nth_int(5, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90), 50); 28 } 29 30 int sum_two_nums(int first, int second, ...) { 31 va_list vlist; 32 va_start(vlist, second); 33 LIBC_NAMESPACE::internal::ArgList v1(vlist); 34 va_end(vlist); 35 36 LIBC_NAMESPACE::internal::ArgList v2 = v1; 37 38 int first_val; 39 for (int i = 0; i < first; ++i) { 40 v1.next_var<int>(); 41 } 42 first_val = v1.next_var<int>(); 43 44 int second_val; 45 for (int i = 0; i < second; ++i) { 46 v2.next_var<int>(); 47 } 48 second_val = v2.next_var<int>(); 49 50 return first_val + second_val; 51 } 52 53 TEST(LlvmLibcArgListTest, CopyConstructor) { 54 ASSERT_EQ(sum_two_nums(3, 1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024), 55 10); 56 57 ASSERT_EQ(sum_two_nums(3, 5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024), 58 40); 59 } 60 61 long int check_primitives(int first, ...) { 62 va_list vlist; 63 va_start(vlist, first); 64 LIBC_NAMESPACE::internal::ArgList args(vlist); 65 va_end(vlist); 66 67 long int count = 0; 68 count += args.next_var<int>(); 69 count += args.next_var<int>(); 70 count += args.next_var<int>(); 71 count += args.next_var<long>(); 72 count += args.next_var<unsigned long>(); 73 count += args.next_var<long long>(); 74 count += args.next_var<unsigned long long>(); 75 count += args.next_var<double>(); 76 count += args.next_var<double>(); 77 count += args.next_var<long double>(); 78 count += *args.next_var<int *>(); 79 return count; 80 } 81 82 TEST(LlvmLibcArgListTest, TestPrimitiveTypes) { 83 char c = '\x01'; 84 short s = 2; 85 int i = 3; 86 long l = 4l; 87 unsigned long ul = 5ul; 88 long long ll = 6ll; 89 unsigned long long ull = 7ull; 90 float f = 8.0f; 91 double d = 9.0; 92 long double ld = 10.0L; 93 long v = 11; 94 void *p = &v; 95 ASSERT_EQ(check_primitives(0, c, s, i, l, ul, ll, ull, f, d, ld, p), 66l); 96 } 97 98 struct S { 99 char c; 100 short s; 101 int i; 102 long l; 103 float f; 104 double d; 105 }; 106 107 long int check_struct_type(int first, ...) { 108 va_list vlist; 109 va_start(vlist, first); 110 LIBC_NAMESPACE::internal::ArgList args(vlist); 111 va_end(vlist); 112 113 S s = args.next_var<S>(); 114 int last = args.next_var<int>(); 115 return s.c + s.s + s.i + s.l + s.f + s.d + last; 116 } 117 118 TEST(LlvmLibcArgListTest, TestStructTypes) { 119 S s{'\x1', 2, 3, 4l, 5.0f, 6.0}; 120 ASSERT_EQ(check_struct_type(0, s, 1), 22l); 121 } 122 123 // Test vector extensions from clang. 124 #if !defined(LIBC_TARGET_OS_IS_WINDOWS) && __has_attribute(ext_vector_type) 125 126 using int1 = int __attribute__((ext_vector_type(1))); 127 using int2 = int __attribute__((ext_vector_type(2))); 128 using int3 = int __attribute__((ext_vector_type(3))); 129 using int4 = int __attribute__((ext_vector_type(4))); 130 131 int check_vector_type(int first, ...) { 132 va_list vlist; 133 va_start(vlist, first); 134 LIBC_NAMESPACE::internal::ArgList args(vlist); 135 va_end(vlist); 136 137 int1 v1 = args.next_var<int1>(); 138 int2 v2 = args.next_var<int2>(); 139 int3 v3 = args.next_var<int3>(); 140 int4 v4 = args.next_var<int4>(); 141 142 return v1.x + v2.x + v2.y + v3.x + v3.y + v3.z + v4.x + v4.y + v4.z + v4.w; 143 } 144 145 TEST(LlvmLibcArgListTest, TestVectorTypes) { 146 int1 v1 = {1}; 147 int2 v2 = {1, 2}; 148 int3 v3 = {1, 2, 3}; 149 int4 v4 = {1, 2, 3, 4}; 150 ASSERT_EQ(check_vector_type(0, v1, v2, v3, v4), 20); 151 } 152 153 #endif 154