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

source code of libc/test/src/__support/arg_list_test.cpp