Skeleton of the new types system is in place and compiles

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@158 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dustin Mitchell 2000-01-28 07:21:38 +00:00
commit 2f8d8b22d5
2 changed files with 509 additions and 27 deletions

View file

@ -145,7 +145,6 @@ static DohObjInfo SuperType =
Super_str, /* doh_str */
Super_data, /* doh_data */
Super_dump, /* doh_dump */
0, /* doh_load */
Super_len, /* doh_len */
Super_hash, /* doh_hash */
Super_cmp, /* doh_cmp */

View file

@ -6,6 +6,9 @@
* complex, as it uses a tree structure internally to cache
* already-represented types and avoid the need to allocate an
* entire DOH object every time a type object is created.
*
* While this library is designed to handle C types, it should be
* sufficiently general to handle most system-level langages.
*
* Author(s) : Dustin Mitchell (djmitche@cs.uchicago.edu)
*
@ -71,26 +74,35 @@ static char cvstag[] = "$Header$";
/* Base types
Base types have no parent (with one exception; see *), and can be
const or volatile. Width specifies the length in bits of an
integral type, and the length in bits of the mantissa of a Float.
Exp_width specifies the width of the exponent in a float type.
Name specifies the name of a Name type, as well as the optional tag
for an Enum or Struct. Attributes specifies the indirect
attributes of a type. For Enums, this is the optional list of
defined names and their values. For Structs, this is an optional
list of the types and names of the members.
const or volatile (that is, 'is_const' and 'is_volatile' are
relevant). 'width' specifies the length in bits of an integral or
character (e.g. wchar) type, and the length in bits of the mantissa
of a Float. 'exp_width' specifies the width of the exponent in a
float type. Only ints can be signed or unsigned (i.e. their
'is_signed' and 'is_unsigned' are relevant) (N.B.: the axiom of the
excluded middle does not apply here: an integer, an unsigned
integer, and a signed integer are distinct types). 'name' specifies
the name of a Name type, as well as the optional tag for an Enum or
Struct. 'attributes' specifies the indirect attributes of a type.
For Enums, this is the optional list of defined names and their
values. For Structs, this is an optional list of the types and
names of the members. Structs also have a 'subtype' to
differentiate structs from unions.
Note: it is up to the parser to distinguish character types
(i.e. those containing ASCII data) from 8-bit integer types, most
likely using some simple heuristics.
(*) If a Name's underlying type is known, then its child field
points to that type. */
#define Swig_Type_Int 1
#define Swig_Type_UInt 2
#define Swig_Type_Float 3
#define Swig_Type_Void 4
#define Swig_Type_Char 5
#define Swig_Type_Name 6
#define Swig_Type_Enum 7
#define Swig_Type_Struct 8
#define Swig_Type_Float 2
#define Swig_Type_Void 3
#define Swig_Type_Char 4
#define Swig_Type_Name 5
#define Swig_Type_Enum 6
#define Swig_Type_Struct 7
/* Constructors
@ -109,26 +121,50 @@ static char cvstag[] = "$Header$";
A Struct may either be a Struct or a Union -- since SWIG handles
them similarly, this is considered a subtype. */
#define Swig_Subtype_Struct 81
#define Swig_Subtype_Union 82
#define Swig_Subtype_Struct 1
#define Swig_Subtype_Union 2
/* (for results of comparisons) */
#define TAGS_EQ 0
#define TAGS_NEQ 1
/* =========================================================================
* structure definitions
* ========================================================================= */
/* These are both DOH types so that we can hash them. The first
(Swig_Type_tag) is a completely internal DOH type, while the second
is the publicly exported DOH type. */
typedef struct Swig_Type_tag
{
short type, subtype;
DOH *name, *attributes;
DOHCOMMON;
short type;
short subtype;
DOH *name;
DOH **attributes;
short width;
short exp_width;
int is_const : 1;
int is_volatile : 1;
int is_signed : 1;
int is_unsigned : 1;
int hashkey;
} Swig_Type_tag;
typedef DOH *Swig_Type_children;
typedef DOH *Swig_Type_children; /* a DOH Hash */
typedef struct Swig_Type_node
{
Swig_Type_tag type;
DOHCOMMON;
Swig_Type_tag *tag;
struct Swig_Type_node *parent;
Swig_Type_hash children;
Swig_Type_children children;
int hashkey;
} Swig_Type_node;
/* =========================================================================
@ -140,15 +176,93 @@ typedef struct Swig_Type_node
static Swig_Type_children Swig_Type_root;
/* =========================================================================
* utility function prototypes
* utility function declarations
* ========================================================================= */
/* Take one step down into the children, creating a new node if
necessary. */
static Swig_Type_node *
Swig_Type_step(Swig_Type_hash children, Swig_Type_tag *tag);
Swig_Type_step(Swig_Type_node *parent, Swig_Type_children children,
Swig_Type_tag *tag);
/* Functions to support hashing on Swig_Type_tag objects */
/* Make sure that this is a real DOH string, not a (char *). */
static DOH *
Swig_Type_make_string(DOH *in);
/* the smallest n such that i < 2**n */
static int Swig_Type_bit_count(unsigned int i);
/* =========================================================================
* Swig_Type_tag DOH type declaration
* ========================================================================= */
static DOH *
Swig_Type_tag_new(short type, short subtype,
DOH *name, DOH *attributes,
int width, int exp_width,
int is_const, int is_volatile,
int is_signed, int is_unsigned);
static DOH *Swig_Type_tag_str(DOH *o); /* e.g. 'pointer to' */
static int Swig_Type_tag_hash(DOH *o);
static int Swig_Type_tag_cmp(DOH *o1, DOH *o2);
#define TagData(x) ((Swig_Type_tag *)(x))
static DohObjInfo Swig_Type_tag_Type =
{
"TypeTag", /* objname */
sizeof(Swig_Type_tag), /* objsize */
0, /* doh_del -- will never happen */
0, /* doh_copy */
0, /* doh_clear */
0, /* doh_scope */
Swig_Type_tag_str, /* doh_str */
0, /* doh_data */
0, /* doh_dump */
0, /* doh_len */
Swig_Type_tag_hash, /* doh_hash */
Swig_Type_tag_cmp, /* doh_cmp */
0, /* doh_mapping */
0, /* doh_sequence */
0, /* doh_file */
0, /* doh_string */
0, /* doh_callable */
0, /* doh_position */
};
/* =========================================================================
* Swig_Type_node DOH type declaration
* ========================================================================= */
static DOH *Swig_Type_node_new(DOH *tag, DOH *parent);
static DOH *Swig_Type_node_str(DOH *o); /* e.g. 'pointer to array (10)
of pointer to char'' */
static int Swig_Type_node_hash(DOH *o);
static int Swig_Type_node_cmp(DOH *o, DOH *o2);
#define NodeData(x) ((Swig_Type_node *)(x))
static DohObjInfo Swig_Type_node_Type =
{
"Type", /* objname */
sizeof(Swig_Type_node), /* objsize */
0, /* doh_del -- will never happen */
0, /* doh_copy */
0, /* doh_clear */
0, /* doh_scope */
Swig_Type_node_str, /* doh_str */
0, /* doh_data */
0, /* doh_dump */
0, /* doh_len */
Swig_Type_node_hash, /* doh_hash */
Swig_Type_node_cmp, /* doh_cmp */
0, /* doh_mapping */
0, /* doh_sequence */
0, /* doh_file */
0, /* doh_string */
0, /* doh_callable */
0, /* doh_position */
};
/* =========================================================================
* utility functions
@ -156,8 +270,377 @@ Swig_Type_step(Swig_Type_hash children, Swig_Type_tag *tag);
/* -------------------------------------------------------------------------
* static Swig_Type_node *
* Swig_Type_step(Swig_Type_hash children, Swig_Type_tag *tag);
* Swig_Type_step(Swig_Type_children children, Swig_Type_tag *tag);
* -------------------------------------------------------------------------
* Take a step down the tree, creating a new node if necessary, and
* return a pointer to the node we arrive at.
* ------------------------------------------------------------------------- */
static Swig_Type_node *
Swig_Type_step(Swig_Type_node *parent, Swig_Type_children children,
Swig_Type_tag *tag)
{
DOH *subnode = Getattr(children, tag);
if (!subnode) {
subnode = Swig_Type_node_new(tag, parent);
Setattr(children, tag, subnode);
}
return NodeData(subnode);
}
/* -------------------------------------------------------------------------
* static DOH *
* Swig_Type_make_string(DOH *in);
* -------------------------------------------------------------------------
* Make sure that this is a real DOH string, not a (char *).
* ------------------------------------------------------------------------- */
static DOH *
Swig_Type_make_string(DOH *in)
{
if (String_check(in) || SuperString_check(in))
return in;
/* assume (char *) */
if (in)
return NewString(in);
else
return NULL;
}
/* -------------------------------------------------------------------------
* static int Swig_Type_bit_count(unsigned int i);
* -------------------------------------------------------------------------
/* The smallest n such that i < 2**n
* ------------------------------------------------------------------------- */
static int Swig_Type_bit_count(unsigned int i)
{
int n = 0;
while (i)
n++, i >>= 1;
return n;
}
/* =========================================================================
* Swig_Type_tag DOH type implementation
* ========================================================================= */
/* -------------------------------------------------------------------------
* static DOH *
* Swig_Type_tag_new( ... );
* ------------------------------------------------------------------------- */
static DOH *
Swig_Type_tag_new(short type, short subtype,
DOH *name, DOH *attributes,
int width, int exp_width,
int is_const, int is_volatile,
int is_signed, int is_unsigned)
{
Swig_Type_tag *t;
t = (Swig_Type_tag *)DohObjMalloc(sizeof(Swig_Type_tag));
t->objinfo = &Swig_Type_tag_Type;
t->hashkey = -1;
t->type = type;
t->subtype = subtype;
t->name = Swig_Type_make_string(name); if (t->name) Incref(t->name);
t->attributes = attributes; if (t->attributes) Incref(t->attributes);
t->width = width;
t->exp_width = exp_width;
t->is_const = is_const;
t->is_volatile = is_volatile;
t->is_signed = is_signed;
t->is_unsigned = is_unsigned;
return t;
}
/* -------------------------------------------------------------------------
* static DOH *
* Swig_Type_tag_str(DOH *o);
* ------------------------------------------------------------------------- */
static DOH *Swig_Type_tag_str(DOH *o)
{
return o, "tag_str";
}
/* -------------------------------------------------------------------------
* static int
* Swig_Type_tag_hash(DOH *o);
* ------------------------------------------------------------------------- */
static int Swig_Type_tag_hash(DOH *o)
{
Swig_Type_tag *tag = TagData(o);
if (tag->hashkey != -1) return tag->hashkey;
/* barring the use of any sub-object's Hashval, we assign a
different integer to each of our types. */
switch (tag->type)
{
/* base types are assigned certain numbers */
case Swig_Type_Int:
tag->hashkey =
Swig_Type_bit_count(tag->width) +
(tag->is_const << 4) +
(tag->is_volatile << 5) +
(tag->is_signed << 6) +
(tag->is_unsigned << 7); /* I wonder what the optimizer will
do with this.. */
break;
case Swig_Type_Float:
tag->hashkey =
Swig_Type_bit_count(tag->width) +
(Swig_Type_bit_count(tag->exp_width) << 4) +
(tag->is_const << 8) +
(tag->is_volatile << 9) +
1 << 10;
break;
case Swig_Type_Void:
tag->hashkey =
Swig_Type_bit_count(tag->width) +
(tag->is_const << 4) +
(tag->is_volatile << 5) +
(tag->is_signed << 6) +
(tag->is_unsigned << 7) +
2 << 10;
break;
case Swig_Type_Char:
tag->hashkey =
Swig_Type_bit_count(tag->width) +
(tag->is_const << 4) +
(tag->is_volatile << 5) +
(tag->is_signed << 6) +
(tag->is_unsigned << 7) +
3 << 10;
break;
case Swig_Type_Name:
tag->hashkey =
Hashval(tag->name);
break;
case Swig_Type_Enum:
tag->hashkey =
(tag->name) ? Hashval(tag->name) : 0 +
(tag->attributes) ? Hashval(tag->attributes) : 0 +
5 << 10;
break;
case Swig_Type_Struct:
tag->hashkey =
(tag->name) ? Hashval(tag->name) : 0 +
(tag->attributes) ? Hashval(tag->attributes) : 0 +
6 << 10 +
tag->subtype << 20;
break;
case Swig_Type_Array:
tag->hashkey =
(tag->attributes) ? Hashval(tag->attributes) : 0 +
7 << 10;
break;
case Swig_Type_Function:
tag->hashkey =
(tag->attributes) ? Hashval(tag->attributes) : 0 +
8 << 10;
break;
case Swig_Type_Pointer:
tag->hashkey =
(tag->is_const << 8) +
(tag->is_volatile << 9) +
9 << 10;
break;
default:
tag->hashkey =
tag->type;
break;
}
if (tag->hashkey == -1) tag->hashkey = 1;
return tag->hashkey;
}
/* -------------------------------------------------------------------------
* static int
* Swig_Type_tag_cmp(DOH *o1, DOH *o2);
* ------------------------------------------------------------------------- */
static int Swig_Type_tag_cmp(DOH *o1, DOH *o2)
{
Swig_Type_tag *t1, *t2;
t1 = TagData(o1);
t2 = TagData(o2);
/* we define only equal or not equal, as that's all we need to hash
types. */
if (t1 == t2)
return TAGS_EQ;
if (t1->type != t2->type)
return TAGS_NEQ;
switch (t1->type)
{
case Swig_Type_Int:
if (t1->width != t2->width ||
t1->is_const != t2->is_const ||
t1->is_volatile != t2->is_volatile ||
t1->is_unsigned != t2->is_unsigned ||
t1->is_signed != t2->is_signed)
return TAGS_NEQ;
break;
case Swig_Type_Float:
if (t1->width != t2->width ||
t1->exp_width != t2->exp_width ||
t1->is_const != t2->is_const ||
t1->is_volatile != t2->is_volatile)
return TAGS_NEQ;
break;
case Swig_Type_Void:
break; /* nothing to it.. */
case Swig_Type_Char:
if (t1->width != t2->width ||
t1->is_const != t2->is_const ||
t1->is_volatile != t2->is_volatile)
return TAGS_NEQ;
break;
case Swig_Type_Name:
return Cmp(t1->name, t2->name);
case Swig_Type_Struct:
if (t1->subtype != t2->subtype)
return TAGS_NEQ;
/* fall through */
case Swig_Type_Enum:
/* do the names differ? */
if (t1->name && t2->name)
{
if (Cmp(t1->name, t2->name))
return TAGS_NEQ;
else if (t1->attributes && t2->attributes)
return Cmp(t1->attributes, t2->attributes);
else if (t1->attributes || t2->attributes)
/* both named, only one has attributes... */
return TAGS_NEQ;
else
/* both named, neither has attributes */
return TAGS_EQ;
}
else if (t1->name || t2->name)
/* one named, one not */
return TAGS_NEQ;
else
{
/* neither named -- structural equivalence */
if (t1->attributes && t2->attributes)
return Cmp(t1->attributes, t2->attributes);
else
/* this should never happen .. */
return TAGS_NEQ;
}
case Swig_Type_Array:
if (t1->attributes && t2->attributes)
return Cmp(t1->attributes, t2->attributes);
else if (t1->attributes || t2->attributes)
return TAGS_NEQ;
else
return TAGS_EQ;
case Swig_Type_Function:
return Cmp(t1->attributes, t2->attributes);
case Swig_Type_Pointer:
if (t1->is_volatile != t2->is_volatile ||
t1->is_const != t2->is_const)
return TAGS_NEQ;
break;
default:
return TAGS_NEQ;
}
/* fall through -> equal */
return TAGS_EQ;
}
/* -------------------------------------------------------------------------
* static DOH *
* Swig_Type_node_new(DOH *tag, DOH *parent);
* ------------------------------------------------------------------------- */
static DOH *
Swig_Type_node_new(DOH *tag, DOH *parent)
{
Swig_Type_node *n;
n = (Swig_Type_node *)DohObjMalloc(sizeof(Swig_Type_node));
n->objinfo = &Swig_Type_node_Type;
n->parent = parent;
n->tag = tag;
n->children = NewHash();
n->hashkey = -1;
return n;
}
/* -------------------------------------------------------------------------
* static DOH *
* Swig_Type_node_str(DOH *o);
* ------------------------------------------------------------------------- */
static DOH *
Swig_Type_node_str(DOH *o)
{
Swig_Type_node *n = (Swig_Type_node *)o;
DOH *s = NewString("");
if (n->parent)
Printf(s, "%s %s", n->tag, n->parent);
else
return Str(n->tag);
}
/* -------------------------------------------------------------------------
* static int
* Swig_Type_node_hash(DOH *o);
* ------------------------------------------------------------------------- */
static int
Swig_Type_node_hash(DOH *o)
{
Swig_Type_node *n = (Swig_Type_node *)o;
if (n->hashkey != -1) return n->hashkey;
n->hashkey = Hashval(n->tag);
if (n->parent)
n->hashkey += Hashval(n->parent);
if (n->hashkey == -1) n->hashkey = 1;
return n->hashkey;
}
/* -------------------------------------------------------------------------
* static int
* Swig_Type_node_cmp(DOH *o1, DOH *o2);
* ------------------------------------------------------------------------- */
static int
Swig_Type_node_cmp(DOH *o1, DOH *o2)
{
Swig_Type_node *n1 = (Swig_Type_node *)o1;
Swig_Type_node *n2 = (Swig_Type_node *)o1;
/* we call the comparison functions directly just to shave a hair
off the execution time */
if (Swig_Type_tag_cmp(n1->tag, n2->tag))
return TAGS_NEQ;
else if (n1->parent && n2->parent)
return Swig_Type_node_cmp(n1->parent, n2->parent);
else if (n1->parent || n2->parent)
return TAGS_NEQ;
else
return TAGS_EQ;
}