#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#include <elf.h>
#include <dwarf.h>
#include "dat.h"

static void ds2acid(Dwarf*, DwarfSym*, Biobuf*, char*);

static ulong
valof(uint ty, DwarfVal *v)
{
	switch(ty){
	default:
fmtinstall('H', encodefmt);
fprint(2, "valof %d %.*H\n", ty, v->b.len, v->b.data);
		return 0;
	case TConstant:
		return v->c;
	}
}

static Type*
xnewtype(uint ty, DwarfSym *s)
{
	Type *t;

	t = typebynum(s->unit+s->uoff, 0);
	t->ty = ty;
	return t;
}

int
dwarf2acid(Dwarf *d, Biobuf *b)
{
	DwarfSym s;

	/* pass over dwarf section pulling out type info */

	if(dwarfenum(d, &s) < 0)
		return -1;

	while(dwarfnextsymat(d, &s, 0) == 1)
		ds2acid(d, &s, b, nil);

	printtypes(b);
	dumpsyms(b);
	freetypes();
	return 0;
}

static void
ds2acid(Dwarf *d, DwarfSym *s, Biobuf *b, char *fn)
{
	int depth;
	Type *t;

	depth = s->depth;

	switch(s->attrs.tag){
	case TagSubroutineType:
		t = xnewtype(Function, s);
		goto Recurse;

	case TagSubprogram:
		fn = s->attrs.name;
		goto Recurse;

	case TagCompileUnit:
	case TagLexDwarfBlock:
	Recurse:
		/* recurse into substructure */
		while(dwarfnextsymat(d, s, depth+1) == 1)
			ds2acid(d, s, b, fn);
		break;

	case TagTypedef:
		t = xnewtype(Typedef, s);
		t->name = s->attrs.name;
		t->sub = typebynum(s->attrs.type, 0);
		break;

	case TagBaseType:
		t = xnewtype(Base, s);
		t->xsizeof = s->attrs.bytesize;
		switch(s->attrs.encoding){
		default:
		case TypeAddress:
			t->printfmt = 'x';
			break;
		case TypeBoolean:
		case TypeUnsigned:
		case TypeSigned:
		case TypeSignedChar:
		case TypeUnsignedChar:
			t->printfmt = 'd';
			break;
		case TypeFloat:
			t->printfmt = 'f';
			break;
		case TypeComplexFloat:
			t->printfmt = 'F';
			break;
		case TypeImaginaryFloat:
			t->printfmt = 'i';
			break;
		}
		break;

	case TagPointerType:
		t = xnewtype(Pointer, s);
		t->sub = typebynum(s->attrs.type, 0);
		break;

	case TagConstType:
	case TagVolatileType:
		t = xnewtype(Defer, s);
		t->sub = typebynum(s->attrs.type, 0);
		break;

	case TagArrayType:
		t = xnewtype(Array, s);
		t->sub = typebynum(s->attrs.type, 0);
		break;

	case TagStructType:
	case TagUnionType:
		t = xnewtype(Aggr, s);
		t->sue = s->attrs.tag==TagStructType ? 's' : 'u';
		t->xsizeof = s->attrs.bytesize;
		t->suename = s->attrs.name;
		t->isunion = s->attrs.tag==TagUnionType;
		while(dwarfnextsymat(d, s, depth+1) == 1){
			if(s->attrs.tag != TagMember){
				ds2acid(d, s, b, fn);
				continue;
			}
			if(!s->attrs.have.name || !s->attrs.have.type)
				continue;
			if(t->n%32 == 0){
				t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
				t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
				t->t = erealloc(t->t, (t->n+32)*sizeof(t->t[0]));
			}
			t->tname[t->n] = s->attrs.name;
			if(t->isunion)
				t->val[t->n] = 0;
			else
				t->val[t->n] = valof(s->attrs.have.datamemberloc, &s->attrs.datamemberloc);
			t->t[t->n] = typebynum(s->attrs.type, 0);
			t->n++;
		}
		break;

	case TagEnumerationType:
		t = xnewtype(Enum, s);
		t->sue = 'e';
		t->suename = s->attrs.name;
		t->xsizeof = s->attrs.bytesize;
		while(dwarfnextsymat(d, s, depth+1) == 1){
			if(s->attrs.tag != TagEnumerator){
				ds2acid(d, s, b, fn);
				continue;
			}
			if(!s->attrs.have.name || !s->attrs.have.constvalue)
				continue;
			if(t->n%32 == 0){
				t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
				t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
			}
			t->tname[t->n] = s->attrs.name;
			t->val[t->n] = valof(s->attrs.have.constvalue, &s->attrs.constvalue);
			t->n++;
		}
		break;

	case TagFormalParameter:
	case TagVariable:
		if(s->attrs.name==nil || s->attrs.type==0)
			break;
		addsymx(fn, s->attrs.name, typebynum(s->attrs.type, 0));
		break;
	}
}

