/*
 * File types.c - datatype handling stuff for internal debugger.
 *
 * Copyright (C) 1997, Eric Youngdale.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Note: This really doesn't do much at the moment, but it forms the framework
 * upon which full support for datatype handling will eventually be built.
 */

#include "config.h"
#include <stdlib.h>

#include "debugger.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);

/******************************************************************
 *		types_extract_as_integer
 *
 * Given a lvalue, try to get an integral (or pointer/address) value
 * out of it
 */
long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
{
    long int            rtn = 0;
    LONGLONG            val;
    DWORD               tag, bt;
    DWORD64             size;

    if (lvalue->type.id == dbg_itype_none ||
        !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
        return 0;

    if (lvalue->type.id == dbg_itype_segptr)
    {
        return (long int)memory_to_linear_addr(&lvalue->addr);
    }

    switch (tag)
    {
    case SymTagBaseType:
        if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) ||
            !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
        {
            WINE_ERR("Couldn't get information\n");
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        }
        if (size > sizeof(rtn))
        {
            WINE_ERR("Size too large (%s)\n", wine_dbgstr_longlong(size));
            return 0;
        }
        switch (bt)
        {
        case btChar:
        case btInt:
            if (!be_cpu->fetch_integer(lvalue, (unsigned)size, TRUE, &val)) return 0;
            rtn = (long)val;
            break;
        case btUInt:
            if (!be_cpu->fetch_integer(lvalue, (unsigned)size, FALSE, &val)) return 0;
            rtn = (DWORD)(DWORD64)val;
            break;
        case btFloat:
            RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
        }
        break;
    case SymTagPointerType:
        if (!memory_read_value(lvalue, sizeof(void*), &rtn)) return 0;
        break;
    case SymTagArrayType:
    case SymTagUDT:
        assert(lvalue->cookie == DLV_TARGET);
        if (!memory_read_value(lvalue, sizeof(rtn), &rtn)) return 0;
        break;
    case SymTagEnum:
        assert(lvalue->cookie == DLV_TARGET);
        if (!memory_read_value(lvalue, sizeof(rtn), &rtn)) return 0;
        break;
    default:
        WINE_FIXME("Unsupported tag %lu\n", tag);
        rtn = 0;
        break;
    }

    return rtn;
}

/******************************************************************
 *		types_extract_as_address
 *
 *
 */
void types_extract_as_address(const struct dbg_lvalue* lvalue, ADDRESS* addr)
{
    if (lvalue->type.id == dbg_itype_segptr && lvalue->type.module == 0)
    {
        *addr = lvalue->addr;
    }
    else
    {
        addr->Mode = AddrModeFlat;
        addr->Offset = types_extract_as_integer( lvalue );
    }
}

/******************************************************************
 *		types_deref
 *
 */
BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
{
    DWORD       tag;

    memset(result, 0, sizeof(*result));
    result->type.id = dbg_itype_none;
    result->type.module = 0;

    /*
     * Make sure that this really makes sense.
     */
    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
        tag != SymTagPointerType ||
        !memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) ||
        !types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id))
        return FALSE;
    result->type.module = lvalue->type.module;
    result->cookie = DLV_TARGET;
    /* FIXME: this is currently buggy.
     * there is no way to tell were the deref:ed value is...
     * for example:
     *	x is a pointer to struct s, x being on the stack
     *		=> lvalue is in debuggee, result is in debugger
     *	x is a pointer to struct s, x being optimized into a reg
     *		=> lvalue is debugger, result is debuggee
     *	x is a pointer to internal variable x
     *	       	=> lvalue is debugger, result is debuggee
     * so we force debuggee address space, because dereferencing pointers to
     * internal variables is very unlikely. A correct fix would be
     * rather large.
     */
    result->addr.Mode = AddrModeFlat;
    return TRUE;
}

/******************************************************************
 *		types_get_udt_element_lvalue
 *
 * Implement a structure derefencement
 */
static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, 
                                         const struct dbg_type* type, long int* tmpbuf)
{
    DWORD       offset, bitoffset;
    DWORD       bt;
    DWORD64     length;

    unsigned    mask;

    types_get_info(type, TI_GET_TYPE, &lvalue->type.id);
    lvalue->type.module = type->module;
    if (!types_get_info(type, TI_GET_OFFSET, &offset)) return FALSE;
    lvalue->addr.Offset += offset;

    if (types_get_info(type, TI_GET_BITPOSITION, &bitoffset))
    {
        types_get_info(type, TI_GET_LENGTH, &length);
        /* FIXME: this test isn't sufficient, depending on start of bitfield
         * (ie a 32 bit field can spread across 5 bytes)
         */
        if (length > 8 * sizeof(*tmpbuf)) return FALSE;
        lvalue->addr.Offset += bitoffset >> 3;
        /*
         * Bitfield operation.  We have to extract the field and store
         * it in a temporary buffer so that we get it all right.
         */
        if (!memory_read_value(lvalue, sizeof(*tmpbuf), tmpbuf)) return FALSE;
        mask = 0xffffffff << (DWORD)length;
        *tmpbuf >>= bitoffset & 7;
        *tmpbuf &= ~mask;

        lvalue->cookie      = DLV_HOST;
        lvalue->addr.Offset = (DWORD)tmpbuf;

        /*
         * OK, now we have the correct part of the number.
         * Check to see whether the basic type is signed or not, and if so,
         * we need to sign extend the number.
         */
        if (types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt) && 
            bt == btInt && (*tmpbuf & (1 << ((DWORD)length - 1))))
        {
            *tmpbuf |= mask;
        }
    }
    else
    {
        if (!memory_read_value(lvalue, sizeof(*tmpbuf), tmpbuf)) return FALSE;

    }
    return TRUE;
}

/******************************************************************
 *		types_udt_find_element
 *
 */
BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name, long int* tmpbuf)
{
    DWORD                       tag, count;
    char                        buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
    TI_FINDCHILDREN_PARAMS*     fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
    WCHAR*                      ptr;
    char                        tmp[256];
    int                         i;
    struct dbg_type             type;

    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
        tag != SymTagUDT)
        return FALSE;

    if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
    {
        fcp->Start = 0;
        while (count)
        {
            fcp->Count = min(count, 256);
            if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
            {
                type.module = lvalue->type.module;
                for (i = 0; i < min(fcp->Count, count); i++)
                {
                    ptr = NULL;
                    type.id = fcp->ChildId[i];
                    types_get_info(&type, TI_GET_SYMNAME, &ptr);
                    if (!ptr) continue;
                    WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                    HeapFree(GetProcessHeap(), 0, ptr);
                    if (strcmp(tmp, name)) continue;

                    return types_get_udt_element_lvalue(lvalue, &type, tmpbuf);
                }
            }
            count -= min(count, 256);
            fcp->Start += 256;
        }
    }
    return FALSE;
}

/******************************************************************
 *		types_array_index
 *
 * Grab an element from an array
 */
BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, 
                       struct dbg_lvalue* result)
{
    DWORD       tag, count;
    DWORD64     length;

    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
        return FALSE;
    switch (tag)
    {
    case SymTagArrayType:
        types_get_info(&lvalue->type, TI_GET_COUNT, &count);
        if (index < 0 || index >= count) return FALSE;
        /* fall through */
    case SymTagPointerType:
        /* Contents of array share same data (addr mode, module...) */
        *result = *lvalue;
        /*
         * Get the base type, so we know how much to index by.
         */
        types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id);
        types_get_info(&result->type, TI_GET_LENGTH, &length);
        memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset);
        result->addr.Offset += index * (DWORD)length;
        break;
    default:
        assert(FALSE);
    }
    return TRUE;
}

struct type_find_t
{
    unsigned long       result; /* out: the found type */
    enum SymTagEnum     tag;    /* in: the tag to look for */
    union
    {
        unsigned long           typeid; /* when tag is SymTagUDT */
        const char*             name;   /* when tag is SymTagPointerType */
    } u;
};

static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
{
    struct type_find_t* user = (struct type_find_t*)_user;
    BOOL                ret = TRUE;
    struct dbg_type     type;
    DWORD               type_id;

    if (sym->Tag == user->tag)
    {
        switch (user->tag)
        {
        case SymTagUDT:
            if (!strcmp(user->u.name, sym->Name))
            {
                user->result = sym->TypeIndex;
                ret = FALSE;
            }
            break;
        case SymTagPointerType:
            type.module = sym->ModBase;
            type.id = sym->TypeIndex;
            if (types_get_info(&type, TI_GET_TYPE, &type_id) && type_id == user->u.typeid)
            {
                user->result = sym->TypeIndex;
                ret = FALSE;
            }
            break;
        default: break;
        }
    }
    return ret;
}

/******************************************************************
 *		types_find_pointer
 *
 * Should look up in module based at linear whether (typeid*) exists
 * Otherwise, we could create it locally
 */
struct dbg_type types_find_pointer(const struct dbg_type* type)
{
    struct type_find_t  f;
    struct dbg_type     ret;

    f.result = dbg_itype_none;
    f.tag = SymTagPointerType;
    f.u.typeid = type->id;
    SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f);
    ret.module = type->module;
    ret.id = f.result;
    return ret;
}

/******************************************************************
 *		types_find_type
 *
 * Should look up in the module based at linear address whether a type
 * named 'name' and with the correct tag exists
 */
struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag)

{
    struct type_find_t  f;
    struct dbg_type     ret;

    f.result = dbg_itype_none;
    f.tag = tag;
    f.u.name = name;
    SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
    ret.module = linear;
    ret.id = f.result;
    return ret;
}

/***********************************************************************
 *           print_value
 *
 * Implementation of the 'print' command.
 */
void print_value(const struct dbg_lvalue* lvalue, char format, int level)
{
    struct dbg_lvalue   lvalue_field;
    int		        i;
    DWORD               tag;
    DWORD               count;
    DWORD64             size;

    if (lvalue->type.id == dbg_itype_none)
    {
        /* No type, just print the addr value */
        print_bare_address(&lvalue->addr);
        goto leave;
    }

    if (format == 'i' || format == 's' || format == 'w' || format == 'b' || format == 'g')
    {
        dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format);
        format = '\0';
    }

    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
    {
        WINE_FIXME("---error\n");
        return;
    }
    switch (tag)
    {
    case SymTagBaseType:
    case SymTagEnum:
    case SymTagPointerType:
        print_basic(lvalue, 1, format);
        break;
    case SymTagUDT:
        if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
        {
            char                        buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
            TI_FINDCHILDREN_PARAMS*     fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
            WCHAR*                      ptr;
            char                        tmp[256];
            long int                    tmpbuf;
            struct dbg_type             type;

            dbg_printf("{");
            fcp->Start = 0;
            while (count)
            {
                fcp->Count = min(count, 256);
                if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
                {
                    for (i = 0; i < min(fcp->Count, count); i++)
                    {
                        ptr = NULL;
                        type.module = lvalue->type.module;
                        type.id = fcp->ChildId[i];
                        types_get_info(&type, TI_GET_SYMNAME, &ptr);
                        if (!ptr) continue;
                        WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                        dbg_printf("%s=", tmp);
                        HeapFree(GetProcessHeap(), 0, ptr);
                        lvalue_field = *lvalue;
                        if (types_get_udt_element_lvalue(&lvalue_field, &type, &tmpbuf))
                        {
                            print_value(&lvalue_field, format, level + 1);
                        }
                        if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
                    }
                }
                count -= min(count, 256);
                fcp->Start += 256;
            }
            dbg_printf("}");
        }
        break;
    case SymTagArrayType:
        /*
         * Loop over all of the entries, printing stuff as we go.
         */
        count = 1; size = 1;
        types_get_info(&lvalue->type, TI_GET_COUNT, &count);
        types_get_info(&lvalue->type, TI_GET_LENGTH, &size);

        if (size == count)
	{
            unsigned    len;
            char        buffer[256];
            /*
             * Special handling for character arrays.
             */
            /* FIXME should check basic type here (should be a char!!!!)... */
            len = min(count, sizeof(buffer));
            memory_get_string(dbg_curr_process,
                              memory_to_linear_addr(&lvalue->addr),
                              lvalue->cookie == DLV_TARGET, TRUE, buffer, len);
            dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
            break;
        }
        lvalue_field = *lvalue;
        types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id);
        dbg_printf("{");
        for (i = 0; i < count; i++)
	{
            print_value(&lvalue_field, format, level + 1);
            lvalue_field.addr.Offset += size / count;
            dbg_printf((i == count - 1) ? "}" : ", ");
	}
        break;
    case SymTagFunctionType:
        dbg_printf("Function ");
        print_bare_address(&lvalue->addr);
        dbg_printf(": ");
        types_print_type(&lvalue->type, FALSE);
        break;
    default:
        WINE_FIXME("Unknown tag (%lu)\n", tag);
        RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
    }

leave:

    if (level == 0) dbg_printf("\n");
}

static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx)
{
    struct dbg_type     type;
    type.module = sym->ModBase;
    type.id = sym->TypeIndex;
    dbg_printf("Mod: %08lx ID: %08lx \n", type.module, type.id);
    types_print_type(&type, TRUE);
    dbg_printf("\n");
    return TRUE;
}

static BOOL CALLBACK print_types_mod_cb(PSTR mod_name, DWORD base, void* ctx)
{
    return SymEnumTypes(dbg_curr_process->handle, base, print_types_cb, ctx);
}

int print_types(void)
{
    SymEnumerateModules(dbg_curr_process->handle, print_types_mod_cb, NULL);
    return 0;
}

int types_print_type(const struct dbg_type* type, BOOL details)
{
    WCHAR*              ptr;
    char                tmp[256];
    const char*         name;
    DWORD               tag, udt, count;
    struct dbg_type     subtype;

    if (type->id == dbg_itype_none || !types_get_info(type, TI_GET_SYMTAG, &tag))
    {
        dbg_printf("--invalid--<%lxh>--", type->id);
        return FALSE;
    }

    if (types_get_info(type, TI_GET_SYMNAME, &ptr) && ptr)
    {
        WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
        name = tmp;
        HeapFree(GetProcessHeap(), 0, ptr);
    }
    else name = "--none--";

    switch (tag)
    {
    case SymTagBaseType:
        if (details) dbg_printf("Basic<%s>", name); else dbg_printf("%s", name);
        break;
    case SymTagPointerType:
        types_get_info(type, TI_GET_TYPE, &subtype.id);
        subtype.module = type->module;
        types_print_type(&subtype, FALSE);
        dbg_printf("*");
        break;
    case SymTagUDT:
        types_get_info(type, TI_GET_UDTKIND, &udt);
        switch (udt)
        {
        case UdtStruct: dbg_printf("struct %s", name); break;
        case UdtUnion:  dbg_printf("union %s", name); break;
        case UdtClass:  dbg_printf("class %s", name); break;
        default:        WINE_ERR("Unsupported UDT type (%ld) for %s", udt, name); break;
        }
        if (details &&
            types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
        {
            char                        buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
            TI_FINDCHILDREN_PARAMS*     fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
            WCHAR*                      ptr;
            char                        tmp[256];
            int                         i;
            struct dbg_type             type_elt;
            dbg_printf(" {");

            fcp->Start = 0;
            while (count)
            {
                fcp->Count = min(count, 256);
                if (types_get_info(type, TI_FINDCHILDREN, fcp))
                {
                    for (i = 0; i < min(fcp->Count, count); i++)
                    {
                        ptr = NULL;
                        type_elt.module = type->module;
                        type_elt.id = fcp->ChildId[i];
                        types_get_info(&type_elt, TI_GET_SYMNAME, &ptr);
                        if (!ptr) continue;
                        WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                        HeapFree(GetProcessHeap(), 0, ptr);
                        dbg_printf("%s", tmp);
                        if (types_get_info(&type_elt, TI_GET_TYPE, &type_elt.id))
                        {
                            dbg_printf(":");
                            types_print_type(&type_elt, details);
                        }
                        if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
                    }
                }
                count -= min(count, 256);
                fcp->Start += 256;
            }
            dbg_printf("}");
        }
        break;
    case SymTagArrayType:
        types_get_info(type, TI_GET_TYPE, &subtype.id);
        subtype.module = type->module;
        types_print_type(&subtype, details);
        dbg_printf(" %s[]", name);
        break;
    case SymTagEnum:
        dbg_printf("enum %s", name);
        break;
    case SymTagFunctionType:
        types_get_info(type, TI_GET_TYPE, &subtype.id);
        subtype.module = type->module;
        types_print_type(&subtype, FALSE);
        dbg_printf(" (*%s)(", name);
        if (types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
        {
            char                        buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
            TI_FINDCHILDREN_PARAMS*     fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
            int                         i;

            fcp->Start = 0;
            while (count)
            {
                fcp->Count = min(count, 256);
                if (types_get_info(type, TI_FINDCHILDREN, fcp))
                {
                    for (i = 0; i < min(fcp->Count, count); i++)
                    {
                        subtype.id = fcp->ChildId[i];
                        types_get_info(&subtype, TI_GET_TYPE, &subtype.id);
                        types_print_type(&subtype, FALSE);
                        if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
                    }
                }
                count -= min(count, 256);
                fcp->Start += 256;
            }
        }
        dbg_printf(")");
        break;
    default:
        WINE_ERR("Unknown type %lu for %s\n", tag, name);
        break;
    }
    
    return TRUE;
}

/* helper to typecast pInfo to its expected type (_t) */
#define X(_t) (*((_t*)pInfo))

BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
{
    if (type->id == dbg_itype_none) return FALSE;
    if (type->module != 0)
    {
        DWORD ret, tag, bt;
        ret = SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
        if (!ret &&
            SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_SYMTAG, &tag) &&
            tag == SymTagBaseType &&
            SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_BASETYPE, &bt))
        {
            static const WCHAR voidW[] = {'v','o','i','d','\0'};
            static const WCHAR charW[] = {'c','h','a','r','\0'};
            static const WCHAR wcharW[] = {'W','C','H','A','R','\0'};
            static const WCHAR intW[] = {'i','n','t','\0'};
            static const WCHAR uintW[] = {'u','n','s','i','g','n','e','d',' ','i','n','t','\0'};
            static const WCHAR floatW[] = {'f','l','o','a','t','\0'};
            static const WCHAR boolW[] = {'b','o','o','l','\0'};
            static const WCHAR longW[] = {'l','o','n','g',' ','i','n','t','\0'};
            static const WCHAR ulongW[] = {'u','n','s','i','g','n','e','d',' ','l','o','n','g',' ','i','n','t','\0'};
            static const WCHAR complexW[] = {'c','o','m','p','l','e','x','\0'};
            const WCHAR* name = NULL;

            switch (bt)
            {
            case btVoid:        name = voidW; break;
            case btChar:        name = charW; break;
            case btWChar:       name = wcharW; break;
            case btInt:         name = intW; break;
            case btUInt:        name = uintW; break;
            case btFloat:       name = floatW; break;
            case btBool:        name = boolW; break;
            case btLong:        name = longW; break;
            case btULong:       name = ulongW; break;
            case btComplex:     name = complexW; break;
            default:            WINE_FIXME("Unsupported basic type %ld\n", bt); return FALSE;
            }
            X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name) + 1) * sizeof(WCHAR));
            if (X(WCHAR*))
            {
                lstrcpyW(X(WCHAR*), name);
                ret = TRUE;
            }
        }
        return ret;
    }

    assert(type->id >= dbg_itype_first);

    switch (type->id)
    {
    case dbg_itype_unsigned_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD)   = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD64) = 4; break;
        case TI_GET_BASETYPE:   X(DWORD)   = btUInt; break;
        default: WINE_FIXME("unsupported %u for u-int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_signed_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD)   = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD64) = 4; break;
        case TI_GET_BASETYPE:   X(DWORD)   = btInt; break;
        default: WINE_FIXME("unsupported %u for s-int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_unsigned_short_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD)   = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD64) = 2; break;
        case TI_GET_BASETYPE:   X(DWORD)   = btUInt; break;
        default: WINE_FIXME("unsupported %u for u-short int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_signed_short_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD)   = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD64) = 2; break;
        case TI_GET_BASETYPE:   X(DWORD)   = btInt; break;
        default: WINE_FIXME("unsupported %u for s-short int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_unsigned_char_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD)   = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD64) = 1; break;
        case TI_GET_BASETYPE:   X(DWORD)   = btUInt; break;
        default: WINE_FIXME("unsupported %u for u-char int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_signed_char_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD)   = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD64) = 1; break;
        case TI_GET_BASETYPE:   X(DWORD)   = btInt; break;
        default: WINE_FIXME("unsupported %u for s-char int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_char:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD)   = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD64) = 1; break;
        case TI_GET_BASETYPE:   X(DWORD)   = btChar; break;
        default: WINE_FIXME("unsupported %u for char int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_astring:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD)   = SymTagPointerType; break;
        case TI_GET_LENGTH:     X(DWORD64) = 4; break;
        case TI_GET_TYPE:       X(DWORD)   = dbg_itype_char; break;
        default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
        }
        break;
    case dbg_itype_segptr:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD)   = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD64) = 4; break;
        case TI_GET_BASETYPE:   X(DWORD)   = btInt; break;
        default: WINE_FIXME("unsupported %u for seg-ptr\n", ti); return FALSE;
        }
        break;
    default: WINE_FIXME("unsupported type id 0x%lx\n", type->id);
    }

#undef X
    return TRUE;
}
