Exemplo n.º 1
0
        private static void DecodeMarshalAsCustom(ref DecodeWellKnownAttributeArguments <TAttributeSyntax, TAttributeData, TAttributeLocation> arguments, CommonMessageProvider messageProvider)
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            ITypeSymbolInternal typeSymbol = null;
            string typeName      = null;
            string cookie        = null;
            bool   hasTypeName   = false;
            bool   hasTypeSymbol = false;
            bool   hasErrors     = false;

            int position = 1;

            foreach (var namedArg in arguments.Attribute.NamedArguments)
            {
                switch (namedArg.Key)
                {
                case "MarshalType":
                    typeName = namedArg.Value.DecodeValue <string>(SpecialType.System_String);
                    if (!MetadataHelpers.IsValidUnicodeString(typeName))
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    hasTypeName = true;     // even if MarshalType == null
                    break;

                case "MarshalTypeRef":
                    typeSymbol    = namedArg.Value.DecodeValue <ITypeSymbolInternal>(SpecialType.None);
                    hasTypeSymbol = true;     // even if MarshalTypeRef == null
                    break;

                case "MarshalCookie":
                    cookie = namedArg.Value.DecodeValue <string>(SpecialType.System_String);
                    if (!MetadataHelpers.IsValidUnicodeString(cookie))
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;
                    // other parameters ignored with no error
                }

                position++;
            }

            if (!hasTypeName && !hasTypeSymbol)
            {
                // MarshalType or MarshalTypeRef must be specified:
                messageProvider.ReportAttributeParameterRequired(arguments.Diagnostics, arguments.AttributeSyntaxOpt, "MarshalType", "MarshalTypeRef");
                hasErrors = true;
            }

            if (!hasErrors)
            {
                arguments.GetOrCreateData <TWellKnownAttributeData>().GetOrCreateData().SetMarshalAsCustom(hasTypeName ? (object)typeName : typeSymbol, cookie);
            }
        }
Exemplo n.º 2
0
        private static void DecodeMarshalAsComInterface(ref DecodeWellKnownAttributeArguments <TAttributeSyntax, TAttributeData, TAttributeLocation> arguments, UnmanagedType unmanagedType, CommonMessageProvider messageProvider)
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            int? parameterIndex = null;
            int  position       = 1;
            bool hasErrors      = false;

            foreach (var namedArg in arguments.Attribute.NamedArguments)
            {
                switch (namedArg.Key)
                {
                case "IidParameterIndex":
                    parameterIndex = namedArg.Value.DecodeValue <int>(SpecialType.System_Int32);
                    if (parameterIndex < 0 || parameterIndex > MarshalPseudoCustomAttributeData.MaxMarshalInteger)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;
                    // other parameters ignored with no error
                }

                position++;
            }

            if (!hasErrors)
            {
                arguments.GetOrCreateData <TWellKnownAttributeData>().GetOrCreateData().SetMarshalAsComInterface(unmanagedType, parameterIndex);
            }
        }
Exemplo n.º 3
0
        internal static void DecodeMethodImplAttribute <T, TAttributeSyntaxNode, TAttributeData, TAttributeLocation>(
            ref DecodeWellKnownAttributeArguments <TAttributeSyntaxNode, TAttributeData, TAttributeLocation> arguments,
            CommonMessageProvider messageProvider)
            where T : CommonMethodWellKnownAttributeData, new()
            where TAttributeSyntaxNode : SyntaxNode
            where TAttributeData : AttributeData
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            MethodImplOptions options;
            var attribute = arguments.Attribute;

            if (attribute.CommonConstructorArguments.Length == 1)
            {
                if (attribute.AttributeConstructor.Parameters[0].Type.SpecialType == SpecialType.System_Int16)
                {
                    options = (MethodImplOptions)attribute.CommonConstructorArguments[0].DecodeValue <short>(SpecialType.System_Int16);
                }
                else
                {
                    options = attribute.CommonConstructorArguments[0].DecodeValue <MethodImplOptions>(SpecialType.System_Enum);
                }

                // low two bits should only be set via MethodCodeType property
                if (((int)options & 3) != 0)
                {
                    messageProvider.ReportInvalidAttributeArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, 0, attribute);
                    options = options & ~(MethodImplOptions)3;
                }
            }
            else
            {
                options = default(MethodImplOptions);
            }

            MethodImplAttributes codeType = MethodImplAttributes.IL;
            int position = 1;

            foreach (var namedArg in attribute.CommonNamedArguments)
            {
                if (namedArg.Key == "MethodCodeType")
                {
                    var value = (MethodImplAttributes)namedArg.Value.DecodeValue <int>(SpecialType.System_Enum);
                    if (value < 0 || value > MethodImplAttributes.Runtime)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, attribute.AttributeClass, "MethodCodeType");
                    }
                    else
                    {
                        codeType = value;
                    }
                }

                position++;
            }

            arguments.GetOrCreateData <T>().SetMethodImplementation(arguments.Index, (MethodImplAttributes)options | codeType);
        }
        private static void DecodeMarshalAsFixedString(ref DecodeWellKnownAttributeArguments <TAttributeSyntax, TAttributeData, TAttributeLocation> arguments, CommonMessageProvider messageProvider)
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            int  elementCount = -1;
            int  position     = 1;
            bool hasErrors    = false;

            foreach (var namedArg in arguments.Attribute.NamedArguments)
            {
                switch (namedArg.Key)
                {
                case "SizeConst":
                    elementCount = namedArg.Value.DecodeValue <int>(SpecialType.System_Int32);
                    if (elementCount < 0 || elementCount > MarshalPseudoCustomAttributeData.MaxMarshalInteger)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;

                case "ArraySubType":
                case "SizeParamIndex":
                    messageProvider.ReportParameterNotValidForType(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position);
                    hasErrors = true;
                    break;

                    // other parameters ignored with no error
                }

                position++;
            }

            if (elementCount < 0)
            {
                // SizeConst must be specified:
                messageProvider.ReportAttributeParameterRequired(arguments.Diagnostics, arguments.AttributeSyntaxOpt, "SizeConst");
                hasErrors = true;
            }

            if (!hasErrors)
            {
                arguments.GetOrCreateData <TWellKnownAttributeData>().GetOrCreateData().SetMarshalAsFixedString(elementCount);
            }
        }
Exemplo n.º 5
0
        private static void DecodeMarshalAsSafeArray(ref DecodeWellKnownAttributeArguments <TAttributeSyntax, TAttributeData, TAttributeLocation> arguments, CommonMessageProvider messageProvider)
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            Cci.VarEnum?        elementTypeVariant = null;
            ITypeSymbolInternal elementTypeSymbol  = null;
            int  symbolIndex = -1;
            bool hasErrors   = false;

            int position = 1;

            foreach (var namedArg in arguments.Attribute.NamedArguments)
            {
                switch (namedArg.Key)
                {
                case "SafeArraySubType":
                    elementTypeVariant = namedArg.Value.DecodeValue <Cci.VarEnum>(SpecialType.System_Enum);
                    if (elementTypeVariant < 0 || (int)elementTypeVariant > MarshalPseudoCustomAttributeData.MaxMarshalInteger)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;

                case "SafeArrayUserDefinedSubType":
                    elementTypeSymbol = namedArg.Value.DecodeValue <ITypeSymbolInternal>(SpecialType.None);
                    symbolIndex       = position;
                    break;

                case "ArraySubType":
                case "SizeConst":
                case "SizeParamIndex":
                    messageProvider.ReportParameterNotValidForType(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position);
                    hasErrors = true;
                    break;
                    // other parameters ignored with no error
                }

                position++;
            }

            switch (elementTypeVariant)
            {
            case Cci.VarEnum.VT_DISPATCH:
            case Cci.VarEnum.VT_UNKNOWN:
            case Cci.VarEnum.VT_RECORD:
                // only these variants accept specification of user defined subtype
                break;

            default:
                if (elementTypeVariant != null && symbolIndex >= 0)
                {
                    messageProvider.ReportParameterNotValidForType(arguments.Diagnostics, arguments.AttributeSyntaxOpt, symbolIndex);
                    hasErrors = true;
                }
                else
                {
                    // type ignored:
                    elementTypeSymbol = null;
                }

                break;
            }

            if (!hasErrors)
            {
                arguments.GetOrCreateData <TWellKnownAttributeData>().GetOrCreateData().SetMarshalAsSafeArray(elementTypeVariant, elementTypeSymbol);
            }
        }
Exemplo n.º 6
0
        private static void DecodeMarshalAsArray(ref DecodeWellKnownAttributeArguments <TAttributeSyntax, TAttributeData, TAttributeLocation> arguments, CommonMessageProvider messageProvider, bool isFixed)
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            UnmanagedType?elementType    = null;
            int?          elementCount   = isFixed ? 1 : (int?)null;
            short?        parameterIndex = null;
            bool          hasErrors      = false;

            int position = 1;

            foreach (var namedArg in arguments.Attribute.NamedArguments)
            {
                switch (namedArg.Key)
                {
                // array:
                case "ArraySubType":
                    elementType = namedArg.Value.DecodeValue <UnmanagedType>(SpecialType.System_Enum);

                    // for some reason, Dev10 metadata writer disallows CustomMarshaler type as an element type of non-fixed arrays
                    if (!isFixed && elementType == Cci.Constants.UnmanagedType_CustomMarshaler ||
                        (int)elementType < 0 ||
                        (int)elementType > MarshalPseudoCustomAttributeData.MaxMarshalInteger)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;

                case "SizeConst":
                    elementCount = namedArg.Value.DecodeValue <int>(SpecialType.System_Int32);
                    if (elementCount < 0 || elementCount > MarshalPseudoCustomAttributeData.MaxMarshalInteger)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;

                case "SizeParamIndex":
                    if (isFixed)
                    {
                        goto case "SafeArraySubType";
                    }

                    parameterIndex = namedArg.Value.DecodeValue <short>(SpecialType.System_Int16);
                    if (parameterIndex < 0)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;

                case "SafeArraySubType":
                    messageProvider.ReportParameterNotValidForType(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position);
                    hasErrors = true;
                    break;
                    // other parameters ignored with no error
                }

                position++;
            }

            if (!hasErrors)
            {
                var data = arguments.GetOrCreateData <TWellKnownAttributeData>().GetOrCreateData();
                if (isFixed)
                {
                    data.SetMarshalAsFixedArray(elementType, elementCount);
                }
                else
                {
                    data.SetMarshalAsArray(elementType, elementCount, parameterIndex);
                }
            }
        }
Exemplo n.º 7
0
        internal static void DecodeStructLayoutAttribute <TTypeWellKnownAttributeData, TAttributeSyntaxNode, TAttributeData, TAttributeLocation>(
            ref DecodeWellKnownAttributeArguments <TAttributeSyntaxNode, TAttributeData, TAttributeLocation> arguments,
            CharSet defaultCharSet,
            int defaultAutoLayoutSize,
            CommonMessageProvider messageProvider)
            where TTypeWellKnownAttributeData : CommonTypeWellKnownAttributeData, new()
            where TAttributeSyntaxNode : SyntaxNode
            where TAttributeData : AttributeData
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            var attribute = arguments.Attribute;

            CharSet charSet   = (defaultCharSet != Cci.Constants.CharSet_None) ? defaultCharSet : CharSet.Ansi;
            int?    size      = null;
            int?    alignment = null;
            bool    hasErrors = false;

            LayoutKind kind = attribute.CommonConstructorArguments[0].DecodeValue <LayoutKind>(Microsoft.CodeAnalysis.SpecialType.System_Enum);

            switch (kind)
            {
            case LayoutKind.Auto:
            case LayoutKind.Explicit:
            case LayoutKind.Sequential:
                break;

            default:
                messageProvider.ReportInvalidAttributeArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, 0, attribute);
                hasErrors = true;
                break;
            }

            int position = 1;

            foreach (var namedArg in attribute.CommonNamedArguments)
            {
                switch (namedArg.Key)
                {
                case "CharSet":
                    charSet = namedArg.Value.DecodeValue <CharSet>(SpecialType.System_Enum);
                    switch (charSet)
                    {
                    case Cci.Constants.CharSet_None:
                        charSet = CharSet.Ansi;
                        break;

                    case CharSet.Ansi:
                    case Cci.Constants.CharSet_Auto:
                    case CharSet.Unicode:
                        break;

                    default:
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                        break;
                    }

                    break;

                case "Pack":
                    alignment = namedArg.Value.DecodeValue <int>(SpecialType.System_Int32);

                    // only powers of 2 less or equal to 128 are allowed:
                    if (alignment > 128 || (alignment & (alignment - 1)) != 0)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;

                case "Size":
                    size = namedArg.Value.DecodeValue <int>(Microsoft.CodeAnalysis.SpecialType.System_Int32);
                    if (size < 0)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;
                }

                position++;
            }

            if (!hasErrors)
            {
                if (kind == LayoutKind.Auto && size == null && alignment != null)
                {
                    // If size is unspecified
                    //   C# emits size=0
                    //   VB emits size=1 if the type is a struct, auto-layout and has alignment specified; 0 otherwise
                    size = defaultAutoLayoutSize;
                }

                arguments.GetOrCreateData <TTypeWellKnownAttributeData>().SetStructLayout(new TypeLayout(kind, size ?? 0, (byte)(alignment ?? 0)), charSet);
            }
        }