blob: 47e84e21c1350cbabd9fecd98e516684f653abcb [file] [log] [blame]
/* This file contains some useful routines for debugging problems with C
descriptors. Compiling it also acts as a test that the implementation of
ISO_Fortran_binding.h provides all the types and constants specified in
TS29113. */
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include "dump-descriptors.h"
void
dump_CFI_cdesc_t (CFI_cdesc_t *d)
{
fprintf (stderr, "<CFI_cdesc_t base_addr=%p elem_len=%ld version=%d",
d->base_addr, (long)(d->elem_len), d->version);
fprintf (stderr, "\n rank=");
dump_CFI_rank_t (d->rank);
fprintf (stderr, " type=");
dump_CFI_type_t (d->type);
fprintf (stderr, " attribute=");
dump_CFI_attribute_t (d->attribute);
/* Dimension info may not be initialized if it's an allocatable
or pointer descriptor with a null base_addr. */
if (d->rank > 0 && d->base_addr)
{
CFI_rank_t i;
for (i = 0; i < d->rank; i++)
{
if (i == 0)
fprintf (stderr, "\n dim=[");
else
fprintf (stderr, ",\n ");
dump_CFI_dim_t (d->dim + i);
}
fprintf (stderr, "]");
}
fprintf (stderr, ">\n");
}
void
dump_CFI_dim_t (CFI_dim_t *d)
{
fprintf (stderr, "<CFI_dim_t lower_bound=");
dump_CFI_index_t (d->lower_bound);
fprintf (stderr, " extent=");
dump_CFI_index_t (d->extent);
fprintf (stderr, " sm=");
dump_CFI_index_t (d->sm);
fprintf (stderr, ">");
}
void
dump_CFI_attribute_t (CFI_attribute_t a)
{
switch (a)
{
case CFI_attribute_pointer:
fprintf (stderr, "CFI_attribute_pointer");
break;
case CFI_attribute_allocatable:
fprintf (stderr, "CFI_attribute_allocatable");
break;
case CFI_attribute_other:
fprintf (stderr, "CFI_attribute_other");
break;
default:
fprintf (stderr, "unknown(%d)", (int)a);
break;
}
}
void
dump_CFI_index_t (CFI_index_t i)
{
fprintf (stderr, "%ld", (long)i);
}
void
dump_CFI_rank_t (CFI_rank_t r)
{
fprintf (stderr, "%d", (int)r);
}
/* We can't use a switch statement to dispatch CFI_type_t because
the type name macros may not be unique. Iterate over a table
instead. */
struct type_name_map {
CFI_type_t t;
const char *n;
};
struct type_name_map type_names[] =
{
{ CFI_type_signed_char, "CFI_type_signed_char" },
{ CFI_type_short, "CFI_type_short" },
{ CFI_type_int, "CFI_type_int" },
{ CFI_type_long, "CFI_type_long" },
{ CFI_type_long_long, "CFI_type_long_long" },
{ CFI_type_size_t, "CFI_type_size_t" },
{ CFI_type_int8_t, "CFI_type_int8_t" },
{ CFI_type_int16_t, "CFI_type_int16_t" },
{ CFI_type_int32_t, "CFI_type_int32_t" },
{ CFI_type_int64_t, "CFI_type_int64_t" },
{ CFI_type_int_least8_t, "CFI_type_int_least8_t" },
{ CFI_type_int_least16_t, "CFI_type_int_least16_t" },
{ CFI_type_int_least32_t, "CFI_type_int_least32_t" },
{ CFI_type_int_least64_t, "CFI_type_int_least64_t" },
{ CFI_type_int_fast8_t, "CFI_type_int_fast8_t" },
{ CFI_type_int_fast16_t, "CFI_type_int_fast16_t" },
{ CFI_type_int_fast32_t, "CFI_type_int_fast32_t" },
{ CFI_type_int_fast64_t, "CFI_type_int_fast64_t" },
{ CFI_type_intmax_t, "CFI_type_intmax_t" },
{ CFI_type_intptr_t, "CFI_type_intptr_t" },
{ CFI_type_ptrdiff_t, "CFI_type_ptrdiff_t" },
{ CFI_type_float, "CFI_type_float" },
{ CFI_type_double, "CFI_type_double" },
{ CFI_type_long_double, "CFI_type_long_double" },
{ CFI_type_float_Complex, "CFI_type_float_Complex" },
{ CFI_type_double_Complex, "CFI_type_double_Complex" },
{ CFI_type_long_double_Complex, "CFI_type_long_double_Complex" },
{ CFI_type_Bool, "CFI_type_Bool" },
{ CFI_type_char, "CFI_type_char" },
{ CFI_type_cptr, "CFI_type_cptr" },
{ CFI_type_struct, "CFI_type_struct" },
{ CFI_type_other, "CFI_type_other" },
/* Extension types */
{ CFI_type_int128_t, "CFI_type_int128_t" },
{ CFI_type_int_least128_t, "CFI_type_int_least128_t" },
{ CFI_type_int_fast128_t, "CFI_type_int_fast128_t" },
{ CFI_type_ucs4_char, "CFI_type_ucs4_char" },
{ CFI_type_float128, "CFI_type_float128" },
{ CFI_type_float128_Complex, "CFI_type_float128_Complex" },
{ CFI_type_cfunptr, "CFI_type_cfunptr" }
};
void
dump_CFI_type_t (CFI_type_t t)
{
int i;
for (i = 0; i < sizeof (type_names) / sizeof (struct type_name_map); i++)
if (type_names[i].t == t)
{
fprintf (stderr, "%s", type_names[i].n);
return;
}
fprintf (stderr, "unknown(%d)", (int)t);
}
void
check_CFI_status (const char *fn, int code)
{
const char *msg;
switch (code)
{
case CFI_SUCCESS:
return;
case CFI_ERROR_BASE_ADDR_NULL:
msg = "CFI_ERROR_BASE_ADDR_NULL";
break;
case CFI_ERROR_BASE_ADDR_NOT_NULL:
msg = "CFI_ERROR_BASE_ADDR_NOT_NULL";
break;
case CFI_INVALID_ELEM_LEN:
msg = "CFI_INVALID_ELEM_LEN";
break;
case CFI_INVALID_RANK:
msg = "CFI_INVALID_RANK";
break;
case CFI_INVALID_TYPE:
msg = "CFI_INVALID_TYPE";
break;
case CFI_INVALID_ATTRIBUTE:
msg = "CFI_INVALID_ATTRIBUTE";
break;
case CFI_INVALID_EXTENT:
msg = "CFI_INVALID_EXTENT";
break;
case CFI_INVALID_DESCRIPTOR:
msg = "CFI_INVALID_DESCRIPTOR";
break;
case CFI_ERROR_MEM_ALLOCATION:
msg = "CFI_ERROR_MEM_ALLOCATION";
break;
case CFI_ERROR_OUT_OF_BOUNDS:
msg = "CFI_ERROR_OUT_OF_BOUNDS";
break;
default:
msg = "unknown error";
break;
}
fprintf (stderr, "%s returned %s\n", fn, msg);
abort ();
}