public static void DecodeMethodImplAttribute <T, TAttributeSyntaxNode, TAttributeData, TAttributeLocation>( ref DecodeWellKnownAttributeArguments <TAttributeSyntaxNode, TAttributeData, TAttributeLocation> arguments, CommonMessageProvider messageProvider) where T : CommonMethodWellKnownAttributeData, new() where TAttributeSyntaxNode : GreenNode 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); }
public 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 : GreenNode where TAttributeData : AttributeData { Debug.Assert((object)arguments.AttributeSyntaxOpt != null); var attribute = arguments.Attribute; CharSet charSet = (defaultCharSet != Constants.CharSet_None) ? defaultCharSet : CharSet.Ansi; int? size = null; int? alignment = null; bool hasErrors = false; LayoutKind kind = attribute.CommonConstructorArguments[0].DecodeValue <LayoutKind>(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 Constants.CharSet_None: charSet = CharSet.Ansi; break; case CharSet.Ansi: case 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>(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); } }