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); } }
private static void DecodeMarshalAsSafeArray(ref DecodeWellKnownAttributeArguments <TAttributeSyntax, TAttributeData, TAttributeLocation> arguments, CommonMessageProvider messageProvider) { Debug.Assert((object)arguments.AttributeSyntaxOpt != null); Cci.VarEnum?elementTypeVariant = null; ITypeSymbol 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 <ITypeSymbol>(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); } }
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); } } }