blob: 152905622fe714c5d4058d706e1ed97e71b106f5 [file] [log] [blame]
// 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
#ifndef __testsuite_dot_h
#define __testsuite_dot_h
#include <stddef.h>
#include "../../selector.h"
typedef long VTBL_ENTRY;
#define LPSELECT(a,b) ABISELECT(a,b)
#define vfunc_called(a,b)
#define NO_STATIC_CHECKS 1
#ifdef __cplusplus
#define STRUCT_IF_C
#else
#define STRUCT_IF_C struct // in C mode we neet put 'struct' before typetag
#endif
#define ALT_NAMES_TERMINATOR ((VTBL_ENTRY)1)
#define __tsi64 long long
#define __tsu64 unsigned long long
#define __tsulong unsigned long
extern int verbose, num_classes , n_errors , n_tests ;
//typedef char char_al_16 __attribute__((aligned(16)));
//typedef char char_al_32 __attribute__((aligned(32)));
//typedef char char_al_64 __attribute__((aligned(64)));
//typedef char char_al_128 __attribute__((aligned(128)));
//typedef char char_al_256 __attribute__((aligned(256)));
//typedef char char_al_512 __attribute__((aligned(512)));
//typedef char char_al_1024 __attribute__((aligned(1024)));
//typedef char char_al_2048 __attribute__((aligned(2048)));
typedef struct { char __attribute__((aligned(16))) a[16]; } sal_16;
typedef struct { char __attribute__((aligned(32))) a[32]; } sal_32;
typedef struct { char __attribute__((aligned(64))) a[64]; } sal_64;
typedef struct { char __attribute__((aligned(128))) a[128]; } sal_128;
typedef struct { char __attribute__((aligned(256))) a[256]; } sal_256;
typedef struct { char __attribute__((aligned(512))) a[512]; } sal_512;
typedef struct { char __attribute__((aligned(1024))) a[1024]; } sal_1024;
typedef struct { char __attribute__((aligned(2048))) a[2048]; } sal_2048;
// A struct to map names of functions to their ptrs. A terminated array of
// these is attached to each Class_Descriptor
typedef struct {
void (*func)();
const char *name;
} Name_Map;
#define NSPAIR(name) { &name, #name}
#define NSPAIRA(name) { name, #name}
typedef struct Class_Descriptor Class_Descriptor;
// A structure to represent base classes
// or destructing a derived class under test. An array of these is attached to the
// Class_Descriptor. That array specifies expected sequence of base classses that will
// be constructed while constructing the
typedef struct _base_class {
Class_Descriptor *type; // class decriptor of the base
ptrdiff_t ofst; // offset in derived class
ptrdiff_t vtbl_ofst; // if >=0, the index of vtable component for this base class inside
// the full object. This is not where the baseclass.vptr field will
// point to, though. For that we need to add num_negative_vtbl_entries
ptrdiff_t num_negative_vtbl_entries;
// In the full object, the base_class.vptr points to
// *(vtbl_enrty**)(full_object_address+b->ofst) ==
// b->base->tv.typeinfo_var_ptr + b->vtbl_ofst+b->num_negative_vtbl_entries
unsigned int index_in_vtt;
// if base needs a vftbl, this is the index of that vftbl in the vtt
// of the derived class. Both this and next field are 1-shifted, in
// the sense that the value 0 indicates that this field is unused, and
// value N represends index (N-1)
unsigned int base_subarray_index_in_vtt;
// if base needs a vtt itself, this is the index of that vtt set
// in its parent vtt.
int init_seq; // while initializing final derive ctor-body of this base classs is
// executed at this seq, from 1. If <0, if that base class has no
// ctor, so a call to note_ctor will not be made for this
int parent_idx; // indexof direct parent, if any. -1 if none
unsigned char is_direct, is_virtual;
} Base_Class;
typedef struct {
VTBL_ENTRY *var;
char *name;
} vName_Map;
typedef struct {
VTBL_ENTRY **var;
char *name;
} vpName_Map;
typedef struct {
VTBL_ENTRY *vtbl;
unsigned short ofst, size;
} VTT_ENTRY;
struct Class_Descriptor {
char *name; // mangled class name
Base_Class *bases; // a NULL terminated arrray of ptrs to Class_Descriptors of direct bases
int n_bases;
VTBL_ENTRY *expected_vtbl_contents;
// ptr to an initialized array of ints having expected vtbl contents
VTT_ENTRY *expected_vtt_contents;
// ptr to an initialized array of VTT_ENTRY having expected vtt contents
// VTT entries contain a ptr to an expected point in vtbl, and a negative ofst
// and size, if that point is not in the main vtbl variable
int class_size;
struct {
VTBL_ENTRY *typeinfo_var_ptr; // actually it is a typeinfo ptr, but it is pointed to by a
// vtbl_entry, so it is more convenient this way
const char *typeinfo_var_name;
} tv;
int tv_size;
// The virtual function table var is a combined
vName_Map vtbl; // extern reference to vtbl var, defined by the compiler under test
int vtbl_size, // number of entries in vtbl var. This not the
vtbl_ofst; // offset from top of vtbl_var where the class attaches to it
// size before address point is vtbl_ofst. total size is vtbl_size
vpName_Map vtt; // extern reference to VTT name, defined by the compiler under test
int vtt_size;
unsigned int n_initialized_bases;
unsigned char has_virtual_bases;
unsigned char has_class_type_fields;
VTBL_ENTRY *alt_thunk_names;
};
#ifdef __cplusplus
//inline void *operator new(std::size_t, void * x) { return x;}
inline void *operator new(size_t, void * x) { return x;}
extern "C" {
#endif
extern long long hide_sll(long long);
extern unsigned long long hide_ull(unsigned long long);
extern void f_note_ctor(const char *, void*, const char *, int);
extern void f_note_dtor(const char *, void*, const char *, int);
extern void init_test(Class_Descriptor*, void *addr);
extern void init_simple_test(const char *name);
extern void f_check2(int actual, int expected, const char *name, const char *filename, int linenum);
extern void f_check_field_offset(void *var_p, void *fld_p, int expected_ofst, const char *name, const char *filename,int linenum);
extern void Check_Ctor_Dtor_Calls(void *);
void test_class_info(void *, Class_Descriptor*);
void test_bitfield_value(void *obj_ptr, unsigned byte_offset, unsigned bit_offset, unsigned bit_size, long long expected_value, unsigned obj_size, const char *name, const char *filename, int linenum);
void clear_var(void *a, unsigned sz);
#ifdef __cplusplus
}
#endif
#define note_ctor(a,b) f_note_ctor(a,b,__FILE__, __LINE__)
#define note_dtor(a,b) f_note_dtor(a,b,__FILE__, __LINE__)
#ifdef NO_STATIC_CHECKS
// This version of checking macros does all checking at runtime.
#define check2(a, b, c) f_check2(a,b,c,__FILE__, __LINE__)
#else // !NO_STATIC_CHECKS
// This version of checking macros reports test failures at compiler time. The resulting code
// is smaller with this version, but even one failure will prevent the build
#define check2(a,b,c) { extern int jj[(2*((a)==(b)))-1];n_tests++;}
#endif // !NO_STATIC_CHECKS
#define check_field_offset(var, fld, ofst, name) \
f_check_field_offset(&var, &(var.fld), ofst, name, __FILE__, __LINE__)
#define check_base_class_offset(var, derivation_seq, ofst, cn) \
f_check_field_offset(&var, derivation_seq &var, ofst, #derivation_seq cn, __FILE__, __LINE__)
#define AMB_check_base_class_offset(var, derivation_seq, ofst, cn)
#define set_bf_and_test(var, bitfield, byte_ofst, bit_ofst, bit_size, value, classname) \
{var.bitfield = value; \
test_bitfield_value(&var, byte_ofst, bit_ofst, bit_size, value, sizeof(var),classname "." #bitfield, __FILE__, __LINE__);}
typedef void (*voidfunc)(void);
typedef struct _atcm { // The C struct equivalent to Arrange_To_Call_Me
voidfunc func;
struct _atcm *next;
const char *name;
} ATCM;
#ifdef __cplusplus
extern struct Arrange_To_Call_Me *atcm_head;
struct Arrange_To_Call_Me {
voidfunc func;
Arrange_To_Call_Me *next;
const char *name;
Arrange_To_Call_Me(voidfunc f, const char *n, unsigned size=10) {
if (size <= 10240) {
func = f;
next = atcm_head;
atcm_head = this;
name = n;
}
}
};
#define ARRANGE_TO_CALL_ME(func,cn) Arrange_To_Call_Me v##cn(func, #cn, sizeof(cn));
#else
extern void atc_register(voidfunc func, const char *name, size_t sz);
#define ARRANGE_TO_CALL_ME(func,cn) __attribute__((constructor)) static void atc_##cn() \
{ atc_register(func,#cn, sizeof(struct cn));}
#endif
// bs is the size of a signed bitfield in bits. v is a constant being assigned to it.
// sign extend v.
#define SEXT_BFV(bs,v) ((v)|(((v) & (1ULL<<((bs)-1))) ? (~(1ULL<<(bs))) : 0))
#endif // __testsuite_dot_h