/*
 * Copyright 2024, 2025 Hans Leidekker for CodeWeavers
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include <stdarg.h>
#include <stdio.h>

#include "widl.h"
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "winnt.h"
#include "utils.h"
#include "typetree.h"

static const IMAGE_DOS_HEADER dos_header =
{
    .e_magic = IMAGE_DOS_SIGNATURE,
    .e_lfanew = sizeof(dos_header),
};

#define FILE_ALIGNMENT 0x200
#define SECTION_ALIGNMENT 0x1000
static IMAGE_NT_HEADERS32 nt_header =
{
    .Signature = IMAGE_NT_SIGNATURE,
    .FileHeader =
    {
        .Machine = IMAGE_FILE_MACHINE_I386,
        .NumberOfSections = 1,
        .SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32),
        .Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_DLL
    },
    .OptionalHeader =
    {
        .Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC,
        .MajorLinkerVersion = 11,
        .ImageBase = 0x400000,
        .SectionAlignment = SECTION_ALIGNMENT,
        .FileAlignment = FILE_ALIGNMENT,
        .MajorOperatingSystemVersion = 6,
        .MinorOperatingSystemVersion = 2,
        .MajorSubsystemVersion = 6,
        .MinorSubsystemVersion = 2,
        .SizeOfHeaders = FILE_ALIGNMENT,
        .Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI,
        .DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NO_SEH | IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |
                              IMAGE_DLLCHARACTERISTICS_NX_COMPAT,
        .SizeOfStackReserve = 0x100000,
        .SizeOfHeapReserve = 0x1000,
        .LoaderFlags = 0x100000,
        .NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES,
        .DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] =
            { .VirtualAddress = SECTION_ALIGNMENT, .Size = sizeof(IMAGE_COR20_HEADER) }
    }
};

static IMAGE_SECTION_HEADER section_header =
{
    .Name = ".text",
    .Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ
};

static IMAGE_COR20_HEADER cor_header =
{
    .cb = sizeof(IMAGE_COR20_HEADER),
    .MajorRuntimeVersion = 2,
    .MinorRuntimeVersion = 5,
    .Flags = COMIMAGE_FLAGS_ILONLY
};

#define METADATA_MAGIC ('B' | ('S' << 8) | ('J' << 16) | ('B' << 24))
static struct
{
    UINT   signature;
    USHORT major_version;
    USHORT minor_version;
    UINT   reserved;
    UINT   length;
    char   version[20];
    USHORT flags;
    USHORT num_streams;
}
metadata_header =
{
    METADATA_MAGIC,
    1,
    1,
    0,
    20,
    "WindowsRuntime 1.4"
};

enum
{
    WINMD_STREAM_TABLE,
    WINMD_STREAM_STRING,
    WINMD_STREAM_USERSTRING,
    WINMD_STREAM_GUID,
    WINMD_STREAM_BLOB,
    WINMD_STREAM_MAX
};

static struct
{
    UINT data_offset;
    UINT data_size;
    char name[12];
    UINT header_size;
    const BYTE *data;
}
streams[] =
{
    { 0, 0, "#~", 12 },
    { 0, 0, "#Strings", 20 },
    { 0, 0, "#US", 12 },
    { 0, 0, "#GUID", 16 },
    { 0, 0, "#Blob", 16 }
};

static void write_headers( UINT image_size )
{
    static const BYTE pad[8];
    UINT i, streams_size = 0;
    USHORT num_streams = 0;

    put_data( &dos_header, sizeof(dos_header) );

    image_size += nt_header.OptionalHeader.SizeOfHeaders + sizeof(section_header);
    nt_header.OptionalHeader.SizeOfImage = (image_size + 0x1fff) & ~0x1fff;

    put_data( &nt_header, sizeof(nt_header) );

    for (i = 0; i < WINMD_STREAM_MAX; i++)
    {
        if (!streams[i].data_size) continue;
        streams_size += streams[i].header_size + streams[i].data_size;
        num_streams++;
    }

    section_header.PointerToRawData = FILE_ALIGNMENT;
    section_header.VirtualAddress = SECTION_ALIGNMENT;
    section_header.Misc.VirtualSize = sizeof(cor_header) + sizeof(metadata_header) + streams_size + 8;
    section_header.SizeOfRawData = (section_header.Misc.VirtualSize + FILE_ALIGNMENT - 1) & ~(FILE_ALIGNMENT - 1);

    put_data( &section_header, sizeof(section_header) );

    for (i = 0; i < FILE_ALIGNMENT - sizeof(dos_header) - sizeof(nt_header) - sizeof(section_header); i++)
        put_data( pad, 1 );

    cor_header.MetaData.VirtualAddress = section_header.VirtualAddress + sizeof(cor_header) + 8;
    cor_header.MetaData.Size = sizeof(metadata_header) + streams_size;

    put_data( &cor_header, sizeof(cor_header) );
    put_data( pad, 8 );

    metadata_header.num_streams = num_streams;
    put_data( &metadata_header, sizeof(metadata_header) );
    for (i = 0; i < WINMD_STREAM_MAX; i++)
    {
        if (!streams[i].data_size) continue;
        put_data( &streams[i], streams[i].header_size );
    }
}

enum table
{
    TABLE_MODULE                 = 0x00,
    TABLE_TYPEREF                = 0x01,
    TABLE_TYPEDEF                = 0x02,
    TABLE_FIELD                  = 0x04,
    TABLE_METHODDEF              = 0x06,
    TABLE_PARAM                  = 0x08,
    TABLE_INTERFACEIMPL          = 0x09,
    TABLE_MEMBERREF              = 0x0a,
    TABLE_CONSTANT               = 0x0b,
    TABLE_CUSTOMATTRIBUTE        = 0x0c,
    TABLE_FIELDMARSHAL           = 0x0d,
    TABLE_DECLSECURITY           = 0x0e,
    TABLE_CLASSLAYOUT            = 0x0f,
    TABLE_FIELDLAYOUT            = 0x10,
    TABLE_STANDALONESIG          = 0x11,
    TABLE_EVENTMAP               = 0x12,
    TABLE_EVENT                  = 0x14,
    TABLE_PROPERTYMAP            = 0x15,
    TABLE_PROPERTY               = 0x17,
    TABLE_METHODSEMANTICS        = 0x18,
    TABLE_METHODIMPL             = 0x19,
    TABLE_MODULEREF              = 0x1a,
    TABLE_TYPESPEC               = 0x1b,
    TABLE_IMPLMAP                = 0x1c,
    TABLE_FIELDRVA               = 0x1d,
    TABLE_ASSEMBLY               = 0x20,
    TABLE_ASSEMBLYPROCESSOR      = 0x21,
    TABLE_ASSEMBLYOS             = 0x22,
    TABLE_ASSEMBLYREF            = 0x23,
    TABLE_ASSEMBLYREFPROCESSOR   = 0x24,
    TABLE_ASSEMBLYREFOS          = 0x25,
    TABLE_FILE                   = 0x26,
    TABLE_EXPORTEDTYPE           = 0x27,
    TABLE_MANIFESTRESOURCE       = 0x28,
    TABLE_NESTEDCLASS            = 0x29,
    TABLE_GENERICPARAM           = 0x2a,
    TABLE_METHODSPEC             = 0x2b,
    TABLE_GENERICPARAMCONSTRAINT = 0x2c,
    TABLE_MAX                    = 0x2d
};

#define SORTED_TABLES \
    1ull << TABLE_INTERFACEIMPL |\
    1ull << TABLE_CONSTANT |\
    1ull << TABLE_CUSTOMATTRIBUTE |\
    1ull << TABLE_FIELDMARSHAL |\
    1ull << TABLE_DECLSECURITY |\
    1ull << TABLE_CLASSLAYOUT |\
    1ull << TABLE_FIELDLAYOUT |\
    1ull << TABLE_EVENTMAP |\
    1ull << TABLE_PROPERTYMAP |\
    1ull << TABLE_METHODSEMANTICS |\
    1ull << TABLE_METHODIMPL |\
    1ull << TABLE_IMPLMAP |\
    1ull << TABLE_FIELDRVA |\
    1ull << TABLE_NESTEDCLASS |\
    1ull << TABLE_GENERICPARAM |\
    1ull << TABLE_GENERICPARAMCONSTRAINT

static struct
{
    UINT   reserved;
    BYTE   majorversion;
    BYTE   minor_version;
    BYTE   heap_sizes;
    BYTE   reserved2;
    UINT64 valid;
    UINT64 sorted;
}
tables_header = { 0, 2, 0, 0, 1, 0, SORTED_TABLES };

static struct buffer
{
    UINT  offset;        /* write position */
    UINT  allocated;     /* allocated size in bytes */
    UINT  count;         /* number of entries written */
    BYTE *ptr;
} strings, strings_idx, userstrings, userstrings_idx, blobs, blobs_idx, guids, tables[TABLE_MAX],
  tables_idx[TABLE_MAX], tables_disk;

static void *grow_buffer( struct buffer *buf, UINT size )
{
    UINT new_size;

    if (buf->allocated - buf->offset >= size) return buf->ptr;

    new_size = max( buf->offset + size, buf->allocated * 2 );
    buf->ptr = xrealloc( buf->ptr, new_size );
    buf->allocated = new_size;
    return buf->ptr;
}

static UINT encode_int( UINT value, BYTE *encoded )
{
    if (value < 0x80)
    {
        encoded[0] = value;
        return 1;
    }
    if (value < 0x4000)
    {
        encoded[0] = value >> 8 | 0x80;
        encoded[1] = value & 0xff;
        return 2;
    }
    if (value < 0x20000000)
    {
        encoded[0] = value >> 24 | 0xc0;
        encoded[1] = value >> 16 & 0xff;
        encoded[2] = value >> 8 & 0xff;
        encoded[3] = value & 0xff;
        return 4;
    }
    fprintf( stderr, "Value too large to encode.\n" );
    exit( 1 );
}

static UINT decode_int( const BYTE *encoded, UINT *len )
{
    if (!(encoded[0] & 0x80))
    {
        *len = 1;
        return encoded[0];
    }
    if (!(encoded[0] & 0x40))
    {
        *len = 2;
        return ((encoded[0] & ~0xc0) << 8) + encoded[1];
    }
    if (!(encoded[0] & 0x20))
    {
        *len = 4;
        return ((encoded[0] & ~0xe0) << 24) + (encoded[1] << 16) + (encoded[2] << 8) + encoded[3];
    }
    fprintf( stderr, "Invalid encoding.\n" );
    exit( 1 );
}

struct index
{
    UINT offset;    /* offset into corresponding data buffer */
    UINT size;      /* size of data entry */
};

static inline int cmp_data( const BYTE *data, UINT size, const BYTE *data2, UINT size2 )
{
    if (size < size2) return -1;
    else if (size > size2) return 1;
    return memcmp( data, data2, size );
}

/* return index struct if found, NULL and insert index if not found */
static const struct index *find_index( const struct buffer *buf_idx, const struct buffer *buf_data, const BYTE *data,
                                       UINT data_size, BOOL is_blob, UINT *insert_idx )
{
    int i, c, min = 0, max = buf_idx->count - 1;
    const struct index *idx, *base = (const struct index *)buf_idx->ptr;
    UINT size, len = 0;

    while (min <= max)
    {
        i = (min + max) / 2;
        idx = &base[i];

        if (is_blob) size = decode_int( buf_data->ptr + idx->offset, &len );
        else size = idx->size;

        c = cmp_data( data, data_size, buf_data->ptr + idx->offset + len, size );

        if (c < 0) max = i - 1;
        else if (c > 0) min = i + 1;
        else return idx;
    }

    if (insert_idx) *insert_idx = max + 1;
    return NULL;
}

static void insert_index( struct buffer *buf_idx, UINT idx, UINT offset, UINT size )
{
    struct index new = { offset, size }, *base = grow_buffer( buf_idx, sizeof(new) );

    memmove( &base[idx] + 1, &base[idx], (buf_idx->count - idx) * sizeof(new) );
    base[idx] = new;
    buf_idx->offset += sizeof(new);
    buf_idx->count++;
}

static UINT add_string( const char *str )
{
    UINT insert_idx, size, offset = strings.offset;
    const struct index *idx;

    if (!str) return 0;
    size = strlen( str ) + 1;
    if ((idx = find_index( &strings_idx, &strings, (const BYTE *)str, size, FALSE, &insert_idx )))
        return idx->offset;

    grow_buffer( &strings, size );
    memcpy( strings.ptr + offset, str, size );
    strings.offset += size;
    strings.count++;

    insert_index( &strings_idx, insert_idx, offset, size );
    return offset;
}

static inline int is_special_char( USHORT c )
{
    return (c >= 0x100 || (c >= 0x01 && c <= 0x08) || (c >= 0x0e && c <= 0x1f) || c == 0x27 || c == 0x2d || c == 0x7f);
}

static UINT add_userstring( const USHORT *str, UINT size )
{
    BYTE encoded[4], terminal = 0;
    UINT i, insert_idx, offset = userstrings.offset, len = encode_int( size + (str ? 1 : 0), encoded );
    const struct index *idx;

    if (!str && offset) return 0;

    if ((idx = find_index( &userstrings_idx, &userstrings, (const BYTE *)str, size, TRUE, &insert_idx )))
        return idx->offset;

    grow_buffer( &userstrings, len + size + 1 );
    memcpy( userstrings.ptr + userstrings.offset, encoded, len );
    userstrings.offset += len;
    if (str)
    {
        for (i = 0; i < size / sizeof(USHORT); i++)
        {
            *(USHORT *)(userstrings.ptr + userstrings.offset) = str[i];
            userstrings.offset += sizeof(USHORT);
            if (is_special_char( str[i] )) terminal = 1;
        }
        userstrings.ptr[userstrings.offset++] = terminal;
    }
    userstrings.count++;

    insert_index( &userstrings_idx, insert_idx, offset, size );
    return offset;
}

static UINT add_blob( const BYTE *blob, UINT size )
{
    BYTE encoded[4];
    UINT insert_idx, offset = blobs.offset, len = encode_int( size, encoded );
    const struct index *idx;

    if (!blob && offset) return 0;
    if ((idx = find_index( &blobs_idx, &blobs, blob, size, TRUE, &insert_idx ))) return idx->offset;

    grow_buffer( &blobs, len + size );
    memcpy( blobs.ptr + blobs.offset, encoded, len );
    blobs.offset += len;
    if (blob)
    {
        memcpy( blobs.ptr + blobs.offset, blob, size );
        blobs.offset += size;
    }
    blobs.count++;

    insert_index( &blobs_idx, insert_idx, offset, size );
    return offset;
}

static UINT add_guid( const GUID *guid )
{
    grow_buffer( &guids, sizeof(*guid) );
    memcpy( guids.ptr + guids.offset, guid, sizeof(*guid) );
    guids.offset += sizeof(*guid);
    return ++guids.count;
}

/* returns row number */
static UINT add_row( enum table table, const BYTE *row, UINT row_size )
{
    const struct index *idx;
    UINT insert_idx, offset = tables[table].offset;
    BOOL sort = (table != TABLE_PARAM && table != TABLE_FIELD && table != TABLE_PROPERTY && table != TABLE_EVENT);

    if (sort && (idx = find_index( &tables_idx[table], &tables[table], row, row_size, FALSE, &insert_idx )))
        return idx->offset / row_size + 1;

    grow_buffer( &tables[table], row_size );
    memcpy( tables[table].ptr + offset, row, row_size );
    tables[table].offset += row_size;
    tables[table].count++;

    if (sort) insert_index( &tables_idx[table], insert_idx, offset, row_size );
    return tables[table].count;
}

static void add_bytes( struct buffer *buf, const BYTE *data, UINT size )
{
    grow_buffer( buf, size );
    memcpy( buf->ptr + buf->offset, data, size );
    buf->offset += size;
}

static void serialize_byte( UINT value )
{
    assert( !(value >> 24) );
    add_bytes( &tables_disk, (const BYTE *)&value, sizeof(BYTE) );
}

static void serialize_ushort( UINT value )
{
    assert( !(value >> 16) );
    add_bytes( &tables_disk, (const BYTE *)&value, sizeof(USHORT) );
}

static void serialize_uint( UINT value )
{
    add_bytes( &tables_disk, (const BYTE *)&value, sizeof(value) );
}

static void serialize_string_idx( UINT idx )
{
    UINT size = strings.offset >> 16 ? sizeof(UINT) : sizeof(USHORT);
    add_bytes( &tables_disk, (const BYTE *)&idx, size );
}

static void serialize_guid_idx( UINT idx )
{
    UINT size = guids.offset >> 16 ? sizeof(UINT) : sizeof(USHORT);
    add_bytes( &tables_disk, (const BYTE *)&idx, size );
}

static void serialize_blob_idx( UINT idx )
{
    UINT size = blobs.offset >> 16 ? sizeof(UINT) : sizeof(USHORT);
    add_bytes( &tables_disk, (const BYTE *)&idx, size );
}

static void serialize_table_idx( UINT idx, enum table target )
{
    UINT size = tables[target].count >> 16 ? sizeof(UINT) : sizeof(USHORT);
    add_bytes( &tables_disk, (const BYTE *)&idx, size );
}

static enum table resolution_scope_to_table( UINT token )
{
    switch (token & 0x3)
    {
    case 0: return TABLE_MODULE;
    case 1: return TABLE_MODULEREF;
    case 2: return TABLE_ASSEMBLYREF;
    case 3: return TABLE_TYPEREF;
    default: assert( 0 );
    }
}

static enum table typedef_or_ref_to_table( UINT token )
{
    switch (token & 0x3)
    {
    case 0: return TABLE_TYPEDEF;
    case 1: return TABLE_TYPEREF;
    case 2: return TABLE_TYPESPEC;
    default: assert( 0 );
    }
}

static enum table methoddef_or_ref_to_table( UINT token )
{
    switch (token & 0x1)
    {
    case 0: return TABLE_METHODDEF;
    case 1: return TABLE_MEMBERREF;
    default: assert( 0 );
    }
}

static enum table memberref_parent_to_table( UINT token )
{
    switch (token & 0x7)
    {
    case 0: return TABLE_TYPEDEF;
    case 1: return TABLE_TYPEREF;
    case 2: return TABLE_MODULEREF;
    case 3: return TABLE_METHODDEF;
    case 4: return TABLE_TYPESPEC;
    default: assert( 0 );
    }
}

static enum table has_constant_to_table( UINT token )
{
    switch (token & 0x3)
    {
    case 0: return TABLE_FIELD;
    case 1: return TABLE_PARAM;
    case 2: return TABLE_PROPERTY;
    default: assert( 0 );
    }
}

static enum table has_customattribute_to_table( UINT token )
{
    switch (token & 0x1f)
    {
    case 0: return TABLE_METHODDEF;
    case 1: return TABLE_FIELD;
    case 2: return TABLE_TYPEREF;
    case 3: return TABLE_TYPEDEF;
    case 4: return TABLE_PARAM;
    case 5: return TABLE_INTERFACEIMPL;
    case 6: return TABLE_MEMBERREF;
    case 7: return TABLE_MODULE;
    case 9: return TABLE_PROPERTY;
    case 10: return TABLE_EVENT;
    case 11: return TABLE_STANDALONESIG;
    case 12: return TABLE_MODULEREF;
    case 13: return TABLE_TYPESPEC;
    case 14: return TABLE_ASSEMBLY;
    case 15: return TABLE_ASSEMBLYREF;
    case 16: return TABLE_FILE;
    case 17: return TABLE_EXPORTEDTYPE;
    case 18: return TABLE_MANIFESTRESOURCE;
    default: assert( 0 );
    }
}

static enum table customattribute_type_to_table( UINT token )
{
    switch (token & 0x7)
    {
    case 2: return TABLE_METHODDEF;
    case 3: return TABLE_MEMBERREF;
    default: assert( 0 );
    }
}

static enum table has_semantics_to_table( UINT token )
{
    switch (token & 0x1)
    {
    case 0: return TABLE_EVENT;
    case 1: return TABLE_PROPERTY;
    default: assert( 0 );
    }
}

struct module_row
{
    UINT generation;
    UINT name;
    UINT mvid;
    UINT encid;
    UINT encbaseid;
};

static UINT add_module_row( UINT name, UINT mvid )
{
    struct module_row row = { 0, name, mvid, 0, 0 };
    return add_row( TABLE_MODULE, (const BYTE *)&row, sizeof(row) );
}

static void serialize_module_table( void )
{
    const struct module_row *row = (const struct module_row *)tables[TABLE_MODULE].ptr;

    serialize_ushort( row->generation );
    serialize_string_idx( row->name );
    serialize_guid_idx( row->mvid );
    serialize_guid_idx( row->encid );
    serialize_guid_idx( row->encbaseid );
}

struct typeref_row
{
    UINT scope;
    UINT name;
    UINT namespace;
};

static UINT add_typeref_row( UINT scope, UINT name, UINT namespace )
{
    struct typeref_row row = { scope, name, namespace };
    return add_row( TABLE_TYPEREF, (const BYTE *)&row, sizeof(row) );
}

static void serialize_typeref_table( void )
{
    const struct typeref_row *row = (const struct typeref_row *)tables[TABLE_TYPEREF].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_TYPEREF].count; i++)
    {
        serialize_table_idx( row->scope, resolution_scope_to_table(row->scope) );
        serialize_string_idx( row->name );
        serialize_string_idx( row->namespace );
        row++;
    }
}

struct typedef_row
{
    UINT flags;
    UINT name;
    UINT namespace;
    UINT extends;
    UINT fieldlist;
    UINT methodlist;
};

static UINT add_typedef_row( UINT flags, UINT name, UINT namespace, UINT extends, UINT fieldlist, UINT methodlist )
{
    struct typedef_row row = { flags, name, namespace, extends, fieldlist, methodlist };

    if (!row.fieldlist) row.fieldlist = tables[TABLE_FIELD].count + 1;
    if (!row.methodlist) row.methodlist = tables[TABLE_METHODDEF].count + 1;
    return add_row( TABLE_TYPEDEF, (const BYTE *)&row, sizeof(row) );
}

/* FIXME: enclosing classes should come before enclosed classes */
static void serialize_typedef_table( void )
{
    const struct typedef_row *row = (const struct typedef_row *)tables[TABLE_TYPEDEF].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_TYPEDEF].count; i++)
    {
        serialize_uint( row->flags );
        serialize_string_idx( row->name );
        serialize_string_idx( row->namespace );
        serialize_table_idx( row->extends, typedef_or_ref_to_table(row->extends) );
        serialize_table_idx( row->fieldlist, TABLE_FIELD );
        serialize_table_idx( row->methodlist, TABLE_METHODDEF );
        row++;
    }
}

struct field_row
{
    UINT flags;
    UINT name;
    UINT signature;
};

static UINT add_field_row( UINT flags, UINT name, UINT signature )
{
    struct field_row row = { flags, name, signature };
    return add_row( TABLE_FIELD, (const BYTE *)&row, sizeof(row) );
}

static void serialize_field_table( void )
{
    const struct field_row *row = (const struct field_row *)tables[TABLE_FIELD].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_FIELD].count; i++)
    {
        serialize_ushort( row->flags );
        serialize_string_idx( row->name );
        serialize_blob_idx( row->signature );
        row++;
    }
}

struct methoddef_row
{
    UINT rva;
    UINT implflags;
    UINT flags;
    UINT name;
    UINT signature;
    UINT paramlist;
};

static UINT add_methoddef_row( UINT implflags, UINT flags, UINT name, UINT signature, UINT paramlist )
{
    struct methoddef_row row = { 0, implflags, flags, name, signature, paramlist };

    if (!row.paramlist) row.paramlist = tables[TABLE_PARAM].count + 1;
    return add_row( TABLE_METHODDEF, (const BYTE *)&row, sizeof(row) );
}

static void serialize_methoddef_table( void )
{
    const struct methoddef_row *row = (const struct methoddef_row *)tables[TABLE_METHODDEF].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_METHODDEF].count; i++)
    {
        serialize_uint( row->rva );
        serialize_ushort( row->implflags );
        serialize_ushort( row->flags );
        serialize_string_idx( row->name );
        serialize_blob_idx( row->signature );
        serialize_table_idx( row->paramlist, TABLE_PARAM );
        row++;
    }
}

struct param_row
{
    UINT flags;
    UINT sequence;
    UINT name;
};

static UINT add_param_row( USHORT flags, USHORT sequence, UINT name )
{
    struct param_row row = { flags, sequence, name };
    return add_row( TABLE_PARAM, (const BYTE *)&row, sizeof(row) );
}

static void serialize_param_table( void )
{
    const struct param_row *row = (const struct param_row *)tables[TABLE_PARAM].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_PARAM].count; i++)
    {
        serialize_ushort( row->flags );
        serialize_ushort( row->sequence );
        serialize_string_idx( row->name );
        row++;
    }
}

struct interfaceimpl_row
{
    UINT class;
    UINT interface;
};

static UINT add_interfaceimpl_row( UINT class, UINT interface )
{
    struct interfaceimpl_row row = { class, interface };
    return add_row( TABLE_INTERFACEIMPL, (const BYTE *)&row, sizeof(row) );
}

static int cmp_interfaceimpl_row( const void *a, const void *b )
{
    const struct interfaceimpl_row *row = a, *row2 = b;
    if (row->class > row2->class) return 1;
    if (row->class < row2->class) return -1;
    if (row->interface > row2->interface) return 1;
    if (row->interface < row2->interface) return -1;
    return 0;
}

/* sorted by class, interface */
static void serialize_interfaceimpl_table( void )
{
    const struct interfaceimpl_row *row = (const struct interfaceimpl_row *)tables[TABLE_INTERFACEIMPL].ptr;
    UINT i;

    qsort( tables[TABLE_INTERFACEIMPL].ptr, tables[TABLE_INTERFACEIMPL].count, sizeof(*row),
           cmp_interfaceimpl_row );

    for (i = 0; i < tables_idx[TABLE_INTERFACEIMPL].count; i++)
    {
        serialize_table_idx( row->class, TABLE_TYPEDEF );
        serialize_table_idx( row->interface, typedef_or_ref_to_table(row->interface) );
        row++;
    }
}

struct memberref_row
{
    UINT class;
    UINT name;
    UINT signature;
};

static UINT add_memberref_row( UINT class, UINT name, UINT signature )
{
    struct memberref_row row = { class, name, signature };
    return add_row( TABLE_MEMBERREF, (const BYTE *)&row, sizeof(row) );
}

static void serialize_memberref_table( void )
{
    const struct memberref_row *row = (const struct memberref_row *)tables[TABLE_MEMBERREF].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_MEMBERREF].count; i++)
    {
        serialize_table_idx( row->class, memberref_parent_to_table(row->class) );
        serialize_string_idx( row->name );
        serialize_blob_idx( row->signature );
        row++;
    }
}

struct constant_row
{
    UINT type;
    UINT padding;
    UINT parent;
    UINT value;
};

static UINT add_constant_row( BYTE type, UINT parent, UINT value )
{
    struct constant_row row = { type, 0, parent, value };
    return add_row( TABLE_CONSTANT, (const BYTE *)&row, sizeof(row) );
}

static int cmp_constant_row( const void *a, const void *b )
{
    const struct constant_row *row = a, *row2 = b;
    if (row->parent > row2->parent) return 1;
    if (row->parent < row2->parent) return -1;
    return 0;
}

/* sorted by parent */
static void serialize_constant_table( void )
{
    const struct constant_row *row = (const struct constant_row *)tables[TABLE_CONSTANT].ptr;
    UINT i;

    qsort( tables[TABLE_CONSTANT].ptr, tables[TABLE_CONSTANT].count, sizeof(*row), cmp_constant_row );

    for (i = 0; i < tables_idx[TABLE_CONSTANT].count; i++)
    {
        serialize_byte( row->type );
        serialize_byte( row->padding );
        serialize_table_idx( row->parent, has_constant_to_table(row->parent) );
        serialize_blob_idx( row->value );
        row++;
    }
}

struct customattribute_row
{
    UINT parent;
    UINT type;
    UINT value;
};

static UINT add_customattribute_row( UINT parent, UINT type, UINT value )
{
    struct customattribute_row row = { parent, type, value };
    return add_row( TABLE_CUSTOMATTRIBUTE, (const BYTE *)&row, sizeof(row) );
}

static int cmp_customattribute_row( const void *a, const void *b )
{
    const struct customattribute_row *row = a, *row2 = b;
    if (row->parent > row2->parent) return 1;
    if (row->parent < row2->parent) return -1;
    return 0;
}

/* sorted by parent */
static void serialize_customattribute_table( void )
{
    const struct customattribute_row *row = (const struct customattribute_row *)tables[TABLE_CUSTOMATTRIBUTE].ptr;
    UINT i;

    qsort( tables[TABLE_CUSTOMATTRIBUTE].ptr, tables[TABLE_CUSTOMATTRIBUTE].count, sizeof(*row),
           cmp_customattribute_row );

    for (i = 0; i < tables_idx[TABLE_CUSTOMATTRIBUTE].count; i++)
    {
        serialize_table_idx( row->parent, has_customattribute_to_table(row->parent) );
        serialize_table_idx( row->type, customattribute_type_to_table(row->type) );
        serialize_blob_idx( row->value );
        row++;
    }
}

struct assembly_row
{
    UINT hashalgid;
    UINT majorversion;
    UINT minorversion;
    UINT buildnumber;
    UINT revisionnumber;
    UINT flags;
    UINT publickey;
    UINT name;
    UINT culture;
};

static UINT add_assembly_row( UINT name )
{
    struct assembly_row row = { CALG_SHA, 255, 255, 255, 255, 0x200, 0, name, 0 };
    return add_row( TABLE_ASSEMBLY, (const BYTE *)&row, sizeof(row) );
}

static void serialize_assembly_table( void )
{
    const struct assembly_row *row = (const struct assembly_row *)tables[TABLE_ASSEMBLY].ptr;

    serialize_uint( row->hashalgid );
    serialize_ushort( row->majorversion );
    serialize_ushort( row->minorversion );
    serialize_ushort( row->buildnumber );
    serialize_ushort( row->revisionnumber );
    serialize_uint( row->flags );
    serialize_blob_idx( row->publickey );
    serialize_string_idx( row->name );
    serialize_string_idx( row->culture );
}

struct assemblyref_row
{
    UINT majorversion;
    UINT minorversion;
    UINT buildnumber;
    UINT revisionnumber;
    UINT flags;
    UINT publickey;
    UINT name;
    UINT culture;
    UINT hashvalue;
};

static UINT add_assemblyref_row( UINT flags, UINT publickey, UINT name )
{
    struct assemblyref_row row = { 255, 255, 255, 255, flags, publickey, name, 0, 0 };
    return add_row( TABLE_ASSEMBLYREF, (const BYTE *)&row, sizeof(row) );
}

static void serialize_assemblyref_table( void )
{
    const struct assemblyref_row *row = (const struct assemblyref_row *)tables[TABLE_ASSEMBLYREF].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_ASSEMBLYREF].count; i++)
    {
        serialize_ushort( row->majorversion );
        serialize_ushort( row->minorversion );
        serialize_ushort( row->buildnumber );
        serialize_ushort( row->revisionnumber );
        serialize_uint( row->flags );
        serialize_blob_idx( row->publickey );
        serialize_string_idx( row->name );
        serialize_string_idx( row->culture );
        serialize_blob_idx( row->hashvalue );
        row++;
    }
}

struct propertymap_row
{
    UINT parent;
    UINT proplist;
};

static UINT add_propertymap_row( UINT parent, UINT proplist )
{
    struct propertymap_row row = { parent, proplist };
    return add_row( TABLE_PROPERTYMAP, (const BYTE *)&row, sizeof(row) );
}

static void serialize_propertymap_table( void )
{
    const struct propertymap_row *row = (const struct propertymap_row *)tables[TABLE_PROPERTYMAP].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_PROPERTYMAP].count; i++)
    {
        serialize_table_idx( row->parent, TABLE_TYPEDEF );
        serialize_table_idx( row->proplist, TABLE_PROPERTY );
        row++;
    }
}

struct property_row
{
    UINT flags;
    UINT name;
    UINT type;
};

static UINT add_property_row( USHORT flags, UINT name, UINT type )
{
    struct property_row row = { flags, name, type };
    return add_row( TABLE_PROPERTY, (const BYTE *)&row, sizeof(row) );
}

static void serialize_property_table( void )
{
    const struct property_row *row = (const struct property_row *)tables[TABLE_PROPERTY].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_PROPERTY].count; i++)
    {
        serialize_ushort( row->flags );
        serialize_string_idx( row->name );
        serialize_blob_idx( row->type );
        row++;
    }
}

struct eventmap_row
{
    UINT parent;
    UINT eventlist;
};

static UINT add_eventmap_row( UINT parent, UINT eventlist )
{
    struct eventmap_row row = { parent, eventlist };
    return add_row( TABLE_EVENTMAP, (const BYTE *)&row, sizeof(row) );
}

static void serialize_eventmap_table( void )
{
    const struct eventmap_row *row = (const struct eventmap_row *)tables[TABLE_EVENTMAP].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_EVENTMAP].count; i++)
    {
        serialize_table_idx( row->parent, TABLE_TYPEDEF );
        serialize_table_idx( row->eventlist, TABLE_EVENT );
        row++;
    }
}

struct event_row
{
    UINT flags;
    UINT name;
    UINT type;
};

static UINT add_event_row( USHORT flags, UINT name, UINT type )
{
    struct event_row row = { flags, name, type };
    return add_row( TABLE_EVENT, (const BYTE *)&row, sizeof(row) );
}

static void serialize_event_table( void )
{
    const struct event_row *row = (const struct event_row *)tables[TABLE_EVENT].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_EVENT].count; i++)
    {
        serialize_ushort( row->flags );
        serialize_string_idx( row->name );
        serialize_table_idx( row->type, typedef_or_ref_to_table(row->type) );
        row++;
    }
}

struct methodsemantics_row
{
    UINT semantics;
    UINT method;
    UINT association;
};

static UINT add_methodsemantics_row( USHORT flags, UINT name, UINT type )
{
    struct methodsemantics_row row = { flags, name, type };
    return add_row( TABLE_METHODSEMANTICS, (const BYTE *)&row, sizeof(row) );
}

static int cmp_methodsemantics_row( const void *a, const void *b )
{
    const struct methodsemantics_row *row = a, *row2 = b;
    if (row->association > row2->association) return 1;
    if (row->association < row2->association) return -1;
    return 0;
}

/* sorted by association */
static void serialize_methodsemantics_table( void )
{
    const struct methodsemantics_row *row = (const struct methodsemantics_row *)tables[TABLE_METHODSEMANTICS].ptr;
    UINT i;

    qsort( tables[TABLE_METHODSEMANTICS].ptr, tables[TABLE_METHODSEMANTICS].count, sizeof(*row),
           cmp_methodsemantics_row );

    for (i = 0; i < tables[TABLE_METHODSEMANTICS].count; i++)
    {
        serialize_ushort( row->semantics );
        serialize_table_idx( row->method, TABLE_METHODDEF );
        serialize_table_idx( row->association, has_semantics_to_table(row->association) );
        row++;
    }
}

struct methodimpl_row
{
    UINT class;
    UINT body;
    UINT declaration;
};

static UINT add_methodimpl_row( UINT class, UINT body, UINT declaration )
{
    struct methodimpl_row row = { class, body, declaration };
    return add_row( TABLE_METHODIMPL, (const BYTE *)&row, sizeof(row) );
}

static void serialize_methodimpl_table( void )
{
    const struct methodimpl_row *row = (const struct methodimpl_row *)tables[TABLE_METHODIMPL].ptr;
    UINT i;

    for (i = 0; i < tables[TABLE_METHODIMPL].count; i++)
    {
        serialize_table_idx( row->class, row->class );
        serialize_table_idx( row->body, methoddef_or_ref_to_table(row->body) );
        serialize_table_idx( row->declaration, methoddef_or_ref_to_table(row->declaration) );
        row++;
    }
}

static UINT typedef_or_ref( enum table table, UINT row )
{
    switch (table)
    {
    case TABLE_TYPEDEF: return row << 2;
    case TABLE_TYPEREF: return row << 2 | 1;
    case TABLE_TYPESPEC: return row << 2 | 2;
    default: assert( 0 );
    }
}

static UINT methoddef_or_ref( enum table table, UINT row )
{
    switch (table)
    {
    case TABLE_METHODDEF: return row << 1;
    case TABLE_MEMBERREF: return row << 1 | 1;
    default: assert( 0 );
    }
}

static UINT resolution_scope( enum table table, UINT row )
{
    switch (table)
    {
    case TABLE_MODULE: return row << 2;
    case TABLE_MODULEREF: return row << 2 | 1;
    case TABLE_ASSEMBLYREF: return row << 2 | 2;
    case TABLE_TYPEREF: return row << 2 | 3;
    default: assert( 0 );
    }
}

static UINT has_constant( enum table table, UINT row )
{
    switch (table)
    {
    case TABLE_FIELD: return row << 2;
    case TABLE_PARAM: return row << 2 | 1;
    case TABLE_PROPERTY: return row << 2 | 2;
    default: assert( 0 );
    }
}

static UINT memberref_parent( enum table table, UINT row )
{
    switch (table)
    {
    case TABLE_TYPEDEF: return row << 3;
    case TABLE_TYPEREF: return row << 3 | 1;
    case TABLE_MODULEREF: return row << 3 | 2;
    case TABLE_METHODDEF: return row << 3 | 3;
    case TABLE_TYPESPEC: return row << 3 | 4;
    default: assert( 0 );
    }
}

static UINT has_customattribute( enum table table, UINT row )
{
    switch (table)
    {
    case TABLE_METHODDEF: return row << 5;
    case TABLE_FIELD: return row << 5 | 1;
    case TABLE_TYPEREF: return row << 5 | 2;
    case TABLE_TYPEDEF: return row << 5 | 3;
    case TABLE_PARAM: return row << 5 | 4;
    case TABLE_INTERFACEIMPL: return row << 5 | 5;
    case TABLE_MEMBERREF: return row << 5 | 6;
    case TABLE_MODULE: return row << 5 | 7;
    case TABLE_PROPERTY: return row << 5 | 9;
    case TABLE_EVENT: return row << 5 | 10;
    case TABLE_STANDALONESIG: return row << 5 | 11;
    case TABLE_MODULEREF: return row << 5 | 12;
    case TABLE_TYPESPEC: return row << 5 | 13;
    case TABLE_ASSEMBLY: return row << 5 | 14;
    case TABLE_ASSEMBLYREF: return row << 5 | 15;
    case TABLE_FILE: return row << 5 | 16;
    case TABLE_EXPORTEDTYPE: return row << 5 | 17;
    case TABLE_MANIFESTRESOURCE: return row << 5 | 18;
    default: assert( 0 );
    }
}

static UINT customattribute_type( enum table table, UINT row )
{
    switch (table)
    {
    case TABLE_METHODDEF: return row << 3 | 2;
    case TABLE_MEMBERREF: return row << 3 | 3;
    default: assert( 0 );
    }
}

static UINT has_semantics( enum table table, UINT row )
{
    switch (table)
    {
    case TABLE_EVENT: return row << 1;
    case TABLE_PROPERTY: return row << 1 | 1;
    default: assert( 0 );
    }
}

enum element_type
{
    ELEMENT_TYPE_END            = 0x00,
    ELEMENT_TYPE_VOID           = 0x01,
    ELEMENT_TYPE_BOOLEAN        = 0x02,
    ELEMENT_TYPE_CHAR           = 0x03,
    ELEMENT_TYPE_I1             = 0x04,
    ELEMENT_TYPE_U1             = 0x05,
    ELEMENT_TYPE_I2             = 0x06,
    ELEMENT_TYPE_U2             = 0x07,
    ELEMENT_TYPE_I4             = 0x08,
    ELEMENT_TYPE_U4             = 0x09,
    ELEMENT_TYPE_I8             = 0x0a,
    ELEMENT_TYPE_U8             = 0x0b,
    ELEMENT_TYPE_R4             = 0x0c,
    ELEMENT_TYPE_R8             = 0x0d,
    ELEMENT_TYPE_STRING         = 0x0e,
    ELEMENT_TYPE_PTR            = 0x0f,
    ELEMENT_TYPE_BYREF          = 0x10,
    ELEMENT_TYPE_VALUETYPE      = 0x11,
    ELEMENT_TYPE_CLASS          = 0x12,
    ELEMENT_TYPE_VAR            = 0x13,
    ELEMENT_TYPE_ARRAY          = 0x14,
    ELEMENT_TYPE_GENERICINST    = 0x15,
    ELEMENT_TYPE_TYPEDBYREF     = 0x16,
    ELEMENT_TYPE_I              = 0x18,
    ELEMENT_TYPE_U              = 0x19,
    ELEMENT_TYPE_FNPTR          = 0x1b,
    ELEMENT_TYPE_OBJECT         = 0x1c,
    ELEMENT_TYPE_SZARRAY        = 0x1d,
    ELEMENT_TYPE_MVAR           = 0x1e,
    ELEMENT_TYPE_CMOD_REQD      = 0x1f,
    ELEMENT_TYPE_CMOD_OPT       = 0x20,
    ELEMENT_TYPE_INTERNAL       = 0x21,
    ELEMENT_TYPE_MODIFIER       = 0x40,
    ELEMENT_TYPE_SENTINEL       = 0x41,
    ELEMENT_TYPE_PINNED         = 0x45
};

enum
{
    TYPE_ATTR_PUBLIC            = 0x000001,
    TYPE_ATTR_NESTEDPUBLIC      = 0x000002,
    TYPE_ATTR_NESTEDPRIVATE     = 0x000003,
    TYPE_ATTR_NESTEDFAMILY      = 0x000004,
    TYPE_ATTR_NESTEDASSEMBLY    = 0x000005,
    TYPE_ATTR_NESTEDFAMANDASSEM = 0x000006,
    TYPE_ATTR_NESTEDFAMORASSEM  = 0x000007,
    TYPE_ATTR_SEQUENTIALLAYOUT  = 0x000008,
    TYPE_ATTR_EXPLICITLAYOUT    = 0x000010,
    TYPE_ATTR_INTERFACE         = 0x000020,
    TYPE_ATTR_ABSTRACT          = 0x000080,
    TYPE_ATTR_SEALED            = 0x000100,
    TYPE_ATTR_SPECIALNAME       = 0x000400,
    TYPE_ATTR_RTSPECIALNAME     = 0x000800,
    TYPE_ATTR_IMPORT            = 0x001000,
    TYPE_ATTR_SERIALIZABLE      = 0x002000,
    TYPE_ATTR_UNKNOWN           = 0x004000,
    TYPE_ATTR_UNICODECLASS      = 0x010000,
    TYPE_ATTR_AUTOCLASS         = 0x020000,
    TYPE_ATTR_CUSTOMFORMATCLASS = 0x030000,
    TYPE_ATTR_HASSECURITY       = 0x040000,
    TYPE_ATTR_BEFOREFIELDINIT   = 0x100000
};

enum
{
    FIELD_ATTR_PRIVATE          = 0x0001,
    FIELD_ATTR_FAMANDASSEM      = 0x0002,
    FIELD_ATTR_ASSEMBLY         = 0x0003,
    FIELD_ATTR_FAMILY           = 0x0004,
    FIELD_ATTR_FAMORASSEM       = 0x0005,
    FIELD_ATTR_PUBLIC           = 0x0006,
    FIELD_ATTR_STATIC           = 0x0010,
    FIELD_ATTR_INITONLY         = 0x0020,
    FIELD_ATTR_LITERAL          = 0x0040,
    FIELD_ATTR_NOTSERIALIZED    = 0x0080,
    FIELD_ATTR_HASFIELDRVA      = 0x0100,
    FIELD_ATTR_SPECIALNAME      = 0x0200,
    FIELD_ATTR_RTSPECIALNAME    = 0x0400,
    FIELD_ATTR_HASFIELDMARSHAL  = 0x1000,
    FIELD_ATTR_PINVOKEIMPL      = 0x2000,
    FIELD_ATTR_HASDEFAULT       = 0x8000
};

enum
{
    METHOD_ATTR_COMPILERCONTROLLED = 0x0000,
    METHOD_ATTR_PRIVATE            = 0x0001,
    METHOD_ATTR_FAMANDASSEM        = 0x0002,
    METHOD_ATTR_ASSEM              = 0x0003,
    METHOD_ATTR_FAMILY             = 0x0004,
    METHOD_ATTR_FAMORASSEM         = 0x0005,
    METHOD_ATTR_PUBLIC             = 0x0006,
    METHOD_ATTR_STATIC             = 0x0010,
    METHOD_ATTR_FINAL              = 0x0020,
    METHOD_ATTR_VIRTUAL            = 0x0040,
    METHOD_ATTR_HIDEBYSIG          = 0x0080,
    METHOD_ATTR_NEWSLOT            = 0x0100,
    METHOD_ATTR_STRICT             = 0x0200,
    METHOD_ATTR_ABSTRACT           = 0x0400,
    METHOD_ATTR_SPECIALNAME        = 0x0800,
    METHOD_ATTR_RTSPECIALNAME      = 0x1000,
    METHOD_ATTR_PINVOKEIMPL        = 0x2000
};

enum
{
    METHOD_IMPL_IL        = 0x0000,
    METHOD_IMPL_NATIVE    = 0x0001,
    METHOD_IMPL_OPTIL     = 0x0002,
    METHOD_IMPL_RUNTIME   = 0x0003,
    METHOD_IMPL_UNMANAGED = 0x0004
};

enum
{
    METHOD_SEM_SETTER   = 0x0001,
    METHOD_SEM_GETTER   = 0x0002,
    METHOD_SEM_OTHER    = 0x0004,
    METHOD_SEM_ADDON    = 0x0008,
    METHOD_SEM_REMOVEON = 0x0010
};

enum
{
    PARAM_ATTR_IN       = 0x0001,
    PARAM_ATTR_OUT      = 0x0002,
    PARAM_ATTR_OPTIONAL = 0x0010
};

enum
{
    SIG_TYPE_DEFAULT      = 0x00,
    SIG_TYPE_C            = 0x01,
    SIG_TYPE_STDCALL      = 0x02,
    SIG_TYPE_THISCALL     = 0x03,
    SIG_TYPE_FASTCALL     = 0x04,
    SIG_TYPE_VARARG       = 0x05,
    SIG_TYPE_FIELD        = 0x06,
    SIG_TYPE_LOCALSIG     = 0x07,
    SIG_TYPE_PROPERTY     = 0x08,
    SIG_TYPE_GENERIC      = 0x10,
    SIG_TYPE_HASTHIS      = 0x20,
    SIG_TYPE_EXPLICITTHIS = 0x40
};

#define MODULE_ROW      1
#define MSCORLIB_ROW    1

#define MAX_NAME        256

static UINT add_name( type_t *type, UINT *namespace )
{
    UINT name = add_string( type->name );
    char *str = format_namespace( type->namespace, "", ".", NULL, NULL );
    *namespace = add_string( str );
    free( str );
    return name;
}

static UINT make_field_value_sig( UINT token, BYTE *buf )
{
    UINT len = 2;

    buf[0] = SIG_TYPE_FIELD;
    buf[1] = ELEMENT_TYPE_VALUETYPE;
    len += encode_int( token, buf + 2 );
    return len;
}

enum
{
    LARGE_STRING_HEAP = 0x01,
    LARGE_GUID_HEAP   = 0x02,
    LARGE_BLOB_HEAP   = 0x04
};

static char *assembly_name;

static enum element_type map_basic_type( enum type_basic_type type, int sign )
{
    enum element_type elem_type;

    switch (type)
    {
    case TYPE_BASIC_CHAR:   elem_type = ELEMENT_TYPE_BOOLEAN; break;
    case TYPE_BASIC_INT16:  elem_type = (sign > 0) ? ELEMENT_TYPE_U2 : ELEMENT_TYPE_I2; break;
    case TYPE_BASIC_INT:
    case TYPE_BASIC_INT32:
    case TYPE_BASIC_LONG:   elem_type = (sign > 0) ? ELEMENT_TYPE_U4 : ELEMENT_TYPE_I4; break;
    case TYPE_BASIC_INT64:  elem_type = (sign > 0) ? ELEMENT_TYPE_U8 : ELEMENT_TYPE_I8; break;
    case TYPE_BASIC_BYTE:   elem_type = ELEMENT_TYPE_U1; break;
    case TYPE_BASIC_WCHAR:  elem_type = ELEMENT_TYPE_CHAR; break;
    case TYPE_BASIC_FLOAT:  elem_type = ELEMENT_TYPE_R4; break;
    case TYPE_BASIC_DOUBLE: elem_type = ELEMENT_TYPE_R8; break;
    default:
        fprintf( stderr, "Unhandled basic type %u.\n", type );
        exit( 1 );
    }
    return elem_type;
}

static UINT make_struct_field_sig( const var_t *var, BYTE *buf )
{
    const type_t *type = var->declspec.type;

    if (type->name && !strcmp( type->name, "HSTRING" ))
    {
        buf[0] = SIG_TYPE_FIELD;
        buf[1] = ELEMENT_TYPE_STRING;
        return 2;
    }

    if (type->name && !strcmp( type->name, "GUID" ))
    {
        UINT token = typedef_or_ref( TABLE_TYPEREF, type->md.ref );
        return make_field_value_sig( token, buf );
    }

    type = type_get_real_type( type );

    if (type_get_type( type ) == TYPE_ENUM || type_get_type( type ) == TYPE_STRUCT)
    {
        UINT token = typedef_or_ref( TABLE_TYPEREF, type->md.ref );
        return make_field_value_sig( token, buf );
    }

    if (type_get_type( type ) != TYPE_BASIC)
    {
        fprintf( stderr, "Unhandled struct field type %u.\n", type_get_type( type ) );
        exit( 1 );
    }

    buf[0] = SIG_TYPE_FIELD;
    buf[1] = map_basic_type( type_basic_get_type(type), type_basic_get_sign(type) );
    return 2;
}

static UINT make_member_sig( UINT token, BYTE *buf )
{
    UINT len = 4;

    buf[0] = SIG_TYPE_HASTHIS;
    buf[1] = 2;
    buf[2] = ELEMENT_TYPE_VOID;
    buf[3] = ELEMENT_TYPE_CLASS;
    len += encode_int( token, buf + 4 );
    buf[len++] = ELEMENT_TYPE_U4;
    return len;
}

static UINT make_member_sig2( UINT type, UINT token, BYTE *buf )
{
    UINT len = 4;

    buf[0] = SIG_TYPE_HASTHIS;
    buf[1] = 1;
    buf[2] = ELEMENT_TYPE_VOID;
    buf[3] = type;
    len += encode_int( token, buf + 4 );
    return len;
}

static UINT make_member_sig3( UINT token, BYTE *buf )
{
    UINT len = 4;

    buf[0] = SIG_TYPE_HASTHIS;
    buf[1] = 3;
    buf[2] = ELEMENT_TYPE_VOID;
    buf[3] = ELEMENT_TYPE_CLASS;
    len += encode_int( token, buf + 4 );
    buf[len++] = ELEMENT_TYPE_U4;
    buf[len++] = ELEMENT_TYPE_STRING;
    return len;
}

static UINT make_member_sig4( UINT token, UINT token2, BYTE *buf )
{
    UINT len = 4;

    buf[0] = SIG_TYPE_HASTHIS;
    buf[1] = 4;
    buf[2] = ELEMENT_TYPE_VOID;
    buf[3] = ELEMENT_TYPE_CLASS;
    len += encode_int( token, buf + 4 );
    buf[len++] = ELEMENT_TYPE_VALUETYPE;
    len += encode_int( token2, buf + len );
    buf[len++] = ELEMENT_TYPE_U4;
    buf[len++] = ELEMENT_TYPE_STRING;
    return len;
}

static UINT make_type_sig( const type_t *type, BYTE *buf )
{
    UINT len = 0;

    type = type_get_real_type( type );

    switch (type_get_type( type ))
    {
    case TYPE_POINTER:
    {
        const type_t *ref_type = type_pointer_get_ref_type( type );
        BOOL skip_byref = FALSE;

        switch (type_get_type( ref_type ))
        {
        case TYPE_DELEGATE:
        case TYPE_INTERFACE:
        case TYPE_RUNTIMECLASS:
            skip_byref = TRUE;
            break;
        default:
            break;
        }
        if (!skip_byref) buf[len++] = ELEMENT_TYPE_BYREF;
        len += make_type_sig( ref_type, buf + len );
        break;
    }
    case TYPE_ARRAY:
        buf[len++] = ELEMENT_TYPE_SZARRAY;
        len += make_type_sig( type_array_get_element_type(type), buf + len );
        break;

    case TYPE_INTERFACE:
        buf[len++] = ELEMENT_TYPE_OBJECT;
        break;

    case TYPE_DELEGATE:
    case TYPE_RUNTIMECLASS:
        buf[len++] = ELEMENT_TYPE_CLASS;
        len += encode_int( typedef_or_ref(TABLE_TYPEREF, type->md.ref), buf + 1 );
        break;

    case TYPE_ENUM:
    case TYPE_STRUCT:
        buf[len++] = ELEMENT_TYPE_VALUETYPE;
        len += encode_int( typedef_or_ref(TABLE_TYPEREF, type->md.ref), buf + 1 );
        break;

    case TYPE_BASIC:
        buf[len++] = map_basic_type( type_basic_get_type(type), type_basic_get_sign(type) );
        break;

    default:
        fprintf( stderr, "Unhandled type %u.\n", type_get_type( type ) );
        exit( 1 );
    }
    return len;
}

static BOOL is_retval( const var_t *arg )
{
    const type_t *type = arg->declspec.type;

    /* array return values are encoded as out parameters even if the retval attribute is present */
    if (!is_attr( arg->attrs, ATTR_RETVAL ) || type_get_type( type ) == TYPE_ARRAY) return FALSE;
    return TRUE;
}

static UINT make_method_sig( const var_t *method, BYTE *buf, BOOL is_static )
{
    const var_t *arg;
    const var_list_t *arg_list = type_function_get_args( method->declspec.type );
    UINT len = 3;

    buf[0] = is_static ? SIG_TYPE_DEFAULT : SIG_TYPE_HASTHIS;
    buf[1] = 0;
    buf[2] = ELEMENT_TYPE_VOID;

    if (!arg_list) return 3;

    /* add return value first */
    LIST_FOR_EACH_ENTRY( arg, arg_list, var_t, entry )
    {
        const type_t *type;

        if (!is_retval( arg )) continue;
        type = type_pointer_get_ref_type( arg->declspec.type ); /* retval must be a pointer */
        len = make_type_sig( type, buf + 2 ) + 2;
    }

    /* add remaining parameters */
    LIST_FOR_EACH_ENTRY( arg, arg_list, var_t, entry )
    {
        if (is_size_param( arg, arg_list ) || is_retval( arg ) ) continue;
        len += make_type_sig( arg->declspec.type, buf + len );
        buf[1]++;
    }
    return len;
}

static UINT make_property_sig( const var_t *method, BYTE *buf, BOOL is_static )
{
    const var_t *arg;
    const var_list_t *arg_list = type_function_get_args( method->declspec.type );
    UINT len = 3;

    buf[0] = is_static ? SIG_TYPE_PROPERTY : SIG_TYPE_HASTHIS | SIG_TYPE_PROPERTY;
    buf[1] = 0;
    buf[2] = ELEMENT_TYPE_VOID;

    LIST_FOR_EACH_ENTRY( arg, arg_list, var_t, entry )
    {
        const type_t *type;

        if (!is_retval( arg )) continue;
        type = type_pointer_get_ref_type( arg->declspec.type ); /* retval must be a pointer */
        len = make_type_sig( type, buf + 2 ) + 2;
    }

    return len;
}

static UINT make_activation_sig( const var_t *method, BYTE *buf )
{
    const var_t *arg;
    UINT len = 3;

    buf[0] = SIG_TYPE_HASTHIS;
    buf[1] = 0;
    buf[2] = ELEMENT_TYPE_VOID;

    if (method) LIST_FOR_EACH_ENTRY( arg, type_function_get_args(method->declspec.type), var_t, entry )
    {
        if (is_retval( arg )) continue;
        len += make_type_sig( arg->declspec.type, buf + len );
        buf[1]++;
    }

    return len;
}

static UINT make_composition_sig( const var_t *method, BYTE *buf )
{
    const var_t *arg;
    UINT len = 3, count = 0;

    buf[0] = SIG_TYPE_HASTHIS;
    buf[1] = 0;
    buf[2] = ELEMENT_TYPE_VOID;

    if (method) LIST_FOR_EACH_ENTRY( arg, type_function_get_args(method->declspec.type), var_t, entry ) count++;

    if (method) assert( count >= 3 );

    if (count > 3) LIST_FOR_EACH_ENTRY( arg, type_function_get_args(method->declspec.type), var_t, entry )
    {
        if (--count < 3) break; /* omit last 3 standard composition args */
        len += make_type_sig( arg->declspec.type, buf + len );
        buf[1]++;
    }

    return len;
}

static UINT make_deprecated_sig( UINT token, BYTE *buf )
{
    UINT len = 5;

    buf[0] = SIG_TYPE_HASTHIS;
    buf[1] = 4;
    buf[2] = ELEMENT_TYPE_VOID;
    buf[3] = ELEMENT_TYPE_STRING;
    buf[4] = ELEMENT_TYPE_VALUETYPE;
    len += encode_int( token, buf + 5 );
    buf[len++] = ELEMENT_TYPE_U4;
    buf[len++] = ELEMENT_TYPE_STRING;

    return len;
}

static UINT make_contract_value( const attr_t *attr, BYTE *buf )
{
    const expr_t *expr = attr->u.pval;
    const type_t *contract = expr->u.var->declspec.type;
    char *name = format_namespace( contract->namespace, "", ".", contract->name, NULL );
    UINT version = expr->ref->u.integer.value, len = strlen( name );

    buf[0] = 1;
    buf[1] = 0;
    buf[2] = len;
    memcpy( buf + 3, name, len );
    len += 3;
    memcpy( buf + len, &version, sizeof(version) );
    len += sizeof(version);
    buf[len++] = 0;
    buf[len++] = 0;

    free( name );
    return len;
}

static UINT make_version_value( const attr_t *attr, BYTE *buf )
{
    const version_t *version;
    UINT value;

    if (attr && (version = attr->u.pval)) value = (version->major << 16) | version->minor;
    else value = 1;

    buf[0] = 1;
    buf[1] = 0;
    memcpy( buf + 2, &value, sizeof(value) );
    buf[6] = buf[7] = 0;
    return 8;
}

static attr_t *get_attr( const attr_list_t *list, enum attr_type attr_type )
{
    attr_t *attr;
    if (list) LIST_FOR_EACH_ENTRY( attr, list, attr_t, entry )
    {
        if (attr->type == attr_type ) return attr;
    }
    return NULL;
}

static void add_contract_attr_step1( const type_t *type )
{
    UINT assemblyref, scope, typeref, typeref_type, class, sig_size;
    BYTE sig[32];
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_CONTRACT ))) return;

    add_assemblyref_row( 0x200, 0, add_string("windowscontracts") );
    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );

    scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
    typeref_type = add_typeref_row( scope, add_string("Type"), add_string("System") );

    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("ContractVersionAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref );
    sig_size = make_member_sig( typedef_or_ref(TABLE_TYPEREF, typeref_type), sig );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

static void add_contract_attr_step2( const type_t *type )
{
    UINT parent, attr_type, value_size;
    BYTE value[MAX_NAME + sizeof(UINT) + 5];
    const attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_CONTRACT ))) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    value_size = make_contract_value( attr, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

static void add_version_attr_step1( const type_t *type )
{
    static const BYTE sig[] = { SIG_TYPE_HASTHIS, 1, ELEMENT_TYPE_VOID, ELEMENT_TYPE_U4 };
    UINT assemblyref, scope, typeref, class;
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_VERSION )) && is_attr( type->attrs, ATTR_CONTRACT )) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );

    typeref = add_typeref_row( scope, add_string("VersionAttribute"), add_string("Windows.Foundation.Metadata") );
    class = memberref_parent( TABLE_TYPEREF, typeref );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

static void add_version_attr_step2( const type_t *type )
{
    UINT parent, attr_type, value_size;
    BYTE value[8];
    const attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_VERSION )) && is_attr( type->attrs, ATTR_CONTRACT )) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    value_size = make_version_value( attr, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

static void add_flags_attr_step1( const type_t *type )
{
    static const BYTE sig[] = { SIG_TYPE_HASTHIS, 0, ELEMENT_TYPE_VOID };
    UINT scope, typeref, class;
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_FLAGS ))) return;

    scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
    typeref = add_typeref_row( scope, add_string("FlagsAttribute"), add_string("System") );
    class = memberref_parent( TABLE_TYPEREF, typeref );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

static void add_flags_attr_step2( const type_t *type )
{
    static const BYTE value[] = { 0x01, 0x00, 0x00, 0x00 };
    UINT parent, attr_type;
    const attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_FLAGS ))) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) );
}

static void add_enum_type_step1( type_t *type )
{
    UINT name, namespace, scope, typeref;

    name = add_name( type, &namespace );

    scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
    typeref = add_typeref_row( scope, add_string("Enum"), add_string("System") );
    type->md.extends = typedef_or_ref( TABLE_TYPEREF, typeref );
    type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace );

    add_version_attr_step1( type );
    add_contract_attr_step1( type );
    add_flags_attr_step1( type );
}

static void add_enum_type_step2( type_t *type )
{
    BYTE sig_value[] = { SIG_TYPE_FIELD, ELEMENT_TYPE_I4 };
    UINT name, namespace, field, parent, sig_size;
    BYTE sig_field[32];
    const var_t *var;

    if (is_attr( type->attrs, ATTR_FLAGS )) sig_value[1] = ELEMENT_TYPE_U4;

    name = add_name( type, &namespace );

    field = add_field_row( FIELD_ATTR_PRIVATE | FIELD_ATTR_SPECIALNAME | FIELD_ATTR_RTSPECIALNAME,
                           add_string("value__"), add_blob(sig_value, sizeof(sig_value)) );

    type->md.def = add_typedef_row( TYPE_ATTR_PUBLIC | TYPE_ATTR_SEALED | TYPE_ATTR_UNKNOWN, name, namespace,
                                    type->md.extends, field, 1 );

    sig_size = make_field_value_sig( typedef_or_ref(TABLE_TYPEREF, type->md.ref), sig_field );

    LIST_FOR_EACH_ENTRY( var, type_enum_get_values(type), const var_t, entry )
    {
        int val = var->eval->u.integer.value;

        field = add_field_row( FIELD_ATTR_PUBLIC | FIELD_ATTR_LITERAL | FIELD_ATTR_STATIC | FIELD_ATTR_HASDEFAULT,
                               add_string(var->name), add_blob(sig_field, sig_size) );
        parent = has_constant( TABLE_FIELD, field );
        add_constant_row( sig_value[1], parent, add_blob((const BYTE *)&val, sizeof(val)) );
    }

    add_version_attr_step2( type );
    add_contract_attr_step2( type );
    add_flags_attr_step2( type );
}

static void add_struct_type_step1( type_t *type )
{
    UINT name, namespace, scope, typeref;
    const var_t *var;

    name = add_name( type, &namespace );
    scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );

    LIST_FOR_EACH_ENTRY( var, type_struct_get_fields(type), const var_t, entry )
    {
        type_t *field_type = var->declspec.type;
        if (field_type->name && !strcmp( field_type->name, "GUID" ))
            field_type->md.ref = add_typeref_row( scope, add_string("Guid"), add_string("System") );
    }

    typeref = add_typeref_row( scope, add_string("ValueType"), add_string("System") );
    type->md.extends = typedef_or_ref( TABLE_TYPEREF, typeref );
    type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace );

    add_contract_attr_step1( type );
}

static void add_struct_type_step2( type_t *type )
{
    UINT name, namespace, field, flags, sig_size, first_field = 0;
    const var_t *var;
    BYTE sig[32];

    name = add_name( type, &namespace );

    LIST_FOR_EACH_ENTRY( var, type_struct_get_fields(type), const var_t, entry )
    {
        sig_size = make_struct_field_sig( var, sig );
        field = add_field_row( FIELD_ATTR_PUBLIC, add_string(var->name), add_blob(sig, sig_size) );
        if (!first_field) first_field = field;
    }

    flags = TYPE_ATTR_PUBLIC | TYPE_ATTR_SEQUENTIALLAYOUT | TYPE_ATTR_SEALED | TYPE_ATTR_UNKNOWN;
    type->md.def = add_typedef_row( flags, name, namespace, type->md.extends, first_field, 0 );

    add_contract_attr_step2( type );
}

static void add_uuid_attr_step1( const type_t *type )
{
    static const BYTE sig[] =
        { SIG_TYPE_HASTHIS, 11, ELEMENT_TYPE_VOID, ELEMENT_TYPE_U4, ELEMENT_TYPE_U2, ELEMENT_TYPE_U2,
          ELEMENT_TYPE_U1, ELEMENT_TYPE_U1, ELEMENT_TYPE_U1, ELEMENT_TYPE_U1, ELEMENT_TYPE_U1, ELEMENT_TYPE_U1,
          ELEMENT_TYPE_U1, ELEMENT_TYPE_U1 };
    UINT assemblyref, scope, typeref, class;
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_UUID ))) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("GuidAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

static void add_uuid_attr_step2( const type_t *type )
{
    const struct uuid *uuid;
    BYTE value[sizeof(*uuid) + 4] = { 0x01 };
    UINT parent, attr_type;
    const attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_UUID ))) return;

    uuid = attr->u.pval;
    memcpy( value + 2, uuid, sizeof(*uuid) );

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) );
}

static UINT make_exclusiveto_value( const attr_t *attr, BYTE *buf )
{
    const type_t *type = attr->u.pval;
    char *name = format_namespace( type->namespace, "", ".", type->name, NULL );
    UINT len = strlen( name );

    buf[0] = 1;
    buf[1] = 0;
    buf[2] = len;
    memcpy( buf + 3, name, len );
    len += 3;
    buf[len++] = 0;
    buf[len++] = 0;

    free( name );
    return len;
}

static void add_exclusiveto_attr_step1( const type_t *type )
{
    UINT assemblyref, scope, typeref, typeref_type, class, sig_size;
    BYTE sig[32];
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_EXCLUSIVETO ))) return;

    scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
    typeref_type = add_typeref_row( scope, add_string("Type"), add_string("System") );

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("ExclusiveToAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref );
    sig_size = make_member_sig2( ELEMENT_TYPE_CLASS, typedef_or_ref(TABLE_TYPEREF, typeref_type), sig );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

static void add_exclusiveto_attr_step2( const type_t *type )
{
    UINT parent, attr_type, value_size;
    BYTE value[MAX_NAME + 5];
    const attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_EXCLUSIVETO ))) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    value_size = make_exclusiveto_value( attr, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

static UINT make_overload_value( const char *name, BYTE *buf )
{
    UINT len = strlen( name );

    buf[0] = 1;
    buf[1] = 0;
    buf[2] = len;
    memcpy( buf + 3, name, len );
    len += 3;
    buf[len++] = 0;
    buf[len++] = 0;

    return len;
}

static void add_overload_attr_step1( const var_t *method )
{
    static const BYTE sig[] = { SIG_TYPE_HASTHIS, 1, ELEMENT_TYPE_VOID, ELEMENT_TYPE_STRING };
    UINT assemblyref, scope, typeref, class;
    attr_t *attr;

    if (!(attr = get_attr( method->attrs, ATTR_OVERLOAD ))) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("OverloadAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

static void add_overload_attr_step2( const var_t *method )
{
    const type_t *type = method->declspec.type;
    UINT parent, attr_type, value_size;
    BYTE value[MAX_NAME + 5];
    const attr_t *attr;

    if (!(attr = get_attr( method->attrs, ATTR_OVERLOAD ))) return;

    parent = has_customattribute( TABLE_METHODDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    value_size = make_overload_value( method->name, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

static void add_default_overload_attr_step1( const var_t *method )
{
    static const BYTE sig[] = { SIG_TYPE_HASTHIS, 0, ELEMENT_TYPE_VOID };
    UINT assemblyref, scope, typeref, class;
    attr_t *attr;

    if (!(attr = get_attr( method->attrs, ATTR_DEFAULT_OVERLOAD )) || !is_attr( method->attrs, ATTR_OVERLOAD )) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("DefaultOverloadAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

static void add_default_overload_attr_step2( const var_t *method )
{
    static const BYTE value[] = { 0x01, 0x00, 0x00, 0x00 };
    const type_t *type = method->declspec.type;
    UINT parent, attr_type;
    const attr_t *attr;

    if (!(attr = get_attr( method->attrs, ATTR_DEFAULT_OVERLOAD )) || !is_attr( method->attrs, ATTR_OVERLOAD )) return;

    parent = has_customattribute( TABLE_METHODDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) );
}

static UINT make_deprecated_value( const attr_t *attr, BYTE **ret_buf )
{
    static const BYTE zero[] = { 0x00, 0x00, 0x00, 0x00 }, one[] = { 0x01, 0x00, 0x00, 0x00 };
    const expr_t *expr = attr->u.pval;
    const type_t *type = expr->ext2->u.var->declspec.type;
    const char *text = expr->ref->u.sval;
    const char *kind = expr->u.ext->u.sval;
    BYTE encoded[4];
    UINT len, version, len_text = strlen( text ), len_encoded = encode_int( len_text, encoded );
    BYTE *buf = xmalloc( 2 + len_encoded + len_text + 6 + MAX_NAME + 5 );
    char *contract;

    buf[0] = 1;
    buf[1] = 0;
    memcpy( buf + 2, encoded, len_encoded );
    len = 2 + len_encoded;
    memcpy( buf + len, text, len_text );
    len += len_text;
    if (!strcmp( kind, "remove" )) memcpy( buf + len, one, sizeof(one) );
    else memcpy( buf + len, zero, sizeof(zero) );
    len += 4;

    version = expr->ext2->ref->u.integer.value;
    memcpy( buf + len, &version, sizeof(version) );
    len += sizeof(version);

    contract = format_namespace( type->namespace, "", ".", type->name, NULL );
    len_text = strlen( contract );
    buf[len++] = len_text;
    memcpy( buf + len, contract, len_text );
    free( contract );
    len += len_text;
    buf[len++] = 0;
    buf[len++] = 0;

    *ret_buf = buf;
    return len;
}

static void add_deprecated_attr_step1( const var_t *method )
{
    UINT assemblyref, scope, typeref_type, typeref, class, sig_size;
    BYTE sig[32];
    attr_t *attr;

    if (!(attr = get_attr( method->attrs, ATTR_DEPRECATED ))) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref_type = add_typeref_row( scope, add_string("DeprecationType"), add_string("Windows.Foundation.Metadata") );
    typeref = add_typeref_row( scope, add_string("DeprecatedAttribute"), add_string("Windows.Foundation.Metadata") );

    sig_size = make_deprecated_sig( typedef_or_ref(TABLE_TYPEREF, typeref_type), sig );
    class = memberref_parent( TABLE_TYPEREF, typeref );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

static void add_deprecated_attr_step2( const var_t *method )
{
    const type_t *type = method->declspec.type;
    UINT parent, attr_type, value_size;
    BYTE *value;
    const attr_t *attr;

    if (!(attr = get_attr( method->attrs, ATTR_DEPRECATED ))) return;

    parent = has_customattribute( TABLE_METHODDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    value_size = make_deprecated_value( attr, &value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
    free( value );
}

static void add_method_params_step1( var_list_t *arg_list )
{
    var_t *arg;

    if (!arg_list) return;

    LIST_FOR_EACH_ENTRY( arg, arg_list, var_t, entry )
    {
        type_t *type = arg->declspec.type;

        if (is_size_param( arg, arg_list )) continue;
        if (type_get_type( type ) == TYPE_POINTER) type = type_pointer_get_ref_type( type );
        if (type->name && !strcmp( type->name, "EventRegistrationToken" ))
        {
            UINT assemblyref, scope;

            assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
            scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
            type = type_get_real_type( type );
            type->md.ref = add_typeref_row( scope, add_string("EventRegistrationToken"), add_string("Windows.Foundation") );
        }
    }
}

static void add_runtimeclass_type_step1( type_t * );

static void add_interface_type_step1( type_t *type )
{
    const statement_t *stmt;
    UINT name, namespace;
    type_t *class;

    name = add_name( type, &namespace );

    type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace );

    add_exclusiveto_attr_step1( type );

    if ((class = type->details.iface->runtime_class)) add_runtimeclass_type_step1( class );

    add_contract_attr_step1( type );
    add_uuid_attr_step1( type );

    STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(type) )
    {
        const var_t *method = stmt->u.var;

        add_method_params_step1( type_function_get_args(method->declspec.type) );

        add_overload_attr_step1( method );
        add_default_overload_attr_step1( method );
        add_deprecated_attr_step1( method );
    }
}

static UINT get_param_attrs( const var_t *arg )
{
    UINT attrs = 0;

    if (is_attr( arg->attrs, ATTR_IN )) attrs |= PARAM_ATTR_IN;
    if (is_attr( arg->attrs, ATTR_OUT )) attrs |= PARAM_ATTR_OUT;
    if (is_attr( arg->attrs, ATTR_OPTIONAL )) attrs |= PARAM_ATTR_OPTIONAL;

    return attrs ? attrs : PARAM_ATTR_IN;
}

static UINT add_method_params_step2( var_list_t *arg_list )
{
    UINT first = 0, row, seq = 1;
    var_t *arg;

    if (!arg_list) return 0;

    LIST_FOR_EACH_ENTRY( arg, arg_list, var_t, entry )
    {
        if (is_retval( arg ))
        {
            first = add_param_row( 0, 0, add_string(arg->name) );
            break;
        }
    }

    LIST_FOR_EACH_ENTRY( arg, arg_list, var_t, entry )
    {
        if (is_size_param( arg, arg_list) || is_retval( arg )) continue;
        row = add_param_row( get_param_attrs(arg), seq++, add_string(arg->name) );
        if (!first) first = row;
    }

    return first;
}

static char *get_method_name( const var_t *method )
{
    const char *overload;

    if (is_attr( method->attrs, ATTR_PROPGET )) return strmake( "get_%s", method->name );
    else if (is_attr( method->attrs, ATTR_PROPPUT )) return strmake( "put_%s", method->name );
    else if (is_attr( method->attrs, ATTR_EVENTADD )) return strmake( "add_%s", method->name );
    else if (is_attr( method->attrs, ATTR_EVENTREMOVE )) return strmake( "remove_%s", method->name );

    if ((overload = get_attrp( method->attrs, ATTR_OVERLOAD ))) return strmake( "%s", overload );
    return strmake( "%s", method->name );
}

static BOOL is_special_method( const var_t *method )
{
    if (is_attr( method->attrs, ATTR_PROPGET )  || is_attr( method->attrs, ATTR_PROPPUT ) ||
        is_attr( method->attrs, ATTR_EVENTADD ) || is_attr( method->attrs, ATTR_EVENTREMOVE )) return TRUE;
    return FALSE;
}

static BOOL is_static_iface( const type_t *class, const type_t *iface )
{
    const attr_t *attr;

    if (!class || !class->attrs) return FALSE;

    LIST_FOR_EACH_ENTRY( attr, class->attrs, const attr_t, entry )
    {
        const expr_t *value = attr->u.pval;

        if (attr->type != ATTR_STATIC) continue;
        if (value->u.var->declspec.type == iface) return TRUE;
    }

    return FALSE;
}

static UINT get_method_attrs( const type_t *class, const type_t *iface, const var_t *method, UINT *flags )
{
    UINT attrs = METHOD_ATTR_PUBLIC | METHOD_ATTR_HIDEBYSIG;

    if (!class)
    {
        *flags = 0;
        attrs |= METHOD_ATTR_ABSTRACT | METHOD_ATTR_VIRTUAL | METHOD_ATTR_NEWSLOT;
    }
    else
    {
        *flags = METHOD_IMPL_RUNTIME;
        if (is_static_iface( class, iface )) attrs |= METHOD_ATTR_STATIC;
        else attrs |= METHOD_ATTR_VIRTUAL | METHOD_ATTR_NEWSLOT | METHOD_ATTR_FINAL;
    }

    if (is_special_method( method )) attrs |= METHOD_ATTR_SPECIALNAME;
    return attrs;
}

static void add_propget_method( const type_t *class, const type_t *iface, const var_t *method )
{
    UINT sig_size, property, paramlist, flags, attrs = get_method_attrs( class, iface, method, &flags );
    char *name = get_method_name( method );
    type_t *type = method->declspec.type;
    BYTE sig[256];

    if (class) property = type->md.class_property;
    else property = type->md.iface_property;

    paramlist = add_method_params_step2( type_function_get_args(type) );
    sig_size = make_method_sig( method, sig, is_static_iface(class, iface) );

    type->md.def = add_methoddef_row( flags, attrs, add_string(name), add_blob(sig, sig_size), paramlist );
    add_methodsemantics_row( METHOD_SEM_GETTER, type->md.def, has_semantics(TABLE_PROPERTY, property) );
    free( name );
}

static const var_t *find_propget_method( const type_t *iface, const char *name )
{
    const statement_t *stmt;

    STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
    {
        const var_t *method = stmt->u.var;
        if (is_attr( method->attrs, ATTR_PROPGET ) && !strcmp( method->name, name )) return method;
    }
    return NULL;
}

static void add_propput_method( const type_t *class, const type_t *iface, const var_t *method )
{
    const var_t *propget = find_propget_method( iface, method->name );
    UINT sig_size, paramlist, property, flags, attrs = get_method_attrs( class, iface, method, &flags );
    char *name = get_method_name( method );
    type_t *type = method->declspec.type;
    BYTE sig[256];

    paramlist = add_method_params_step2( type_function_get_args(method->declspec.type) );
    sig_size = make_method_sig( method, sig, is_static_iface(class, iface) );

    type->md.def = add_methoddef_row( flags, attrs, add_string(name), add_blob(sig, sig_size), paramlist );
    free( name );

    /* add propget method first if not already added */
    if (class)
    {
        if (!propget->declspec.type->md.class_property) add_propget_method( class, iface, propget );
        property = type->md.class_property = propget->declspec.type->md.class_property;
    }
    else
    {
        if (!propget->declspec.type->md.iface_property) add_propget_method( class, iface, propget );
        property = type->md.iface_property = propget->declspec.type->md.iface_property;
    }

    add_methodsemantics_row( METHOD_SEM_SETTER, type->md.def, has_semantics(TABLE_PROPERTY, property) );
}

static void add_eventadd_method( const type_t *class, const type_t *iface, const var_t *method )
{
    UINT event, sig_size, paramlist, flags, attrs = get_method_attrs( class, iface, method, &flags );
    char *name = get_method_name( method );
    type_t *type = method->declspec.type;
    BYTE sig[256];

    if (class) event = type->md.class_event;
    else event = type->md.iface_event;

    paramlist = add_method_params_step2( type_function_get_args(type) );
    sig_size = make_method_sig( method, sig, is_static_iface(class, iface) );

    type->md.def = add_methoddef_row( flags, attrs, add_string(name), add_blob(sig, sig_size), paramlist );
    free( name );

    add_methodsemantics_row( METHOD_SEM_ADDON, type->md.def, has_semantics(TABLE_EVENT, event) );
}

static const var_t *find_eventadd_method( const type_t *iface, const char *name )
{
    const statement_t *stmt;

    STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
    {
        const var_t *method = stmt->u.var;
        if (is_attr( method->attrs, ATTR_EVENTADD ) && !strcmp( method->name, name )) return method;
    }
    return NULL;
}

static void add_eventremove_method( const type_t *class, const type_t *iface, const var_t *method )
{
    const var_t *eventadd = find_eventadd_method( iface, method->name );
    UINT event, sig_size, paramlist, flags, attrs = get_method_attrs( class, iface, method, &flags );
    char *name = get_method_name( method );
    type_t *type = method->declspec.type;
    BYTE sig[256];

    paramlist = add_method_params_step2( type_function_get_args(type) );
    sig_size = make_method_sig( method, sig, is_static_iface(class, iface) );

    type->md.def = add_methoddef_row( flags, attrs, add_string(name), add_blob(sig, sig_size), paramlist );
    free( name );

    /* add eventadd method first if not already added */
    if (class)
    {
        if (!eventadd->declspec.type->md.class_event) add_eventadd_method( class, iface, eventadd );
        event = type->md.class_event = eventadd->declspec.type->md.class_event;
    }
    else
    {
        if (!eventadd->declspec.type->md.iface_event) add_eventadd_method( class, iface, eventadd );
        event = type->md.iface_event = eventadd->declspec.type->md.iface_event;
    }

    add_methodsemantics_row( METHOD_SEM_REMOVEON, type->md.def, has_semantics(TABLE_EVENT, event) );
}

static void add_regular_method( const type_t *class, const type_t *iface, const var_t *method )
{
    UINT paramlist, sig_size, flags, attrs = get_method_attrs( class, iface, method, &flags );
    char *name = get_method_name( method );
    type_t *type = method->declspec.type;
    BYTE sig[256];

    paramlist = add_method_params_step2( type_function_get_args(type) );
    sig_size = make_method_sig( method, sig, is_static_iface(class, iface) );

    type->md.def = add_methoddef_row( flags, attrs, add_string(name), add_blob(sig, sig_size), paramlist );
    free( name );
}

static void add_property( type_t *class, type_t *iface, const var_t *method )
{
    UINT sig_size;
    type_t *type = method->declspec.type;
    BYTE sig[256];

    if (!is_attr( method->attrs, ATTR_PROPGET )) return;

    sig_size = make_property_sig( method, sig, is_static_iface(class, iface) );
    if (class)
    {
        type->md.class_property = add_property_row( 0, add_string(method->name), add_blob(sig, sig_size) );
        if (!class->md.propertymap) class->md.propertymap = add_propertymap_row( class->md.def, type->md.class_property );
    }
    else
    {
        type->md.iface_property = add_property_row( 0, add_string(method->name), add_blob(sig, sig_size) );
        if (!iface->md.propertymap) iface->md.propertymap = add_propertymap_row( iface->md.def, type->md.iface_property );
    }
}

static void add_event( type_t *class, type_t *iface, const var_t *method )
{
    UINT event_type = 0;
    type_t *type = method->declspec.type;
    var_t *arg;

    if (!is_attr( method->attrs, ATTR_EVENTADD )) return;

    LIST_FOR_EACH_ENTRY( arg, type_function_get_args(type), var_t, entry )
    {
        type_t *arg_type = arg->declspec.type;

        arg_type = type_pointer_get_ref_type( arg_type ); /* first arg must be a delegate pointer */
        event_type = typedef_or_ref( TABLE_TYPEREF, arg_type->md.ref );
        break;
    }

    if (class)
    {
        type->md.class_event = add_event_row( 0, add_string(method->name), event_type );
        if (!class->md.eventmap) class->md.eventmap = add_eventmap_row( class->md.def, type->md.class_event );
    }
    else
    {
        type->md.iface_event = add_event_row( 0, add_string(method->name), event_type );
        if (!iface->md.eventmap) iface->md.eventmap = add_eventmap_row( iface->md.def, type->md.iface_event );
    }
}

static void add_method( type_t *class, type_t *iface, const var_t *method )
{
    if (is_attr( method->attrs, ATTR_PROPGET )) add_propget_method( class, iface, method );
    else if (is_attr( method->attrs, ATTR_PROPPUT )) add_propput_method( class, iface, method );
    else if (is_attr( method->attrs, ATTR_EVENTADD )) add_eventadd_method( class, iface, method );
    else if (is_attr( method->attrs, ATTR_EVENTREMOVE )) add_eventremove_method( class, iface, method );
    else add_regular_method( class, iface, method );
}

static void add_runtimeclass_type_step2( type_t *type );

static void add_interface_type_step2( type_t *type )
{
    UINT name, namespace, interface, flags = TYPE_ATTR_INTERFACE | TYPE_ATTR_ABSTRACT | TYPE_ATTR_UNKNOWN;
    const typeref_list_t *require_list = type_iface_get_requires( type );
    const typeref_t *require;
    const statement_t *stmt;
    type_t *class;

    name = add_name( type, &namespace );

    if (!is_attr( type->attrs, ATTR_EXCLUSIVETO )) flags |= TYPE_ATTR_PUBLIC;
    type->md.def = add_typedef_row( flags, name, namespace, 0, 0, 0 );

    if (require_list) LIST_FOR_EACH_ENTRY( require, require_list, typeref_t, entry )
    {
        interface = typedef_or_ref( TABLE_TYPEREF, require->type->md.ref );
        add_interfaceimpl_row( type->md.def, interface );
    }

    STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(type) )
    {
        const var_t *method = stmt->u.var;

        add_property( NULL, type, method );
        add_event( NULL, type, method );
        add_method( NULL, type, method );

        add_deprecated_attr_step2( method );
        add_default_overload_attr_step2( method );
        add_overload_attr_step2( method );
    }

    if ((class = type->details.iface->runtime_class)) add_runtimeclass_type_step2( class );

    add_contract_attr_step2( type );
    add_uuid_attr_step2( type );
    add_exclusiveto_attr_step2( type );
}

static void add_contractversion_attr_step1( const type_t *type )
{
    static const BYTE sig[] = { SIG_TYPE_HASTHIS, 1, ELEMENT_TYPE_VOID, ELEMENT_TYPE_U4 };
    UINT assemblyref, scope, typeref, class;
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_CONTRACTVERSION ))) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("ContractVersionAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

static void add_contractversion_attr_step2( const type_t *type )
{
    UINT parent, attr_type, value_size;
    BYTE value[8];
    const attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_CONTRACTVERSION ))) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    value_size = make_version_value( attr, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

static void add_apicontract_attr_step1( const type_t *type )
{
    static const BYTE sig[] = { SIG_TYPE_HASTHIS, 0, ELEMENT_TYPE_VOID };
    UINT assemblyref, scope, typeref, class;
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_APICONTRACT ))) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("ApiContractAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

static void add_apicontract_attr_step2( const type_t *type )
{
    static const BYTE value[] = { 0x01, 0x00, 0x00, 0x00 };
    UINT parent, attr_type;
    const attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_APICONTRACT ))) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) );
}

static void add_apicontract_type_step1( type_t *type )
{
    UINT name, namespace, scope, typeref;

    name = add_name( type, &namespace );

    scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
    typeref = add_typeref_row( scope, add_string("ValueType"), add_string("System") );
    type->md.extends = typedef_or_ref( TABLE_TYPEREF, typeref );
    type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace );

    add_contractversion_attr_step1( type );
    add_apicontract_attr_step1( type );
}

static void add_apicontract_type_step2( type_t *type )
{
    UINT name, namespace, flags = TYPE_ATTR_PUBLIC | TYPE_ATTR_SEQUENTIALLAYOUT | TYPE_ATTR_SEALED | TYPE_ATTR_UNKNOWN;

    name = add_name( type, &namespace );

    type->md.def = add_typedef_row( flags, name, namespace, type->md.extends, 0, 1 );

    add_contractversion_attr_step2( type );
    add_apicontract_attr_step2( type );
}

static void add_runtimeclass_type_step1( type_t *type )
{
    UINT name, namespace;

    if (type->md.ref) return;

    name = add_name( type, &namespace );
    type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace );
}

static void add_default_attr( UINT interfaceimpl_ref )
{
    static const BYTE sig[] = { SIG_TYPE_HASTHIS, 0, ELEMENT_TYPE_VOID };
    static const BYTE value[] = { 0x01, 0x00, 0x00, 0x00 };
    UINT assemblyref, scope, typeref, class, memberref, parent, attr_type;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("DefaultAttribute"), add_string("Windows.Foundation.Metadata") );
    class = memberref_parent( TABLE_TYPEREF, typeref );
    memberref = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );

    parent = has_customattribute( TABLE_INTERFACEIMPL, interfaceimpl_ref );
    attr_type = customattribute_type( TABLE_MEMBERREF, memberref );
    add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) );
}

static void add_method_impl( const type_t *class, const type_t *iface, const var_t *method )
{
    UINT parent, memberref, body, decl, sig_size;
    char *name = get_method_name( method );
    type_t *type = method->declspec.type;
    BYTE sig[256];

    parent = memberref_parent( TABLE_TYPEREF, iface->md.ref );
    sig_size = make_method_sig( method, sig, FALSE );

    memberref = add_memberref_row( parent, add_string(name), add_blob(sig, sig_size) );
    free( name );

    body = methoddef_or_ref( TABLE_METHODDEF, type->md.def );
    decl = methoddef_or_ref( TABLE_MEMBERREF, memberref );

    add_methodimpl_row( class->md.def, body, decl );
}

static void add_method_contract_attrs( const type_t *class, const type_t *iface, const type_t *method )
{
    UINT parent, attr_type, value_size;
    BYTE value[MAX_NAME + sizeof(UINT) + 5];
    const attr_t *attr = get_attr( iface->attrs, ATTR_CONTRACT );

    parent = has_customattribute( TABLE_METHODDEF, method->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    value_size = make_contract_value( get_attr(class->attrs, ATTR_CONTRACT), value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );

    if (method->md.class_property)
    {
        parent = has_customattribute( TABLE_PROPERTY, method->md.class_property );
        add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
    }

    if (method->md.class_event)
    {
        parent = has_customattribute( TABLE_EVENT, method->md.class_event );
        add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
    }
}

static UINT make_static_value( const expr_t *attr, BYTE *buf )
{
    const expr_t *contract = attr->ref;
    const type_t *type_iface = attr->u.var->declspec.type, *type_contract = contract->u.var->declspec.type;
    char *name_iface = format_namespace( type_iface->namespace, "", ".", type_iface->name, NULL );
    char *name_contract = format_namespace( type_contract->namespace, "", ".", type_contract->name, NULL );
    UINT len_iface = strlen( name_iface ), len_contract = strlen( name_contract );
    BYTE *ptr = buf;

    ptr[0] = 1;
    ptr[1] = 0;
    ptr[2] = len_iface;
    memcpy( ptr + 3, name_iface, len_iface );
    ptr += len_iface + 3;
    ptr[0] = ptr[1] = 0;

    ptr += 2;
    ptr[0] = 1;
    ptr[1] = 0;
    ptr[2] = len_contract;
    memcpy( ptr + 3, name_contract, len_contract );
    ptr += len_contract + 3;
    ptr[0] = ptr[1] = 0;

    free( name_iface );
    free( name_contract );
    return len_iface + len_contract + 10;
}

static void add_static_attr_step1( const type_t *type )
{
    UINT assemblyref, scope, typeref, typeref_type, class, sig_size;
    BYTE sig[32];
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_STATIC ))) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("StaticAttribute"), add_string("Windows.Foundation.Metadata") );

    scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
    typeref_type = add_typeref_row( scope, add_string("Type"), add_string("System") );

    class = memberref_parent( TABLE_TYPEREF, typeref );
    sig_size = make_member_sig3( typedef_or_ref(TABLE_TYPEREF, typeref_type), sig );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

static void add_static_attr_step2( const type_t *type )
{
    const attr_t *attr;

    if (type->attrs) LIST_FOR_EACH_ENTRY_REV( attr, type->attrs, const attr_t, entry )
    {
        UINT parent, attr_type, value_size;
        BYTE value[MAX_NAME * 2 + 10];

        if (attr->type != ATTR_STATIC) continue;

        parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
        attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
        value_size = make_static_value( attr->u.pval, value );
        add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
    }
}

static UINT make_activatable_value( const expr_t *attr, BYTE *buf )
{
    char *name_iface = NULL, *name_contract;
    const type_t *type_iface, *type_contract;
    UINT version, len_iface = 0, len_contract, len_extra = 5;
    BYTE *ptr = buf;

    if (attr->type == EXPR_MEMBER)
    {
        type_iface = attr->u.var->declspec.type;
        name_iface = format_namespace( type_iface->namespace, "", ".", type_iface->name, NULL );
        len_iface = strlen( name_iface );

        type_contract = attr->ref->u.var->declspec.type;
        version = attr->ref->ref->u.integer.value;
    }
    else
    {
        type_contract = attr->u.var->declspec.type;
        version = attr->ref->u.integer.value;
    }

    name_contract = format_namespace( type_contract->namespace, "", ".", type_contract->name, NULL );
    len_contract = strlen( name_contract );

    if (len_iface)
    {
        ptr[0] = 1;
        ptr[1] = 0;
        ptr[2] = len_iface;
        memcpy( ptr + 3, name_iface, len_iface );
        ptr += len_iface + 3;
        ptr[0] = ptr[1] = 0;
        ptr += 2;
        len_extra += 5;
    }

    ptr[0] = 1;
    ptr[1] = 0;
    memcpy( ptr + 2, &version, sizeof(version) );
    ptr += sizeof(version) + 2;

    ptr[0] = len_contract;
    memcpy( ptr + 1, name_contract, len_contract );
    ptr += len_contract + 1;
    ptr[0] = ptr[1] = 0;

    free( name_iface );
    free( name_contract );
    return len_iface + sizeof(version) + len_contract + len_extra;
}

static void add_activatable_attr_step1( const type_t *type )
{
    static const BYTE sig_default[] = { SIG_TYPE_HASTHIS, 2, ELEMENT_TYPE_VOID, ELEMENT_TYPE_U4, ELEMENT_TYPE_STRING };
    attr_t *attr;

    if (type->attrs) LIST_FOR_EACH_ENTRY_REV( attr, type->attrs, attr_t, entry )
    {
        UINT assemblyref, scope, typeref, typeref_type, class, sig_size;
        const expr_t *value = attr->u.pval;
        BYTE sig[32];

        if (attr->type != ATTR_ACTIVATABLE) continue;

        assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
        scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
        typeref = add_typeref_row( scope, add_string("ActivatableAttribute"), add_string("Windows.Foundation.Metadata") );

        scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
        typeref_type = add_typeref_row( scope, add_string("Type"), add_string("System") );

        class = memberref_parent( TABLE_TYPEREF, typeref );

        if (value->type == EXPR_MEMBER)
            sig_size = make_member_sig3( typedef_or_ref(TABLE_TYPEREF, typeref_type), sig );
        else
        {
            memcpy( sig, sig_default, sizeof(sig_default) );
            sig_size = sizeof(sig_default);
        }

        attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
    }
}

static void add_activatable_attr_step2( const type_t *type )
{
    const attr_t *attr;

    if (type->attrs) LIST_FOR_EACH_ENTRY_REV( attr, type->attrs, const attr_t, entry )
    {
        UINT parent, attr_type, value_size;
        BYTE value[MAX_NAME * 2 + sizeof(UINT) + 10];

        if (attr->type != ATTR_ACTIVATABLE) continue;

        parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
        attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
        value_size = make_activatable_value( attr->u.pval, value );
        add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
    }
}

static UINT make_threading_value( const attr_t *attr, BYTE *buf )
{
    UINT value, model = attr->u.ival;

    switch (model)
    {
    case THREADING_SINGLE:
        value = 1;
        break;
    case THREADING_FREE:
        value = 2;
        break;
    case THREADING_BOTH:
        value = 3;
        break;
    default:
        fprintf( stderr, "Unhandled model %u.\n", model );
        return 0;
    }

    buf[0] = 1;
    buf[1] = 0;
    memcpy( buf + 2, &value, sizeof(value) );
    buf[6] = buf[7] = 0;
    return 8;
}

static void add_threading_attr_step1( const type_t *type )
{
    UINT assemblyref, scope, typeref, typeref_attr, class, sig_size;
    BYTE sig[32];
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_THREADING ))) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("ThreadingModel"), add_string("Windows.Foundation.Metadata") );

    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref_attr = add_typeref_row( scope, add_string("ThreadingAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref_attr );
    sig_size = make_member_sig2( ELEMENT_TYPE_VALUETYPE, typedef_or_ref(TABLE_TYPEREF, typeref), sig );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

static void add_threading_attr_step2( const type_t *type )
{
    UINT parent, attr_type, value_size;
    BYTE value[8];
    const attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_THREADING ))) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    value_size = make_threading_value( attr, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

static UINT make_marshalingbehavior_value( const attr_t *attr, BYTE *buf )
{
    UINT marshaling = attr->u.ival;

    buf[0] = 1;
    buf[1] = 0;
    memcpy( buf + 2, &marshaling, sizeof(marshaling) );
    buf[6] = buf[7] = 0;
    return 8;
}

static void add_marshalingbehavior_attr_step1( const type_t *type )
{
    UINT assemblyref, scope, typeref, typeref_attr, class, sig_size;
    BYTE sig[32];
    attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_MARSHALING_BEHAVIOR ))) return;

    assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref = add_typeref_row( scope, add_string("MarshalingType"), add_string("Windows.Foundation.Metadata") );

    scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
    typeref_attr = add_typeref_row( scope, add_string("MarshalingBehaviorAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref_attr );
    sig_size = make_member_sig2( ELEMENT_TYPE_VALUETYPE, typedef_or_ref(TABLE_TYPEREF, typeref), sig );
    attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

static void add_marshalingbehavior_attr_step2( const type_t *type )
{
    UINT parent, attr_type, value_size;
    BYTE value[8];
    const attr_t *attr;

    if (!(attr = get_attr( type->attrs, ATTR_MARSHALING_BEHAVIOR ))) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
    value_size = make_marshalingbehavior_value( attr, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

static UINT make_composable_value( const expr_t *attr, BYTE *buf )
{
    char *name_iface, *name_contract;
    const expr_t *contract = attr->ref;
    const type_t *type_iface = attr->u.var->declspec.type;
    const type_t *type_contract = contract->u.var->declspec.type;
    UINT access_type = 1, contract_version = contract->ref->u.integer.value;
    UINT len_iface, len_contract;
    BYTE *ptr = buf;

    name_iface = format_namespace( type_iface->namespace, "", ".", type_iface->name, NULL );
    len_iface = strlen( name_iface );

    name_contract = format_namespace( type_contract->namespace, "", ".", type_contract->name, NULL );
    len_contract = strlen( name_contract );

    ptr[0] = 1;
    ptr[1] = 0;
    ptr[2] = len_iface;
    memcpy( ptr + 3, name_iface, len_iface );
    ptr += len_iface + 3;

    if (is_attr( attr->u.var->attrs, ATTR_PUBLIC)) access_type = 2;
    memcpy( ptr, &access_type, sizeof(access_type) );
    ptr += sizeof(access_type);

    memcpy( ptr, &contract_version, sizeof(contract_version) );
    ptr += sizeof(contract_version);

    ptr[0] = len_contract;
    memcpy( ptr + 1, name_contract, len_contract );
    ptr += len_contract + 1;
    ptr[0] = ptr[1] = 0;

    free( name_iface );
    free( name_contract );
    return len_iface + sizeof(access_type) + sizeof(contract_version) + len_contract + 6;
}

static void add_composable_attr_step1( const type_t *type )
{
    attr_t *attr;

    if (type->attrs) LIST_FOR_EACH_ENTRY( attr, type->attrs, attr_t, entry )
    {
        UINT assemblyref, scope, typeref, typeref_attr, typeref_type, class, sig_size;
        BYTE sig[64];

        if (attr->type != ATTR_COMPOSABLE) continue;

        scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
        typeref_type = add_typeref_row( scope, add_string("Type"), add_string("System") );

        assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
        scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );
        typeref = add_typeref_row( scope, add_string("CompositionType"), add_string("Windows.Foundation.Metadata") );
        typeref_attr = add_typeref_row( scope, add_string("ComposableAttribute"), add_string("Windows.Foundation.Metadata") );

        class = memberref_parent( TABLE_TYPEREF, typeref_attr );
        sig_size = make_member_sig4( typedef_or_ref(TABLE_TYPEREF, typeref_type), typedef_or_ref(TABLE_TYPEREF, typeref), sig );
        attr->md_member = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
    }
}

static void add_composable_attr_step2( const type_t *type )
{
    const attr_t *attr;

    if (type->attrs) LIST_FOR_EACH_ENTRY( attr, type->attrs, const attr_t, entry )
    {
        UINT parent, attr_type, value_size;
        BYTE value[MAX_NAME + sizeof(UINT) * 2 + 6];

        if (attr->type != ATTR_COMPOSABLE) continue;

        parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
        attr_type = customattribute_type( TABLE_MEMBERREF, attr->md_member );
        value_size = make_composable_value( attr->u.pval, value );
        add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
    }
}

static void add_member_interfaces( type_t *class )
{
    const typeref_list_t *iface_list = type_runtimeclass_get_ifaces( class );
    const typeref_t *iface;

    if (iface_list) LIST_FOR_EACH_ENTRY( iface, iface_list, typeref_t, entry )
    {
        UINT interface = typedef_or_ref( TABLE_TYPEREF, iface->type->md.ref );
        UINT interfaceimpl_ref = add_interfaceimpl_row( class->md.def, interface );
        const statement_t *stmt;

        if (is_attr( iface->attrs, ATTR_DEFAULT )) add_default_attr( interfaceimpl_ref );

        /* add properties in reverse order like midlrt */
        STATEMENTS_FOR_EACH_FUNC_REV( stmt, type_iface_get_stmts(iface->type) )
        {
            const var_t *method = stmt->u.var;

            add_property( class, iface->type, method );
        }

        STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface->type) )
        {
            const var_t *method = stmt->u.var;

            add_event( class, iface->type, method );
            add_method( class, iface->type, method );
            add_method_impl( class, iface->type, method );
            add_method_contract_attrs( class, iface->type, method->declspec.type );
        }
    }
}

static void add_static_interfaces( type_t *class )
{
    const attr_t *attr;

    if (class->attrs) LIST_FOR_EACH_ENTRY( attr, class->attrs, const attr_t, entry )
    {
        const expr_t *value = attr->u.pval;
        const statement_t *stmt;
        type_t *iface;

        if (attr->type != ATTR_STATIC) continue;

        iface = value->u.var->declspec.type;

        STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
        {
            const var_t *method = stmt->u.var;

            add_property( class, iface, method );
            add_event( class, iface, method );
            add_method( class, iface, method );
            add_method_contract_attrs( class, iface, method->declspec.type );
        }
    }
}

static void add_activation_interfaces( const type_t *class )
{
    UINT flags = METHOD_ATTR_PUBLIC | METHOD_ATTR_HIDEBYSIG | METHOD_ATTR_SPECIALNAME | METHOD_ATTR_RTSPECIALNAME;
    const attr_t *attr, *contract_attr = get_attr( class->attrs, ATTR_CONTRACT );

    if (class->attrs) LIST_FOR_EACH_ENTRY_REV( attr, class->attrs, const attr_t, entry )
    {
        UINT methoddef, parent, attr_type, value_size, paramlist = 0, sig_size;
        BYTE value[MAX_NAME + sizeof(UINT) + 5], sig[256];
        const expr_t *activatable = attr->u.pval;
        const type_t *iface = NULL;
        const var_t *method = NULL, *arg;
        const statement_t *stmt;

        if (attr->type != ATTR_ACTIVATABLE) continue;

        /* interface is optional */
        if (activatable->type == EXPR_MEMBER) iface = activatable->u.var->declspec.type;

        if (iface) STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
        {
            UINT seq = 1, row;

            method = stmt->u.var;

            LIST_FOR_EACH_ENTRY( arg, type_function_get_args(method->declspec.type), var_t, entry )
            {
                if (is_retval( arg )) continue;
                row = add_param_row( get_param_attrs(arg), seq++, add_string(arg->name) );
                if (!paramlist) paramlist = row;
            }
            break;
        }

        sig_size = make_activation_sig( method, sig );
        methoddef = add_methoddef_row( METHOD_IMPL_RUNTIME, flags, add_string(".ctor"), add_blob(sig, sig_size), paramlist );

        parent = has_customattribute( TABLE_METHODDEF, methoddef );
        attr_type = customattribute_type( TABLE_MEMBERREF, contract_attr->md_member );
        value_size = make_contract_value( contract_attr, value );
        add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
    }
}

static void add_composition_interfaces( const type_t *class )
{
    UINT flags = METHOD_ATTR_FAMILY | METHOD_ATTR_HIDEBYSIG | METHOD_ATTR_SPECIALNAME | METHOD_ATTR_RTSPECIALNAME;
    const attr_t *attr, *contract_attr = get_attr( class->attrs, ATTR_CONTRACT );

    if (class->attrs) LIST_FOR_EACH_ENTRY_REV( attr, class->attrs, const attr_t, entry )
    {
        UINT methoddef, parent, attr_type, value_size, paramlist = 0, sig_size;
        BYTE value[MAX_NAME + sizeof(UINT) + 5], sig[256];
        const expr_t *composable = attr->u.pval;
        const var_t *method = NULL, *arg;
        const statement_t *stmt;
        const type_t *iface;

        if (attr->type != ATTR_COMPOSABLE) continue;

        iface = composable->u.var->declspec.type;

        STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
        {
            UINT seq = 1, row, count = 0;

            method = stmt->u.var;

            LIST_FOR_EACH_ENTRY( arg, type_function_get_args(method->declspec.type), var_t, entry ) count++;

            if (count > 3) LIST_FOR_EACH_ENTRY( arg, type_function_get_args(method->declspec.type), var_t, entry )
            {
                if (--count < 3) break; /* omit last 3 standard composition args */
                row = add_param_row( get_param_attrs(arg), seq++, add_string(arg->name) );
                if (!paramlist) paramlist = row;
            }
            break;
        }

        sig_size = make_composition_sig( method, sig );
        methoddef = add_methoddef_row( METHOD_IMPL_RUNTIME, flags, add_string(".ctor"), add_blob(sig, sig_size), paramlist );

        parent = has_customattribute( TABLE_METHODDEF, methoddef );
        attr_type = customattribute_type( TABLE_MEMBERREF, contract_attr->md_member );
        value_size = make_contract_value( contract_attr, value );
        add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
    }
}

static void add_constructor_overload( const type_t *type )
{
    static const BYTE sig_default[] = { SIG_TYPE_HASTHIS, 0, ELEMENT_TYPE_VOID };
    static const BYTE sig_overload[] = { SIG_TYPE_HASTHIS, 1, ELEMENT_TYPE_VOID, ELEMENT_TYPE_STRING };
    UINT name, namespace;
    const attr_t *attr;

    if (type->attrs) LIST_FOR_EACH_ENTRY_REV( attr, type->attrs, const attr_t, entry )
    {
        const expr_t *value = attr->u.pval;

        if (attr->type == ATTR_COMPOSABLE || (attr->type == ATTR_ACTIVATABLE && value->type == EXPR_MEMBER))
        {
            UINT assemblyref, scope, typeref_default, typeref_overload, class;

            assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") );
            scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref );

            name = add_string( "DefaultOverloadAttribute" );
            namespace = add_string( "Windows.Foundation.Metadata" );
            typeref_default = add_typeref_row( scope, name, namespace );

            class = memberref_parent( TABLE_TYPEREF, typeref_default );
            add_memberref_row( class, add_string(".ctor"), add_blob(sig_default, sizeof(sig_default)) );

            name = add_string( "OverloadAttribute" );
            typeref_overload = add_typeref_row( scope, name, namespace );

            class = memberref_parent( TABLE_TYPEREF, typeref_overload );
            add_memberref_row( class, add_string(".ctor"), add_blob(sig_overload, sizeof(sig_overload)) );
            break;
        }
    }
}

static void add_runtimeclass_type_step2( type_t *type )
{
    const typeref_list_t *iface_list = type_runtimeclass_get_ifaces( type );
    UINT name, namespace, scope, extends, typeref, flags;

    if (type->md.def) return;

    name = add_name( type, &namespace );

    add_constructor_overload( type );

    scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
    typeref = add_typeref_row( scope, add_string("Object"), add_string("System") );
    extends = typedef_or_ref( TABLE_TYPEREF, typeref );

    flags = TYPE_ATTR_PUBLIC | TYPE_ATTR_UNKNOWN;
    if (!is_attr( type->attrs, ATTR_COMPOSABLE )) flags |= TYPE_ATTR_SEALED;
    if (!iface_list) flags |= TYPE_ATTR_ABSTRACT;

    type->md.def = add_typedef_row( flags, name, namespace, extends, 0, 0 );

    /* add contract first so activation/composition constructors can inherit it */
    add_contract_attr_step1( type );

    add_activation_interfaces( type );
    add_composition_interfaces( type );
    add_member_interfaces( type );
    add_static_interfaces( type );

    add_composable_attr_step1( type );
    add_static_attr_step1( type );
    add_activatable_attr_step1( type );
    add_threading_attr_step1( type );
    add_marshalingbehavior_attr_step1( type );

    add_contract_attr_step2( type );
    add_composable_attr_step2( type );
    add_static_attr_step2( type );
    add_activatable_attr_step2( type );
    add_threading_attr_step2( type );
    add_marshalingbehavior_attr_step2( type );
}

static void add_delegate_type_step1( type_t *type )
{
    UINT name, namespace, scope, typeref;

    name = add_name( type, &namespace );

    scope = resolution_scope( TABLE_ASSEMBLYREF, MSCORLIB_ROW );
    typeref = add_typeref_row( scope, add_string("MulticastDelegate"), add_string("System") );
    type->md.extends = typedef_or_ref( TABLE_TYPEREF, typeref );
    type->md.ref = add_typeref_row( resolution_scope(TABLE_MODULE, MODULE_ROW), name, namespace );

    add_version_attr_step1( type );
    add_contract_attr_step1( type );
    add_uuid_attr_step1( type );
}

static void add_delegate_type_step2( type_t *type )
{
    static const BYTE sig_ctor[] = { SIG_TYPE_HASTHIS, 2, ELEMENT_TYPE_VOID, ELEMENT_TYPE_OBJECT, ELEMENT_TYPE_I };
    UINT name, namespace, methoddef, flags, paramlist;
    const type_t *iface = type_delegate_get_iface( type );
    const statement_t *stmt;

    name = add_name( type, &namespace );

    flags = METHOD_ATTR_RTSPECIALNAME | METHOD_ATTR_SPECIALNAME | METHOD_ATTR_HIDEBYSIG | METHOD_ATTR_PRIVATE;
    methoddef = add_methoddef_row( METHOD_IMPL_RUNTIME, flags, add_string(".ctor"),
                                   add_blob(sig_ctor, sizeof(sig_ctor)), 0 );

    add_param_row( 0, 1, add_string("object") );
    add_param_row( 0, 2, add_string("method") );

    flags = METHOD_ATTR_SPECIALNAME | METHOD_ATTR_HIDEBYSIG | METHOD_ATTR_PUBLIC | METHOD_ATTR_VIRTUAL |
            METHOD_ATTR_NEWSLOT;

    STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
    {
        const var_t *method = stmt->u.var;
        UINT sig_size;
        BYTE sig[256];

        sig_size = make_method_sig( method, sig, FALSE );
        paramlist = add_method_params_step2( type_function_get_args(method->declspec.type) );

        add_methoddef_row( METHOD_IMPL_RUNTIME, flags, add_string("Invoke"), add_blob(sig, sig_size), paramlist );
        break;
    }
    type->md.def = add_typedef_row( TYPE_ATTR_PUBLIC | TYPE_ATTR_SEALED | TYPE_ATTR_UNKNOWN, name, namespace,
                                    type->md.extends, 0, methoddef );

    add_uuid_attr_step2( type );
    add_version_attr_step2( type );
    add_contract_attr_step2( type );
}

static void build_tables( const statement_list_t *stmt_list )
{
    const statement_t *stmt;

    /* Adding a type involves two passes: the first creates various references and the second
       uses those references to create the remaining rows. */

    LIST_FOR_EACH_ENTRY( stmt, stmt_list, const statement_t, entry )
    {
        type_t *type = stmt->u.type;

        if (stmt->type != STMT_TYPE) continue;

        switch (type->type_type)
        {
        case TYPE_ENUM:
            add_enum_type_step1( type );
            break;
        case TYPE_STRUCT:
            add_struct_type_step1( type );
            break;
        case TYPE_INTERFACE:
            if (type->signature && !strncmp( type->signature, "pinterface", 10 ))
            {
                fprintf( stderr, "Ingoring supported %s parameterized interface.\n", type->name );
                break;
            }
            add_interface_type_step1( type );
            break;
        case TYPE_APICONTRACT:
            add_apicontract_type_step1( type );
            break;
        case TYPE_RUNTIMECLASS:
            add_runtimeclass_type_step1( type );
            break;
        case TYPE_DELEGATE:
            add_delegate_type_step1( type );
            break;
        default:
            fprintf( stderr, "Unhandled type %u name '%s'.\n", type->type_type, type->name );
            break;
        }
    }

    LIST_FOR_EACH_ENTRY( stmt, stmt_list, const statement_t, entry )
    {
        type_t *type = stmt->u.type;

        if (stmt->type != STMT_TYPE) continue;

        switch (type->type_type)
        {
        case TYPE_ENUM:
            add_enum_type_step2( type );
            break;
        case TYPE_STRUCT:
            add_struct_type_step2( type );
            break;
        case TYPE_INTERFACE:
            if (type->signature && !strncmp( type->signature, "pinterface", 10 ))
            {
                fprintf( stderr, "Ingoring supported %s parameterized interface.\n", type->name );
                break;
            }
            add_interface_type_step2( type );
            break;
        case TYPE_APICONTRACT:
            add_apicontract_type_step2( type );
            break;
        case TYPE_RUNTIMECLASS:
            add_runtimeclass_type_step2( type );
            break;
        case TYPE_DELEGATE:
            add_delegate_type_step2( type );
            break;
        default:
            break;
        }
    }
}

static void build_table_stream( const statement_list_t *stmts )
{
    static const GUID guid = { 0x9ddc04c6, 0x04ca, 0x04cc, { 0x52, 0x85, 0x4b, 0x50, 0xb2, 0x60, 0x1d, 0xa8 } };
    static const BYTE token[] = { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 };
    static const USHORT space = 0x20;
    char *ptr;
    UINT i;

    add_string( "" );
    add_userstring( NULL, 0 );
    add_userstring( &space, sizeof(space) );
    add_blob( NULL, 0 );

    assembly_name = xstrdup( metadata_name );
    if ((ptr = strrchr( assembly_name, '.' ))) *ptr = 0;

    add_typedef_row( 0, add_string("<Module>"), 0, 0, 1, 1 );
    add_assembly_row( add_string(assembly_name) );
    add_module_row( add_string(metadata_name), add_guid(&guid) );
    add_assemblyref_row( 0, add_blob(token, sizeof(token)), add_string("mscorlib") );

    build_tables( stmts );

    for (i = 0; i < TABLE_MAX; i++) if (tables[i].count) tables_header.valid |= (1ull << i);

    if (strings.offset >> 16) tables_header.heap_sizes |= LARGE_STRING_HEAP;
    if (guids.offset >> 16) tables_header.heap_sizes |= LARGE_GUID_HEAP;
    if (blobs.offset >> 16) tables_header.heap_sizes |= LARGE_BLOB_HEAP;

    add_bytes( &tables_disk, (const BYTE *)&tables_header, sizeof(tables_header) );

    for (i = 0; i < TABLE_MAX; i++)
        if (tables[i].count) add_bytes( &tables_disk, (const BYTE *)&tables[i].count, sizeof(tables[i].count) );

    serialize_module_table();
    serialize_typeref_table();
    serialize_typedef_table();
    serialize_field_table();
    serialize_methoddef_table();
    serialize_param_table();
    serialize_interfaceimpl_table();
    serialize_memberref_table();
    serialize_constant_table();
    serialize_customattribute_table();
    serialize_eventmap_table();
    serialize_event_table();
    serialize_propertymap_table();
    serialize_property_table();
    serialize_methodsemantics_table();
    serialize_methodimpl_table();
    serialize_assembly_table();
    serialize_assemblyref_table();
}

static void build_streams( const statement_list_t *stmts )
{
    static const BYTE pad[4];
    UINT i, len, offset = sizeof(metadata_header);

    build_table_stream( stmts );

    len = (tables_disk.offset + 3) & ~3;
    add_bytes( &tables_disk, pad, len - tables_disk.offset );

    streams[WINMD_STREAM_TABLE].data_size = tables_disk.offset;
    streams[WINMD_STREAM_TABLE].data = tables_disk.ptr;

    len = (strings.offset + 3) & ~3;
    add_bytes( &strings, pad, len - strings.offset );

    streams[WINMD_STREAM_STRING].data_size = strings.offset;
    streams[WINMD_STREAM_STRING].data = strings.ptr;

    len = (userstrings.offset + 3) & ~3;
    add_bytes( &userstrings, pad, len - userstrings.offset );

    streams[WINMD_STREAM_USERSTRING].data_size = userstrings.offset;
    streams[WINMD_STREAM_USERSTRING].data = userstrings.ptr;

    len = (blobs.offset + 3) & ~3;
    add_bytes( &blobs, pad, len - blobs.offset );

    streams[WINMD_STREAM_BLOB].data_size = blobs.offset;
    streams[WINMD_STREAM_BLOB].data = blobs.ptr;

    streams[WINMD_STREAM_GUID].data_size = guids.offset;
    streams[WINMD_STREAM_GUID].data = guids.ptr;

    for (i = 0; i < WINMD_STREAM_MAX; i++)
    {
        if (!streams[i].data_size) continue;
        offset += streams[i].header_size;
    }
    for (i = 0; i < WINMD_STREAM_MAX; i++)
    {
        if (!streams[i].data_size) continue;
        streams[i].data_offset = offset;
        offset += streams[i].data_size;
    }
}

static void write_streams( void )
{
    UINT i;
    for (i = 0; i < WINMD_STREAM_MAX; i++)
    {
        if (!streams[i].data_size) continue;
        put_data( streams[i].data, streams[i].data_size );
    }
}

void write_metadata( const statement_list_t *stmts )
{
    static const BYTE pad[FILE_ALIGNMENT];
    UINT image_size, file_size, i;

    if (!do_metadata || !winrt_mode) return;

    build_streams( stmts );

    image_size = FILE_ALIGNMENT + sizeof(cor_header) + 8 + sizeof(metadata_header);
    for (i = 0; i < WINMD_STREAM_MAX; i++) image_size += streams[i].header_size + streams[i].data_size;

    init_output_buffer();

    write_headers( image_size );
    write_streams( );

    file_size = (image_size + FILE_ALIGNMENT - 1) & ~(FILE_ALIGNMENT - 1);
    put_data( pad, file_size - image_size );

    flush_output_buffer( metadata_name );
}
