// 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 "testsuite.h"


#if 0 // __linux__
Not yet. 
#define _GNU_SOURCE
#include <dlfcn.h>
static char *find_symname(void *addr, char *buf);
#else
#define find_symname(a,b) ""
#endif

#include <stdio.h>
#include <string.h>

// given a full pathname, return path starting from test
static char *trim_fn(const char *ifn)
{
  // basically find last /test/
  char *x, *fn = (char*) ifn;
  char *rv = fn;
  if (!strncmp(fn, "test/", 5))
    return fn; // fn starts with test/
  while ((x = strstr(rv, "/test/"))) // look for /test/
    rv = x+1;
  return rv;
}

#define TRUE 1
#define FALSE 0
int num_classes = 0, n_errors = 0, n_tests = 0;
int verbose = 0;
int test_finished = FALSE;
void f_check2(int actual, int expected, const char *name, const char *filename, int linenum)
{
  n_tests++;
  if (actual != expected) {
    printf("ERROR at %s:%d '%s' actual %d != expected %d\n", trim_fn(filename), linenum, name, actual, expected);
    n_errors++;
  } else if (verbose > 1) {
    printf("OK at %s:%d '%s' = %d\n", trim_fn(filename), linenum, name, actual);
  }
}

void f_check_field_offset(void* ps, void* pf, int ofst, const char *name, const char * filename, int linenum)
{
  n_tests++;
  if ((((char*)ps) + ofst) != ((char*)pf)) {
    //printf("ERROR at %s:%d '%s' 0x%p + %d != 0x%p\n", trim_fn(filename), linenum, name, ps, ofst, pf);
    printf("ERROR at %s:%d '%s' expected ofst %d != actual ofst %d\n", trim_fn(filename), linenum, 
               name, ofst, (int)(((char*) pf)-((char*) ps)));
    n_errors++;
  } else if (verbose > 1) {
    printf("OK at %s:%d '%s' expected ofst = %d\n", trim_fn(filename), linenum, name, ofst);
  }
}


static Class_Descriptor *cur_cd;

static void *full_object_address; // address of the full object being constructed.
        // This is used to do checks for ctors and dtors during the construction. 
        // if the object is being constructed via a placement new, we know the address before
        // the ctors starts, else this is deduced from the first call to a ctor.

static int cur_init_seq;
static int ctors_done; // set to 1 once the full object has been created.

void 
init_simple_test(const char *name)
{
  num_classes++;
  cur_cd = NULL;
  if (verbose)
    printf("Testing class %s\n", name);
}

void 
init_test(Class_Descriptor *cd, void *var_addr)
{
  cur_cd = cd;
  full_object_address = var_addr;
  cur_init_seq = 0;
  num_classes++;
  ctors_done = 0;
  if (verbose)
  printf("Testing class %s\n", cd->name);
}

#include <stdarg.h>
extern void abort();
extern void exit(int);
static void Blow_Up(const char *m, ...)
{
  va_list ap;
  va_start(ap, m);
  printf("Assertion Failed: ");
  vprintf(m, ap);
  printf("\n");
  exit(1);
}

#define Is_True(a, b) if (!(a)) Blow_Up b

static Base_Class *
find_base_from_seq_num(Class_Descriptor *cd, int seq)
{
  Base_Class *b = cur_cd->bases;
  if (b) {
    for (; b->type; b++) 
      if (b->init_seq == seq)
        return b;
  }
  return NULL;
}


static int satisfies_alternate_matches(VTBL_ENTRY expected, VTBL_ENTRY actual, 
                                         Class_Descriptor *cd, int t)
{
  VTBL_ENTRY *alt_tbl = cd->alt_thunk_names;
  int i=0, state = 0;

  if (!alt_tbl) return 0;
  // alt_tbl is an array of items separated by a single NULL and terminated by another NULL
  // each item is a sequence of VTBL entrie such that the first one is the expected value and
  // rest of them are acceptable alternate values
  // state machine: state 0 at the start. state 1 inside the list of extected. 2 inside other list
  // state    ANTERM    expected   actual   any-non-NULL
  // 0         F         1         F          2
  // 1         F         F         T          1
  // 2         0         2         2          2
  // 
  //printf(" SAM EXP:%p ACT:%p CD=%p tbl:%p t=%d\n", expected, actual, cd, alt_tbl, t);
  while (1) {
    VTBL_ENTRY v = alt_tbl[i];
    //printf("  [%d] %d= ", i, state); 
    //printf((v==NULL)?" 0\n":(v==ALT_NAMES_TERMINATOR)?" ALNT\n":":%p\n", v);
    switch (state) {
      case 0: 
        if (v == expected) 
          state = 1;
        else if (v == actual || v == ALT_NAMES_TERMINATOR)
          return FALSE;
        else
          state = 2;
        break;
      case 1:
        if (v == actual) {
          return TRUE;
        } else if (v == ALT_NAMES_TERMINATOR || v == expected) {
          return TRUE; // this allows tests to pass if the expected sym is a virtual thunk
                       // but the actual sym is not in the alternate lists. This can happen
                       // if there are multiple virtual thunks reaching same place, and
                       // some compiler selects a different one than our. For now we are
                       // allowing that. Perhaps we can figure out a way of tightening this
                       // by 
                       //    - adding all possible thunks that reach same place, 
                       //    - somehow comparing thunks for equivalence
          //return FALSE;
        } else 
          state = 1;
        break;
      case 2:
        state = (v == ALT_NAMES_TERMINATOR) ? 0 : 2;
    }
    i++;
  }
}


// actual points to the VTT variable defined by the compiler under test.
// expected points to an array of VTT_ENTRY structures. Each VTT_ENTRY structure has a 
// field 'VTBL_ENTRY *vtbl', which must match the corresponding entry of actual. However,
// the meaning of the match is non-trivial. If expected[i].ofst==0, actual[i] and expected[i].vtbl
// both must point to same element of the primary vtbl of the class, hence the pointer values
// must match. if expected[i].ofst is non-zero, both point to copies of secondary vtables whose 
// contents must be same. In that case, we run memcmp on those vtables.
static void 
check_vtt_tbl(Class_Descriptor *cd, VTT_ENTRY *expected, VTBL_ENTRY **actual, char *name, int size)
{
  int i, j;
  n_tests++;
  if (verbose > 1) 
    printf("check_vtt_tbl %s %s EXPECTED:%p ACTUAL:%p %d\n", cd->name, name, expected, actual, size);
  for (i=0; i<size; i++) {
    if (expected[i].vtbl != actual[i]) {
      // actual pointers do not match, but the contents could still match. 
      int ofst = expected[i].ofst;
      int size = expected[i].size;
      VTBL_ENTRY *exp = expected[i].vtbl - ofst;
      VTBL_ENTRY *act = actual[i] - ofst;
      int n_mismatches = 0;
      if (memcmp(exp, act, size*sizeof(VTBL_ENTRY)) == 0) {
        // contents match. 
        continue;
      }
      for (j=0; j<size; j++) {
        if (exp[j] != act[j] && !satisfies_alternate_matches(exp[j], act[j], cd, j)) {
          if (n_mismatches==0) {
            static char erb1[10240], erb2[10240];
            if (act[j] == NULL) {
              continue; // a vtbl entry can be NULL in clang, if clang chooses to always use another vtbl
            }
            printf("ERROR: Expected contents of %s::vtbl from vtt, for class %s do not match. at index %d. "
                   "memcmp(EXPECTED:%p,ACTUAL:%p,%d)\n", 
                   name, cd->name, j, exp, act, (int)(size*sizeof(VTBL_ENTRY)));
            n_mismatches++;
            n_errors++;
            printf("   %d: EXPECTED:%p%s ACTUAL:%p%s\n", j, 
                    (void*)exp[j], find_symname((void*)exp[j], erb1),
                    (void*)act[j], find_symname((void*)act[j], erb2));
          }
        }
      }
    }
  }
}


static void 
check_vftbl(Class_Descriptor *cd, void *expected, void *actual, char *name, int size)
{
  int i, n_mismatches=0;
  n_tests++;
  if (verbose > 1) 
    printf("check_vftbl %s %s %p %p %d\n", cd->name, name, expected, actual, size);
  if (memcmp(expected, actual, sizeof(VTBL_ENTRY)*size)) {
    void **pexp = (void**) expected;
    void **pact = (void**) actual;
    for (i=0; i<size; i++) {
      if (pexp[i] != pact[i] && 
              !satisfies_alternate_matches((VTBL_ENTRY)pexp[i], (VTBL_ENTRY)pact[i], cd, -i)) {
        static char erb1[10240], erb2[10240];
        if (pact[i] == NULL) {
          continue; // a vtbl entry can be NULL in clang, if clang chooses to always use another vtbl
        }
          
        if (n_mismatches==0) {
          printf("ERROR: Expected contents of %s::vtbl, for class %s do not match.\n", name, cd->name);
          n_errors++;
          n_mismatches++;
        }
        printf("  %d: EXPECTED:%p%s ACTUAL:%p%s\n", i, pexp[i], find_symname(pexp[i], erb1),
                pact[i], find_symname(pact[i], erb2));
      }
    }
  }
}

// if derivation of b in cd has any virtual steps, return he most-derived such base, else 
// return NULL
static Base_Class *
any_virtual_steps_in_derivation(Class_Descriptor *cd, Base_Class *b)
{
  // first a simple assertion check that b is a base class of cd
  Is_True(
    cd->bases &&  // cd has bases
    (b >= cd->bases) && ((b-cd->bases) < cd->n_bases) && // b lies between first and last base of cd
    ((cd->bases + (b-cd->bases)) == b), // it is a proper Base_Class ptr
          ("Wrong base in any_virtual..."));
  while (1) {
    if (b->is_virtual)
      return b;
    if (b->parent_idx < 0)
      return 0;
    b = cd->bases + b->parent_idx;
  }
}

// check tbls of cd and all non-virtual bases, and, if check_virtual_bases is TRUE, its
// virtual bases as well. This flag will be true when the var_ptr points to a full object of 
// type cd, i.e., 
//  - when the cd is the main class under test and the full object of cd has been constructed,
//    and destruction has not yet started,
//  - or, if cd is a base class of the class under test, but cd itself does not have any 
//    virtual base classes and we are currently in ctor or dtor of cd.
static void 
check_full_object_vtbls(void *var_ptr, Class_Descriptor *cd, int check_virtual_bases)
{
  Base_Class *b;
  // check that the initialized contents of the main vtbl variable, as generated by the 
  // compiler-under-test are what we expect them to be
  if (cd->expected_vtbl_contents) {
      check_vftbl(cd, cd->expected_vtbl_contents, cd->vtbl.var, cd->vtbl.name, cd->vtbl_size);
      // check that the fully initialized object attaches to that vtbl variable at correct
      // offset. i.e., var_ptr[0] should point inside the vtbl_var+vtbl_ofst. 
      // However, if var_ptr is does not point to a full object of cd (indicated by 
      // check_virtual_bases being false), and cd has some virtual bases, its vtbl will not match
      // the cd->vtbl_var because that reflects the shape of a full object of cd.
      if (check_virtual_bases || !cd->has_virtual_bases) {
        if ((*(VTBL_ENTRY**)var_ptr) != (cd->vtbl.var + cd->vtbl_ofst)) {
          printf("ERROR: Object of class %s::%s does not point to expected spot in vtbl\n", cur_cd->name, cd->name);
          n_errors++;
        }
      }
  }
  // check that any non-primary base classes also attach to the expected offsets
  if (cd->bases)
  for (b=cd->bases; b->type; b++) {
      if (b->ofst != 0 && b->vtbl_ofst >= 0 && (check_virtual_bases || !any_virtual_steps_in_derivation(cd, b))) {
        // cd->vtbl.var is the vbl variable. It contains the main vtbl, followed by vtbls
        // for base classes at non-zero offsets. b->vtbl_ofst is the offset (in terms of vtbl 
        // entries) of the b's vtbl in the main vtbl. But the object does not attach to the top
        // of any vtbl; it attaches at least two entries down, and maybe more. That is given by 
        // b->num_negative_vtbl_entries
        if ((*(VTBL_ENTRY**)(b->ofst+(char*)var_ptr)) !=
                (cd->vtbl.var + (b->vtbl_ofst+b->num_negative_vtbl_entries))) {
          printf("ERROR: base class %s of class %s::%s does not have correct vtbl ", b->type->name,
                 cur_cd->name,  cd->name);
          printf("0x%x != (0x%x + %d + %d) = 0x%x\n",
          (int)(*(VTBL_ENTRY**)(b->ofst+(char*)var_ptr))  ,
              (int)cd->vtbl.var ,(int) b->num_negative_vtbl_entries, (int)b->vtbl_ofst,
              (int)(cd->vtbl.var + (b->vtbl_ofst+b->num_negative_vtbl_entries)));
          n_errors++;
        }
      }
  }
}



// Given a derived class der, and it base class entry b. d_in_b is a Base_Class entry in
// b->type. Find corresponding Base_Class entry of der.
// There are three possible situations:
// 1) d_in_b is virtual by itself. In that case we need to just find a virtual base class of same
//    type in der. Since there can be only one such virtual base class in der, that is all.
// 2) d_in_b is not virtual, and there are no virtual steps from b to d_in_b. In this case
//    the relative offset of b-to-d_in_b will be same in der as it is in a b. So we just look
//    for a base class of expected type at such computed offset.
// 3) Third case is more complicated. here d_in_b is not virtual by itself, but there are virtual
//    steps in b-to-d_in_b derivation. Say a base class t is lowest such step, i.e., t is a 
//    virtual base of b, and d_in_b is a base class of t without any virtual steps from t to 
//    d_in_b. In this case we first find the virtual base t in der using rule 1, and then use 
//    rule 2 to find the final answer
//
static Base_Class *
find_corresp_base(Class_Descriptor *der, Base_Class *b, Base_Class *d_in_b)
{
  Base_Class *t, *p, *q;

  if (d_in_b->is_virtual) {
    // case 1
    for (t = der->bases; t < (der->bases + der->n_bases); t++)
      if (t->is_virtual && t->type == d_in_b->type)
        return t;
    Is_True(0, ("Count not find virtual base class %s in %s", d_in_b->type->name, der->name));
  }
  if (!(p=any_virtual_steps_in_derivation(b->type, d_in_b))) {
    // case 2
    for (t = der->bases; t < (der->bases + der->n_bases); t++)
      if ((!t->is_virtual) && t->ofst == (b->ofst + d_in_b->ofst) && t->type == d_in_b->type )
        return t;
    Is_True(0, ("Count not find non virtual base class %s in %s", d_in_b->type->name, der->name));
  }

  // case 3. First we find the highest non-virtual derived class from d_in_b
  q = find_corresp_base(der, b, p);// use rule 1. This will work because we know that p is virtual
  for (t = der->bases; t < (der->bases + der->n_bases); t++)
    if ((!t->is_virtual) && t->ofst == (q->ofst + d_in_b->ofst-p->ofst) && t->type == d_in_b->type )
      return t;
  Is_True(t<(der->bases + der->n_bases), ("Could not find_corresp_base(%s, %s, %s)", der->name, 
              b->type->name, d_in_b->type->name));
  return 0;
}

// same as strcat, but some toolkits do not have strcat
static void 
mystrcat(char *a, char *b)
{
  int i, j;
  for (j=0; a[j]; j++) ;
  for (i=0; b[i]; i++) a[j++] = b[i];
  a[j] = 0;
}

// Called from ctor and dtors of base classes of the main class under test (which is cur_cd).
// init_seq is the sequence number of ctors, which increases from 1 till the whole class has
// been contructed, and decreases back. n is the name of the baseclass whose ctor/dtor has 
// been called. this_p is the 'this' pointer being pass the ctor/dtor. The task here is to check
// that correct vtbls are being passed to the current class being constructed, and all its
// base classes.
void 
check_base(int init_seq, const char *n, void* this_p, const char *filename, int linenum)
{
  Base_Class *b;
  if (verbose> 1) 
    printf("check_%ctor %s %p-%p from %s:%d cur_cd=%s init_seq=%d cur_init_seq=%d\n", 
            ctors_done?'d':'c',
            n, this_p, full_object_address, trim_fn(filename), linenum, cur_cd->name, init_seq, cur_init_seq);
  if (init_seq == 1 && !full_object_address) {
    // this is first call. Go through base classes of cur_cd to find the base with 
    // init_seq==1, and deduce the full object address from that. 
    b = find_base_from_seq_num(cur_cd, 1);
    Is_True(b, ("first-init base not found"));
    full_object_address = (void*) (((char*)this_p) - b->ofst);
  } else {
    // find the base with this init seq
    b = find_base_from_seq_num(cur_cd, init_seq);
    Is_True(b, ("init base %s %d not found", cur_cd->name, init_seq));
  }
  if (strcmp(b->type->name, n)) {
    printf("Wrong ctor/dtor being called \n");
    n_errors++;
    return;
  }
  if (full_object_address != (void*) (((char*)this_p) - b->ofst)) {
    printf("ERROR: %ctor of %s::%s being called with wrong offset 0x%p != 0x%p+%d = 0x%p\n", 
            ctors_done?'d':'c', cur_cd->name, b->type->name,
            this_p, full_object_address, (int)b->ofst, 
             ((char*)full_object_address)+b->ofst);
    n_errors++;
    return;
  }
  if (!cur_cd->vtbl.var)
    return; // nothing further to check.
  // While construction a full object A, during construction or destruction of a subobject, 
  // say B, the virtual function set of A::B must be same as the full object B, irrespective of
  // any virtual function overrides between B and A. However, the shape of A::B is not necessarily
  // same of the full object B.
  if (!b->type->has_virtual_bases) {
    // The shape of A::B is same as the full object B, since B does not have any virtual bases.
    // In that case, we can just run the full_object test.
    check_full_object_vtbls(this_p, b->type, TRUE);
  } else {
    // b->type has some virtual bases of its own. So the shape is not same as that of a full 
    // b->type, but the virtual function set is. In this case check the primary vtbl, and 
    // each base class separately.
    // We are running ctor of B, while constructing full object A
    // First, the primary vtbl test.
    //   a) if b->type_subarray_index_in_vtt is non-zero, the primary vtable is A.vtt[b.index_in_vtbl-1]
    //   b) else find the lowest parent, D, of B whose Base_Class entry for class B has a non-zero 
    //      index_in_vtt. (this is a_base_class.index_in_construction_vtable_array). There 
    //      must be one.
    //   c) proceed up from D to A, collecting 
    //      (base_subarray_index_in_vtt-1) whereever base_subarray_index.. is non-zero, and
    //      add that to the number of the last step.
    VTBL_ENTRY *pointed_tbl = *(VTBL_ENTRY**)this_p;
    VTT_ENTRY *vttp;
    Base_Class *d_in_b, *d_in_cur_cd;
    Class_Descriptor *bc = b->type;
    //check_full_object_vtbls(this_p, b->type, FALSE); // check non-virtual base classes, if any
    Is_True(b->base_subarray_index_in_vtt>0, ("%s::%s->type_subarray_index_in_vtt must be >0",
                                                   cur_cd->name, bc->name));
    vttp = cur_cd->expected_vtt_contents + (b->base_subarray_index_in_vtt-1);
    check_vftbl(cur_cd, vttp->vtbl - vttp->ofst, pointed_tbl-vttp->ofst, b->type->name, vttp->size);
    // and now we need to check vtbls of all subclasses of b that use vtbl.
    // scan all base classes of B, and find corresponding Base_Class entry in cur_cd->bases
    for (d_in_b = bc->bases; d_in_b < (bc->bases+bc->n_bases); d_in_b++) {
      char buf[10240];
      if (!d_in_b->type->vtbl.var)
        continue; // nothing to check for this base
      if (d_in_b->index_in_vtt == 0)
        continue; // checked via some other base
      d_in_cur_cd = find_corresp_base(cur_cd, b, d_in_b);
      if (d_in_b->ofst == 0)
        continue; // d is at offset 0, so the vtbl has already been checked above.
      // we need to take the offset from d_in_cur_cd, because that reflects the shape of cur_cd
      // but we take expected vtbl ptr by first selecting vtt group for b-in-cur_cd and then
      // using d-in-b to pick a particular vtbl
      vttp = cur_cd->expected_vtt_contents + (b->base_subarray_index_in_vtt-1) + (d_in_b->index_in_vtt-1);
      pointed_tbl = *(VTBL_ENTRY**)(((long)full_object_address) + d_in_cur_cd->ofst);

      // follwing four lines are essentially
      //     sprintf(buf, "%s-during-%s()", d_in_b->type->name, bc->name);
      buf[0] = 0;
      mystrcat(buf, d_in_b->type->name);
      mystrcat(buf, "-during-");
      mystrcat(buf, bc->name);
      mystrcat(buf, "()");
      check_vftbl(cur_cd, vttp->vtbl - vttp->ofst, pointed_tbl-vttp->ofst, buf, vttp->size);
    }
  }
}

static Base_Class *find_base_class(ptrdiff_t ofst, Class_Descriptor *cd, const char *name)
{
  Base_Class *bc = cd->bases;
  if (bc) {
    for (; bc < (cd->bases+cd->n_bases); bc++)
      if (bc->ofst == ofst && !strcmp(bc->type->name, name))
        return bc;
  }
  return NULL;
}

void 
f_note_ctor(const char *n, void* this_p, const char *filename, int linenum)
{
  if (cur_cd == NULL) // cur_cd has no base classes. This must be from a field
    return;
  if (!cur_cd->has_class_type_fields) {
    if (strcmp(n, cur_cd->name))
      check_base(++cur_init_seq, n, this_p, filename, linenum);
    // else we have reached the ctor of the top class. The tests will be done by test_class_info
  } else if (cur_cd->n_bases == 0) {
    // nothing to check. ctor is for a field.
  } else {
    // cur_cd has fields that will call constructors and destructors, therefore init_sequence 
    // checks can not be done, but it also has bases that need to be checked.
    // See if a base matches the offset and type, and check that
    Base_Class *bc = find_base_class(((char*)this_p) - ((char*)full_object_address), cur_cd, n);
    if (bc)
      check_base(bc->init_seq, n, this_p, filename, linenum);
  }
}

void 
f_note_dtor(const char *n, void * this_p, const char *filename, int linenum)
{
  if (test_finished)
    return;
  if (cur_cd == NULL) // cur_cd has no base classes. This must be from a field
    return;
  if (!cur_cd->has_class_type_fields) {
    if (strcmp(n, cur_cd->name))
      check_base(cur_init_seq--, n, this_p, filename, linenum);
    // else we are destroying the top class. The tests have been done by test_class_info
  } else if (cur_cd->n_bases == 0) {
    // nothing to check. dtor is for a field.
  } else {
    // cur_cd has fields that will call constructors and destructors, therefore init_sequence 
    // checks can not be done, but it also has bases that need to be checked.
    // See if a base matches the offset and type, and check that
    Base_Class *bc = find_base_class(((char*)this_p) - ((char*)full_object_address), cur_cd, n);
    if (bc)
      check_base(bc->init_seq, n, this_p, filename, linenum);
  }
}

void Check_Ctor_Dtor_Calls(void *op)
{
  if (cur_init_seq != 0) {
    printf("ERROR: Expected number of dtors not called %s\n", cur_cd->name);
    n_errors++;
  }
}


void test_class_info(void *var_ptr, Class_Descriptor* cd)
{
  ctors_done = 1;
  if (verbose > 1) {
    printf("test_class_info %s %p cur_init_seq=%d\n", cd->name, var_ptr, cur_init_seq);
  }
  if (full_object_address && full_object_address != var_ptr) {
    printf("ERROR: full object address does not match deduced address %s\n", cur_cd->name);
    n_errors++;
  }
  if ((cur_init_seq != cd->n_initialized_bases) && !cd->has_class_type_fields) {
    printf("ERROR: Not all bases of %s were initialized \n", cur_cd->name);
    n_errors++;
  }
  if (cd->expected_vtbl_contents) {
    // check that fully constructed object points to correct vtbls.
    check_full_object_vtbls(var_ptr, cd, TRUE);
  }
  if (!cd->vtt.var) {
    // Sunil: may 1, 2014: Made vtt a weak symbol and added '&&cd->vtt.var' check. Clang, with -O
    // does not generate VTT if it is not going to be used, such as if a class X has virtual base 
    // Y but Y has no virtual base of functions. In this case the VTT for X will never be used.
    // TODO: add check for that property; that base classes do not need vtt.
  } else if (cd->expected_vtt_contents) {
    // We can not simply compare the contents of VTT tables always. 
    // VTT table has two kind of entries. Some entries point to elements of main vtbl whose
    // name is specified by the ABI spec, so we refer to them as globally visible name, and
    // we can expec the pointer values in vtt to be same.
    // In other cases though, vtt entries point to aux-vtables, whose names are not specified
    // by the ABI spec, so the generated tests have their own names which are not same as the
    // names generated by the compiler-under-test. Their contents are expected to match, but
    // not the pointer values. The contents are being tested by the ctor vtable tests.
    // TODO: check those vtt entries here that point to main vtbl
    check_vtt_tbl(cd, cd->expected_vtt_contents, cd->vtt.var, cd->vtt.name, cd->vtt_size);
  }
}

static int f_isLittleEndian() {
  unsigned short i = 0xff00;
  unsigned char *i_ptr = (unsigned char *) &i;
  return !(*i_ptr);
}
static int isLittleEndian;

static unsigned char LITTLE_ENDIAN_MASKS[] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
static unsigned char BIG_ENDIAN_MASKS[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };

// Function to read the value of a bitfield
// NOTE: This function implicitly depends on a byte having 8 bits. If a byte is of a different size, several of the calculations would be incorrect.
static long long readValue(unsigned char *iter, unsigned int bit_offset, int size) {
  int is_little_endian = isLittleEndian;
  long long retval = 0;
  unsigned char mask = 0;
  unsigned char adjustment_offset = 0;

  if(!iter) return retval;

  // read the first partial piece (if any)
  if(bit_offset) {
    unsigned char bits_to_read = 8 - bit_offset;
    // Check to see if the object is fully contained within the remaining bits, and if so
    // restrict the read to only those bits.
    if(size < bits_to_read)
      bits_to_read = size;

    if(is_little_endian) {
      mask = LITTLE_ENDIAN_MASKS[bits_to_read] << bit_offset;
      retval = ((*iter) & mask) >> bit_offset;
      adjustment_offset += bits_to_read;
    } else {
      mask = BIG_ENDIAN_MASKS[bits_to_read] >> bit_offset;
      retval = (*iter) & mask;
      // If we read in the entire value, we need to potentially right shift it, and clear 
      // out the upper bits to be safe
      if(size == bits_to_read) {
        retval >>= (8 - (bits_to_read + bit_offset));
        retval &= ~(BIG_ENDIAN_MASKS[8 - bits_to_read]);
      }
    }

    // Decrement the size by the number of bits read, and move to the next byte
    size -= bits_to_read;
    iter++;
  }
  
  // read in a full byte at a time
  while(size >= 8) {
    if(is_little_endian) {
      retval |= ((long long)((*iter) & 0xff)) << adjustment_offset;
      adjustment_offset += 8;
    } else {
      retval <<= 8;
      retval |= (*iter) & 0xff;
    }
    // Decrement the size by a byte and move to the next byte
    size -= 8;
    iter++;
  }

  // read any remaining bits
  if(size) {
    if(is_little_endian) {
      mask = LITTLE_ENDIAN_MASKS[size];
      retval |= ((long long)((*iter) & mask)) << adjustment_offset;
      adjustment_offset += size;
    } else {
      mask = BIG_ENDIAN_MASKS[size];
      retval <<= size;
      retval |= ((*iter) & mask) >> (8 - size);
    }
    size = 0;
    iter = 0;
  }

  return retval;
}


int  is_bitfield_value_correct(void *obj_ptr, unsigned int byte_offset, unsigned int bit_offset, unsigned int size, long long expected_value) {
  long long read_value = readValue(((unsigned char *)obj_ptr) + byte_offset, bit_offset, size);
  unsigned long long expected_mask = 0, i;

  //n_tests++;

  // Calculate the mask to be used for the incoming value which was probably sign extended
  expected_mask = 0;
  for(i = 0; i < size; i += 8) {
    expected_mask <<= 8;
    expected_mask |= 0xff;
  }
  if(size % 8) {
    expected_mask <<= (size % 8);
    expected_mask |= LITTLE_ENDIAN_MASKS[(size % 8)];
  }
  expected_value &= expected_mask;
  read_value &= expected_mask;

  if(read_value != expected_value) 
    return 0;

  return 1;
}
void clear_var(void *a, unsigned b)
{
  // do not rely on memzero
  char *ca = a;
  unsigned i;
  for (i=0; i<b; i++)
    ca[i] = 0;
}



void test_bitfield_value(void *obj_ptr, unsigned int byte_offset, unsigned int bit_offset, 
                         unsigned int size, long long expected_value, unsigned var_size, 
                         const char *name, const char *filename, int linenum) {
  long long read_value = readValue(((unsigned char *)obj_ptr) + byte_offset, bit_offset, size);
  unsigned long long expected_mask = 0, i;

  n_tests++;

  // Calculate the mask to be used for the incoming value which was probably sign extended
  expected_mask = 0;
  if (size > 7)
  for(i = 0; i < size; i += 8) {
    expected_mask <<= 8;
    expected_mask |= 0xff;
  }
  if(size % 8) {
    expected_mask <<= (size % 8);
    expected_mask |= LITTLE_ENDIAN_MASKS[(size % 8)];
  }
  expected_value &= expected_mask;
  read_value &= expected_mask;

  if(read_value != expected_value) {
    int i, found = -1;
    for (i=1; i<20; i++) {
      if ((byte_offset+i) < var_size && is_bitfield_value_correct(obj_ptr, byte_offset+i, bit_offset, size, expected_value)) {
        found = byte_offset+i;
        break;
      }
      if (byte_offset >= i && is_bitfield_value_correct(obj_ptr, byte_offset-i, bit_offset, size, expected_value)) {
        found = byte_offset-i;
        break;
      }
    }
    printf("ERROR at %s:%d Bitfield errors found (expected=0X%llX, got=0X%llX) in %s", 
            trim_fn(filename), linenum, expected_value, read_value, name);
    if (found >= 0) printf(" expected byte ofst %d != actual byte ofst %d", byte_offset, found);
    printf("\n");
    n_errors++;
  }

  return;
}


ATCM *atcm_head;

#ifndef __cplusplus
extern void *malloc(size_t);
void atc_register(voidfunc func, const char *name, size_t sz)
{
  ATCM *sa = (ATCM*) malloc(sizeof(ATCM));
  sa->next = atcm_head;
  atcm_head = sa;
  sa->func = func;
  sa->name = name;
}

#endif


int main(int argc, char **argv)
{
  int i, run_full_test = 1;
  ATCM *p;
  isLittleEndian = f_isLittleEndian();
  for (i=1; i<argc; i++) {
    char *a = argv[i];
    if (a[0] == '-' && a[1] == 'v') {
      verbose++;
      continue;
    }
    for (p=atcm_head; p; p = p->next)
      if (strcmp(a, p->name)==0)
        break;
    if (!p) {
      printf("Unknown arg '%s'\n", a);
      exit(1);
    }
    p->func();
    run_full_test = 0;
  }
  if (run_full_test) {
    ATCM *t, *h = NULL;
    // first reverse the chain
    while (atcm_head) {
      t = atcm_head;
      atcm_head = t->next;
      t->next = h;
      h = t;
    }

    while (h) {
      h->func();
      h = h->next;
    }
  }
  printf("TEST %s. %d classes. %d tests. %d failures.\n", 
           n_errors||!n_tests?"FAILED":"PASSED",num_classes, n_tests, n_errors);
  
  test_finished = TRUE;
  cur_cd = NULL;
  return n_errors != 0;
}

long long hide_sll(long long p) { return p; }
unsigned long long hide_ull(unsigned long long p) { return p; }
#if 0 //def __linux__
static char *find_symname(void *addr, char *buf)
{
  Dl_info dli;
  int rv;
  if (!addr) return "";
  rv = dladdr(addr, &dli);
  if (rv) return "";
  long ofst = ((long)dli.dli_saddr) - ((long)addr);
  if (ofst > 0)
    sprintf(buf, " (%s+%ld)", dli.dli_sname, ofst);
  else if (ofst < 0)
    sprintf(buf, " (%s-%ld)", dli.dli_sname, -ofst);
  else
    sprintf(buf, " (%s)", dli.dli_sname);
  return buf;
}
#endif
