blob: 4f229e2bfe69408bcbf012e5f3d12a1f4c81cffa [file] [log] [blame]
//===-- Unittests for ArgList ---------------------------------------------===//
//
// 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 "src/__support/arg_list.h"
#include "test/UnitTest/Test.h"
int get_nth_int(int n, ...) {
va_list vlist;
va_start(vlist, n);
LIBC_NAMESPACE::internal::ArgList v(vlist);
va_end(vlist);
for (int i = 0; i < n; ++i) {
v.next_var<int>();
}
return v.next_var<int>();
}
TEST(LlvmLibcArgListTest, BasicUsage) {
ASSERT_EQ(get_nth_int(5, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90), 50);
}
int sum_two_nums(int first, int second, ...) {
va_list vlist;
va_start(vlist, second);
LIBC_NAMESPACE::internal::ArgList v1(vlist);
va_end(vlist);
LIBC_NAMESPACE::internal::ArgList v2 = v1;
int first_val;
for (int i = 0; i < first; ++i) {
v1.next_var<int>();
}
first_val = v1.next_var<int>();
int second_val;
for (int i = 0; i < second; ++i) {
v2.next_var<int>();
}
second_val = v2.next_var<int>();
return first_val + second_val;
}
TEST(LlvmLibcArgListTest, CopyConstructor) {
ASSERT_EQ(sum_two_nums(3, 1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024),
10);
ASSERT_EQ(sum_two_nums(3, 5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024),
40);
}
long int check_primitives(int first, ...) {
va_list vlist;
va_start(vlist, first);
LIBC_NAMESPACE::internal::ArgList args(vlist);
va_end(vlist);
long int count = 0;
count += args.next_var<int>();
count += args.next_var<int>();
count += args.next_var<int>();
count += args.next_var<long>();
count += args.next_var<unsigned long>();
count += args.next_var<long long>();
count += args.next_var<unsigned long long>();
count += args.next_var<double>();
count += args.next_var<double>();
count += args.next_var<long double>();
count += *args.next_var<int *>();
return count;
}
TEST(LlvmLibcArgListTest, TestPrimitiveTypes) {
char c = '\x01';
short s = 2;
int i = 3;
long l = 4l;
unsigned long ul = 5ul;
long long ll = 6ll;
unsigned long long ull = 7ull;
float f = 8.0f;
double d = 9.0;
long double ld = 10.0L;
long v = 11;
void *p = &v;
ASSERT_EQ(check_primitives(0, c, s, i, l, ul, ll, ull, f, d, ld, p), 66l);
}
struct S {
char c;
short s;
int i;
long l;
float f;
double d;
};
long int check_struct_type(int first, ...) {
va_list vlist;
va_start(vlist, first);
LIBC_NAMESPACE::internal::ArgList args(vlist);
va_end(vlist);
S s = args.next_var<S>();
int last = args.next_var<int>();
return s.c + s.s + s.i + s.l + s.f + s.d + last;
}
TEST(LlvmLibcArgListTest, TestStructTypes) {
S s{'\x1', 2, 3, 4l, 5.0f, 6.0};
ASSERT_EQ(check_struct_type(0, s, 1), 22l);
}
// Test vector extensions from clang.
#if __has_attribute(ext_vector_type)
using int1 = int __attribute__((ext_vector_type(1)));
using int2 = int __attribute__((ext_vector_type(2)));
using int3 = int __attribute__((ext_vector_type(3)));
using int4 = int __attribute__((ext_vector_type(4)));
int check_vector_type(int first, ...) {
va_list vlist;
va_start(vlist, first);
LIBC_NAMESPACE::internal::ArgList args(vlist);
va_end(vlist);
int1 v1 = args.next_var<int1>();
int2 v2 = args.next_var<int2>();
int3 v3 = args.next_var<int3>();
int4 v4 = args.next_var<int4>();
return v1.x + v2.x + v2.y + v3.x + v3.y + v3.z + v4.x + v4.y + v4.z + v4.w;
}
TEST(LlvmLibcArgListTest, TestVectorTypes) {
int1 v1 = {1};
int2 v2 = {1, 2};
int3 v3 = {1, 2, 3};
int4 v4 = {1, 2, 3, 4};
ASSERT_EQ(check_vector_type(0, v1, v2, v3, v4), 20);
}
#endif