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; }
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); } }