/*
 * 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( BYTE value )
{
    add_bytes( &tables_disk, (const BYTE *)&value, sizeof(value) );
}

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

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
{
    USHORT 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
{
    USHORT 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;
    USHORT implflags;
    USHORT 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
{
    USHORT flags;
    USHORT 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
{
    BYTE type;
    BYTE 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;
    USHORT majorversion;
    USHORT minorversion;
    USHORT buildnumber;
    USHORT 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
{
    USHORT majorversion;
    USHORT minorversion;
    USHORT buildnumber;
    USHORT 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
{
    USHORT 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
{
    USHORT 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
{
    USHORT 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 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_attr( arg->attrs, ATTR_RETVAL )) 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_attr( arg->attrs, ATTR_RETVAL ) ) 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_attr( arg->attrs, ATTR_RETVAL )) 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_attr( arg->attrs, ATTR_RETVAL )) 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 type_t *type, BYTE *buf )
{
    const expr_t *attr = get_attrp( type->attrs, ATTR_CONTRACT );
    const type_t *contract = attr->u.var->declspec.type;
    char *name = format_namespace( contract->namespace, "", ".", contract->name, NULL );
    UINT version = attr->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 type_t *type, BYTE *buf )
{
    UINT version = get_attrv( type->attrs, ATTR_VERSION );

    buf[0] = 1;
    buf[1] = 0;
    buf[2] = is_attr( type->attrs, ATTR_VERSION ) ? 0 : 1;
    buf[3] = 0;
    memcpy( buf + 4, &version, sizeof(version) );
    return 8;
}

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

    if (!is_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 );
    type->md.member[MD_ATTR_CONTRACT] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

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

    if (!is_attr( type->attrs, ATTR_CONTRACT )) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_CONTRACT] );
    value_size = make_contract_value( type, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

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

    if (!is_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 );
    type->md.member[MD_ATTR_VERSION] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

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

    if (!is_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, type->md.member[MD_ATTR_VERSION] );
    value_size = make_version_value( type, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

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

    if (!is_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 );
    type->md.member[MD_ATTR_FLAGS] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

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

    if (!is_attr( type->attrs, ATTR_FLAGS )) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_FLAGS] );
    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( 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;

    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 );
    type->md.member[MD_ATTR_UUID] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

static void add_uuid_attr_step2( type_t *type )
{
    static const BYTE default_uuid[] =
        { 0xe7, 0x1f, 0xb5, 0x67, 0x6e, 0x38, 0x31, 0x5a, 0x8a, 0x1c, 0x89, 0x83, 0xc9, 0x49, 0x5c, 0x33 };
    const struct uuid *uuid = get_attrp( type->attrs, ATTR_UUID );
    BYTE value[sizeof(*uuid) + 4] = { 0x01 };
    UINT parent, attr_type;

    if (uuid) memcpy( value + 2, uuid, sizeof(*uuid) );
    else memcpy( value + 2, default_uuid, sizeof(default_uuid) );

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_UUID] );
    add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) );
}

static UINT make_exclusiveto_value( const type_t *type, BYTE *buf )
{
    const type_t *attr = get_attrp( type->attrs, ATTR_EXCLUSIVETO );
    char *name = format_namespace( attr->namespace, "", ".", attr->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( type_t *type )
{
    UINT assemblyref, scope, typeref, typeref_type, class, sig_size;
    BYTE sig[32];

    if (!is_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 );
    type->md.member[MD_ATTR_EXCLUSIVETO] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

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

    if (!is_attr( type->attrs, ATTR_EXCLUSIVETO )) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_EXCLUSIVETO] );
    value_size = make_exclusiveto_value( type, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

static UINT make_overload_value( const var_t *method, BYTE *buf )
{
    UINT len = strlen( method->name );

    buf[0] = 1;
    buf[1] = 0;
    buf[2] = len;
    memcpy( buf + 3, method->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;
    type_t *type = method->declspec.type;

    if (!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("OverloadAttribute"), add_string("Windows.Foundation.Metadata") );

    class = memberref_parent( TABLE_TYPEREF, typeref );
    type->md.member[MD_ATTR_OVERLOAD] = 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];

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

    parent = has_customattribute( TABLE_METHODDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_OVERLOAD] );
    value_size = make_overload_value( method, 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;
    type_t *type = method->declspec.type;

    if (!is_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 );
    type->md.member[MD_ATTR_DEFAULT_OVERLOAD] = 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;

    if (!is_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, type->md.member[MD_ATTR_DEFAULT_OVERLOAD] );
    add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) );
}

static UINT make_deprecated_value( const var_t *method, BYTE **ret_buf )
{
    static const BYTE zero[] = { 0x00, 0x00, 0x00, 0x00 }, one[] = { 0x01, 0x00, 0x00, 0x00 };
    const expr_t *attr = get_attrp( method->attrs, ATTR_DEPRECATED );
    const type_t *type = attr->ext2->u.var->declspec.type;
    const char *text = attr->ref->u.sval;
    const char *kind = attr->u.ext->u.sval;
    BYTE encoded[4];
    UINT len, 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;
    buf[len++] = 0;
    buf[len++] = 0;

    buf[len++] = 1;
    buf[len++] = 0;
    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;
    type_t *type = method->declspec.type;
    BYTE sig[32];

    if (!is_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 );
    type->md.member[MD_ATTR_DEPRECATED] = 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;

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

    parent = has_customattribute( TABLE_METHODDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_DEPRECATED] );
    value_size = make_deprecated_value( method, &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 (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_attr( arg->attrs, ATTR_RETVAL ))
        {
            first = add_param_row( 0, 0, add_string(arg->name) );
            break;
        }
    }

    LIST_FOR_EACH_ENTRY( arg, arg_list, var_t, entry )
    {
        if (is_attr( arg->attrs, ATTR_RETVAL )) 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 UINT make_contractversion_value( const type_t *type, BYTE *buf )
{
    UINT version = get_attrv( type->attrs, ATTR_CONTRACTVERSION ), len = 2 + sizeof(version);

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

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

    if (!is_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 );
    type->md.member[MD_ATTR_CONTRACTVERSION] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

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

    if (!is_attr( type->attrs, ATTR_CONTRACTVERSION )) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_CONTRACTVERSION] );
    value_size = make_contractversion_value( type, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

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

    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 );
    type->md.member[MD_ATTR_APICONTRACT] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) );
}

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

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_APICONTRACT] );
    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( const type_t *type, 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];

    parent = has_customattribute( TABLE_METHODDEF, method->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, iface->md.member[MD_ATTR_CONTRACT] );
    value_size = make_contract_value( class, 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( type_t *type )
{
    UINT assemblyref, scope, typeref, typeref_type, class, sig_size;
    BYTE sig[32];

    if (!is_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 );
    type->md.member[MD_ATTR_STATIC] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

static void add_static_attr_step2( 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, type->md.member[MD_ATTR_STATIC] );
        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( 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( 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 type_t *type, BYTE *buf )
{
    UINT value, model = get_attrv( type->attrs, ATTR_THREADING );

    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( type_t *type )
{
    UINT assemblyref, scope, typeref, typeref_attr, class, sig_size;
    BYTE sig[32];

    if (!is_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 );
    type->md.member[MD_ATTR_THREADING] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

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

    if (!is_attr( type->attrs, ATTR_THREADING )) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_THREADING] );
    value_size = make_threading_value( type, value );
    add_customattribute_row( parent, attr_type, add_blob(value, value_size) );
}

static UINT make_marshalingbehavior_value( const type_t *type, BYTE *buf )
{
    UINT marshaling = get_attrv( type->attrs, ATTR_MARSHALING_BEHAVIOR );

    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( type_t *type )
{
    UINT assemblyref, scope, typeref, typeref_attr, class, sig_size;
    BYTE sig[32];

    if (!is_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 );
    type->md.member[MD_ATTR_MARSHALINGBEHAVIOR] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) );
}

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

    if (!is_attr( type->attrs, ATTR_MARSHALING_BEHAVIOR )) return;

    parent = has_customattribute( TABLE_TYPEDEF, type->md.def );
    attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_MARSHALINGBEHAVIOR] );
    value_size = make_marshalingbehavior_value( type, 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( 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( 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( class, 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;

    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_attr( arg->attrs, ATTR_RETVAL )) 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, class->md.member[MD_ATTR_CONTRACT] );
        value_size = make_contract_value( class, 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;

    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, class->md.member[MD_ATTR_CONTRACT] );
        value_size = make_contract_value( class, 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 );
}
