xref: /llvm-project/libc/test/src/__support/arg_list_test.cpp (revision ded080152acceca5d68014d63f5027a6d8266cbb)
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