예제 #1
0
        private static void GetAttributeParentNameAndKind(
            MetadataReader metadataReader,
            EntityHandle token,
            out string name,
            out SymbolKind kind
            )
        {
            switch (token.Kind)
            {
            case HandleKind.AssemblyDefinition:
                name = null;
                kind = SymbolKind.Assembly;
                return;

            case HandleKind.TypeDefinition:
                name = metadataReader.GetString(
                    metadataReader.GetTypeDefinition((TypeDefinitionHandle)token).Name
                    );
                kind = SymbolKind.NamedType;
                return;

            case HandleKind.MethodDefinition:
                name = metadataReader.GetString(
                    metadataReader.GetMethodDefinition((MethodDefinitionHandle)token).Name
                    );
                kind = SymbolKind.Method;
                return;

            default:
                throw TestExceptionUtilities.UnexpectedValue(token.Kind);
            }
        }
예제 #2
0
        public void ExplicitFieldLayout_OnBackingField()
        {
            string source =
                @"
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Explicit)]
public struct A
{
    [field: FieldOffset(4)]
    int a { get; set; }

    [field: FieldOffset(8)]
    event Action b;
}
";

            CompileAndVerify(
                source,
                assemblyValidator: (assembly) =>
            {
                var reader = assembly.GetMetadataReader();
                Assert.Equal(2, reader.GetTableRowCount(TableIndex.FieldLayout));

                foreach (var fieldHandle in reader.FieldDefinitions)
                {
                    var field   = reader.GetFieldDefinition(fieldHandle);
                    string name = reader.GetString(field.Name);

                    int expectedOffset;
                    switch (name)
                    {
                    case "<a>k__BackingField":
                        expectedOffset = 4;
                        break;

                    case "b":
                        expectedOffset = 8;
                        break;

                    default:
                        throw TestExceptionUtilities.UnexpectedValue(name);
                    }

                    Assert.Equal(expectedOffset, field.GetOffset());
                }
            }
                );
        }
예제 #3
0
        public void ReadingFromMetadata()
        {
            // the image is missing a record in ClassLayout table
            using (var module = ModuleMetadata.CreateFromImage(TestResources.MetadataTests.Invalid.ClassLayout))
            {
                var reader = module.Module.GetMetadataReader();

                foreach (var typeHandle in reader.TypeDefinitions)
                {
                    var  type = reader.GetTypeDefinition(typeHandle);
                    var  name = reader.GetString(type.Name);
                    uint classSize, packingSize;
                    bool hasClassLayout = type.GetTypeLayout(out classSize, out packingSize);

                    TypeLayout layout = module.Module.GetTypeLayout(typeHandle);
                    switch (name)
                    {
                    case "<Module>":
                        Assert.False(hasClassLayout);
                        Assert.Equal(default(TypeLayout), layout);
                        break;

                    case "S1":
                        // invalid size/pack value
                        Assert.True(hasClassLayout);
                        Assert.Equal(0xaaaaaaaaU, classSize);
                        Assert.Equal(0xffffU, packingSize);
                        Assert.Equal(new TypeLayout(LayoutKind.Sequential, 0, 0), layout);
                        break;

                    case "S2":
                        // invalid size value
                        Assert.True(hasClassLayout);
                        Assert.Equal(0xffffffffU, classSize);
                        Assert.Equal(0x0002U, packingSize);
                        Assert.Equal(new TypeLayout(LayoutKind.Explicit, 0, 2), layout);
                        break;

                    case "S3":
                        Assert.True(hasClassLayout);
                        Assert.Equal(1U, classSize);
                        Assert.Equal(2U, packingSize);
                        Assert.Equal(new TypeLayout(LayoutKind.Sequential, size: 1, alignment: 2), layout);
                        break;

                    case "S4":
                        Assert.True(hasClassLayout);
                        Assert.Equal(0x12345678U, classSize);
                        Assert.Equal(0U, packingSize);
                        Assert.Equal(new TypeLayout(LayoutKind.Sequential, size: 0x12345678, alignment: 0), layout);
                        break;

                    case "S5":
                        // doesn't have layout
                        Assert.False(hasClassLayout);
                        Assert.Equal(new TypeLayout(LayoutKind.Sequential, size: 0, alignment: 0), layout);
                        break;

                    default:
                        throw TestExceptionUtilities.UnexpectedValue(name);
                    }
                }
            }
        }
예제 #4
0
        public void ReadingFromMetadata()
        {
            // the image is missing a record in ClassLayout table
            using (var module = ModuleMetadata.CreateFromImage(TestResources.MetadataTests.Invalid.ClassLayout))
            {
                var reader = module.Module.GetMetadataReader();

                foreach (var typeHandle in reader.TypeDefinitions)
                {
                    var type = reader.GetTypeDefinition(typeHandle);
                    var name = reader.GetString(type.Name);

                    bool badLayout = false;
                    System.Reflection.Metadata.TypeLayout mdLayout;
                    try
                    {
                        mdLayout = type.GetLayout();
                    }
                    catch (BadImageFormatException)
                    {
                        badLayout = true;
                        mdLayout  = default(System.Reflection.Metadata.TypeLayout);
                    }

                    bool       hasClassLayout = !mdLayout.IsDefault;
                    TypeLayout layout         = module.Module.GetTypeLayout(typeHandle);
                    switch (name)
                    {
                    case "<Module>":
                        Assert.False(hasClassLayout);
                        Assert.Equal(default(TypeLayout), layout);
                        Assert.False(badLayout);
                        break;

                    case "S1":
                    case "S2":
                        // invalid size/pack value
                        Assert.False(hasClassLayout);
                        Assert.True(badLayout);
                        break;

                    case "S3":
                        Assert.True(hasClassLayout);
                        Assert.Equal(1, mdLayout.Size);
                        Assert.Equal(2, mdLayout.PackingSize);
                        Assert.Equal(new TypeLayout(LayoutKind.Sequential, size: 1, alignment: 2), layout);
                        Assert.False(badLayout);
                        break;

                    case "S4":
                        Assert.True(hasClassLayout);
                        Assert.Equal(unchecked ((int)0x12345678), mdLayout.Size);
                        Assert.Equal(0, mdLayout.PackingSize);
                        Assert.Equal(new TypeLayout(LayoutKind.Sequential, size: 0x12345678, alignment: 0), layout);
                        Assert.False(badLayout);
                        break;

                    case "S5":
                        // doesn't have layout
                        Assert.False(hasClassLayout);
                        Assert.Equal(new TypeLayout(LayoutKind.Sequential, size: 0, alignment: 0), layout);
                        Assert.False(badLayout);
                        break;

                    default:
                        throw TestExceptionUtilities.UnexpectedValue(name);
                    }
                }
            }
        }