예제 #1
0
        internal void SetMarshalAsSafeArray(Cci.VarEnum?elementType, ITypeSymbolInternal elementTypeSymbol)
        {
            Debug.Assert(elementType == null || elementType >= 0 && (int)elementType <= MaxMarshalInteger);

            _marshalType             = Cci.Constants.UnmanagedType_SafeArray;
            _marshalArrayElementType = (int)(elementType ?? InvalidVariantType);
            _marshalTypeNameOrSymbol = elementTypeSymbol;
        }
예제 #2
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);
            }
        }