**** Merged from MCS ****
[mono.git] / mcs / gmcs / attribute.cs
index 8400748fe900adf677e8c28d1c677b584bbf3087..8cbc52161e876450933c5e1fdbc034e6de244003 100644 (file)
-//\r
-// attribute.cs: Attribute Handler\r
-//\r
-// Author: Ravi Pratap (ravi@ximian.com)\r
-//\r
-// Licensed under the terms of the GNU GPL\r
-//\r
-// (C) 2001 Ximian, Inc (http://www.ximian.com)\r
-//\r
-//\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using System.Collections;\r
-using System.Reflection;\r
-using System.Reflection.Emit;\r
-using System.Runtime.InteropServices;\r
-using System.Runtime.CompilerServices;\r
-using System.Text;\r
-\r
-namespace Mono.CSharp {\r
-\r
-       public class Attribute {\r
-               public readonly string    Name;\r
-               public readonly ArrayList Arguments;\r
-\r
-               Location Location;\r
-\r
-               public Type Type;\r
-               \r
-               //\r
-               // The following are only meaningful when the attribute\r
-               // being emitted is one of the builtin ones\r
-               //\r
-               AttributeTargets Targets;\r
-               bool AllowMultiple;\r
-               bool Inherited;\r
-\r
-               bool UsageAttr = false;\r
-               \r
-               MethodImplOptions ImplOptions;\r
-               UnmanagedType     UnmanagedType;\r
-               CustomAttributeBuilder cb;\r
-       \r
-               /* non-null if named args present after Resolve () is called */\r
-               PropertyInfo [] prop_info_arr;\r
-               FieldInfo [] field_info_arr;\r
-               object [] field_values_arr;\r
-               object [] prop_values_arr;\r
-               \r
-               public Attribute (string name, ArrayList args, Location loc)\r
-               {\r
-                       Name = name;\r
-                       Arguments = args;\r
-                       Location = loc;\r
-               }\r
-\r
-               void Error_InvalidNamedArgument (string name)\r
-               {\r
-                       Report.Error (617, Location, "'" + name + "' is not a valid named attribute " +\r
-                                     "argument. Named attribute arguments must be fields which are not " +\r
-                                     "readonly, static or const, or properties with a set accessor which "+\r
-                                     "are not static.");\r
-               }\r
-\r
-               static void Error_AttributeArgumentNotValid (Location loc)\r
-               {\r
-                       Report.Error (182, loc,\r
-                                     "An attribute argument must be a constant expression, typeof " +\r
-                                     "expression or array creation expression");\r
-               }\r
-\r
-               static void Error_AttributeConstructorMismatch (Location loc)\r
-               {\r
-                       Report.Error (-6, loc,\r
-                                      "Could not find a constructor for this argument list.");\r
-               }\r
-               \r
-               private Type CheckAttributeType (EmitContext ec) {\r
-                       Type t;\r
-                       bool isattributeclass = true;\r
-                       \r
-                       t = RootContext.LookupType (ec.DeclSpace, Name, true, Location);\r
-                       if (t != null) {\r
-                               isattributeclass = t.IsSubclassOf (TypeManager.attribute_type);\r
-                               if (isattributeclass)\r
-                                       return t;\r
-                       }\r
-                       t = RootContext.LookupType (ec.DeclSpace, Name + "Attribute", true, Location);\r
-                       if (t != null) {\r
-                               if (t.IsSubclassOf (TypeManager.attribute_type))\r
-                                       return t;\r
-                       }\r
-                       if (!isattributeclass) {\r
-                               Report.Error (616, Location, "'" + Name + "': is not an attribute class");\r
-                               return null;\r
-                       }\r
-                       if (t != null) {\r
-                               Report.Error (616, Location, "'" + Name + "Attribute': is not an attribute class");\r
-                               return null;\r
-                       }\r
-                       Report.Error (\r
-                               246, Location, "Could not find attribute '" + Name + "' (are you" +\r
-                               " missing a using directive or an assembly reference ?)");\r
-                       return null;\r
-               }\r
-\r
-               public Type ResolveType (EmitContext ec)\r
-               {\r
-                       Type = CheckAttributeType (ec);\r
-                       return Type;\r
-               }\r
-\r
-               /// <summary>\r
-               ///   Validates the guid string\r
-               /// </summary>\r
-               bool ValidateGuid (string guid)\r
-               {\r
-                       try {\r
-                               new Guid (guid);\r
-                               return true;\r
-                       } catch {\r
-                               Report.Error (647, Location, "Format of GUID is invalid: " + guid);\r
-                               return false;\r
-                       }\r
-               }\r
-\r
-               //\r
-               // Given an expression, if the expression is a valid attribute-argument-expression\r
-               // returns an object that can be used to encode it, or null on failure.\r
-               //\r
-               public static bool GetAttributeArgumentExpression (Expression e, Location loc, out object result)\r
-               {\r
-                       if (e is Constant) {\r
-                               result = ((Constant) e).GetValue ();\r
-                               return true;\r
-                       } else if (e is TypeOf) {\r
-                               result = ((TypeOf) e).TypeArg;\r
-                               return true;\r
-                       } else if (e is ArrayCreation){\r
-                               result =  ((ArrayCreation) e).EncodeAsAttribute ();\r
-                               if (result != null)\r
-                                       return true;\r
-                       }\r
-\r
-                       result = null;\r
-                       Error_AttributeArgumentNotValid (loc);\r
-                       return false;\r
-               }\r
-               \r
-               public CustomAttributeBuilder Resolve (EmitContext ec)\r
-               {\r
-                       if (Type == null)\r
-                               Type = CheckAttributeType (ec);\r
-                       if (Type == null)\r
-                               return null;\r
-\r
-                       bool MethodImplAttr = false;\r
-                       bool MarshalAsAttr = false;\r
-                       bool GuidAttr = false;\r
-                       UsageAttr = false;\r
-\r
-                       bool DoCompares = true;\r
-                       if (Type == TypeManager.attribute_usage_type)\r
-                               UsageAttr = true;\r
-                       else if (Type == TypeManager.methodimpl_attr_type)\r
-                               MethodImplAttr = true;\r
-                       else if (Type == TypeManager.marshal_as_attr_type)\r
-                               MarshalAsAttr = true;\r
-                       else if (Type == TypeManager.guid_attr_type)\r
-                               GuidAttr = true;\r
-                       else\r
-                               DoCompares = false;\r
-\r
-                       // Now we extract the positional and named arguments\r
-                       \r
-                       ArrayList pos_args = new ArrayList ();\r
-                       ArrayList named_args = new ArrayList ();\r
-                       int pos_arg_count = 0;\r
-                       \r
-                       if (Arguments != null) {\r
-                               pos_args = (ArrayList) Arguments [0];\r
-                               if (pos_args != null)\r
-                                       pos_arg_count = pos_args.Count;\r
-                               if (Arguments.Count > 1)\r
-                                       named_args = (ArrayList) Arguments [1];\r
-                       }\r
-\r
-                       object [] pos_values = new object [pos_arg_count];\r
-\r
-                       //\r
-                       // First process positional arguments \r
-                       //\r
-\r
-                       int i;\r
-                       for (i = 0; i < pos_arg_count; i++) {\r
-                               Argument a = (Argument) pos_args [i];\r
-                               Expression e;\r
-\r
-                               if (!a.Resolve (ec, Location))\r
-                                       return null;\r
-\r
-                               e = a.Expr;\r
-\r
-                               object val;\r
-                               if (!GetAttributeArgumentExpression (e, Location, out val))\r
-                                       return null;\r
-                               \r
-                               pos_values [i] = val;\r
-                               if (DoCompares){\r
-                                       if (UsageAttr)\r
-                                               this.Targets = (AttributeTargets) pos_values [0];\r
-                                       else if (MethodImplAttr)\r
-                                               this.ImplOptions = (MethodImplOptions) pos_values [0];\r
-                                       else if (GuidAttr){\r
-                                               //\r
-                                               // we will later check the validity of the type\r
-                                               //\r
-                                               if (pos_values [0] is string){\r
-                                                       if (!ValidateGuid ((string) pos_values [0]))\r
-                                                               return null;\r
-                                               }\r
-                                               \r
-                                       } else if (MarshalAsAttr)\r
-                                               this.UnmanagedType =\r
-                                               (System.Runtime.InteropServices.UnmanagedType) pos_values [0];\r
-                               }\r
-                       }\r
-\r
-                       //\r
-                       // Now process named arguments\r
-                       //\r
-\r
-                       ArrayList field_infos = null;\r
-                       ArrayList prop_infos  = null;\r
-                       ArrayList field_values = null;\r
-                       ArrayList prop_values = null;\r
-\r
-                       if (named_args.Count > 0) {\r
-                               field_infos = new ArrayList ();\r
-                               prop_infos  = new ArrayList ();\r
-                               field_values = new ArrayList ();\r
-                               prop_values = new ArrayList ();\r
-                       }\r
-                       \r
-                       for (i = 0; i < named_args.Count; i++) {\r
-                               DictionaryEntry de = (DictionaryEntry) named_args [i];\r
-                               string member_name = (string) de.Key;\r
-                               Argument a  = (Argument) de.Value;\r
-                               Expression e;\r
-                               \r
-                               if (!a.Resolve (ec, Location))\r
-                                       return null;\r
-\r
-                               Expression member = Expression.MemberLookup (\r
-                                       ec, Type, member_name,\r
-                                       MemberTypes.Field | MemberTypes.Property,\r
-                                       BindingFlags.Public | BindingFlags.Instance,\r
-                                       Location);\r
-\r
-                               if (member == null || !(member is PropertyExpr || member is FieldExpr)) {\r
-                                       Error_InvalidNamedArgument (member_name);\r
-                                       return null;\r
-                               }\r
-\r
-                               e = a.Expr;\r
-                               if (member is PropertyExpr) {\r
-                                       PropertyExpr pe = (PropertyExpr) member;\r
-                                       PropertyInfo pi = pe.PropertyInfo;\r
-\r
-                                       if (!pi.CanWrite) {\r
-                                               Error_InvalidNamedArgument (member_name);\r
-                                               return null;\r
-                                       }\r
-\r
-                                       if (e is Constant) {\r
-                                               object o = ((Constant) e).GetValue ();\r
-                                               prop_values.Add (o);\r
-                                               \r
-                                               if (UsageAttr) {\r
-                                                       if (member_name == "AllowMultiple")\r
-                                                               this.AllowMultiple = (bool) o;\r
-                                                       if (member_name == "Inherited")\r
-                                                               this.Inherited = (bool) o;\r
-                                               }\r
-                                               \r
-                                       } else if (e is TypeOf) {\r
-                                               prop_values.Add (((TypeOf) e).TypeArg);\r
-                                       } else {\r
-                                               Error_AttributeArgumentNotValid (Location);\r
-                                               return null;\r
-                                       }\r
-                                       \r
-                                       prop_infos.Add (pi);\r
-                                       \r
-                               } else if (member is FieldExpr) {\r
-                                       FieldExpr fe = (FieldExpr) member;\r
-                                       FieldInfo fi = fe.FieldInfo;\r
-\r
-                                       if (fi.IsInitOnly) {\r
-                                               Error_InvalidNamedArgument (member_name);\r
-                                               return null;\r
-                                       }\r
-\r
-                                       //\r
-                                       // Handle charset here, and set the TypeAttributes\r
-                                       \r
-                                       if (e is Constant){\r
-                                               object value = ((Constant) e).GetValue ();\r
-                                               \r
-                                               field_values.Add (value);\r
-                                       } else if (e is TypeOf) {\r
-                                               field_values.Add (((TypeOf) e).TypeArg);\r
-                                       } else {\r
-                                               Error_AttributeArgumentNotValid (Location);\r
-                                               return null;\r
-                                       }\r
-                                       \r
-                                       field_infos.Add (fi);\r
-                               }\r
-                       }\r
-\r
-                       Expression mg = Expression.MemberLookup (\r
-                               ec, Type, ".ctor", MemberTypes.Constructor,\r
-                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,\r
-                                Location);\r
-\r
-                       if (mg == null) {\r
-                               Error_AttributeConstructorMismatch (Location);\r
-                               return null;\r
-                       }\r
-\r
-                       MethodBase constructor = Invocation.OverloadResolve (\r
-                               ec, (MethodGroupExpr) mg, pos_args, Location);\r
-\r
-                       if (constructor == null) {\r
-                               Error_AttributeConstructorMismatch (Location);\r
-                               return null;\r
-                       }\r
-\r
-                       //\r
-                       // Now we perform some checks on the positional args as they\r
-                       // cannot be null for a constructor which expects a parameter\r
-                       // of type object\r
-                       //\r
-\r
-                       ParameterData pd = Invocation.GetParameterData (constructor);\r
-\r
-                       int group_in_params_array = Int32.MaxValue;\r
-                       int pc = pd.Count;\r
-                       if (pc > 0 && pd.ParameterModifier (pc-1) == Parameter.Modifier.PARAMS)\r
-                               group_in_params_array = pc-1;\r
-                       \r
-                       for (int j = 0; j < pos_arg_count; ++j) {\r
-                               Argument a = (Argument) pos_args [j];\r
-                               \r
-                               if (a.Expr is NullLiteral && pd.ParameterType (j) == TypeManager.object_type) {\r
-                                       Error_AttributeArgumentNotValid (Location);\r
-                                       return null;\r
-                               }\r
-\r
-                               if (j < group_in_params_array)\r
-                                       continue;\r
-                               \r
-                               if (j == group_in_params_array){\r
-                                       object v = pos_values [j];\r
-                                       int count = pos_arg_count - j;\r
-\r
-                                       object [] array = new object [count];\r
-                                       pos_values [j] = array;\r
-                                       array [0] = v;\r
-                               } else {\r
-                                       object [] array = (object []) pos_values [group_in_params_array];\r
-\r
-                                       array [j - group_in_params_array] = pos_values [j];\r
-                               }\r
-                       }\r
-\r
-                       //\r
-                       // Adjust the size of the pos_values if it had params\r
-                       //\r
-                       if (group_in_params_array != Int32.MaxValue){\r
-                               int argc = group_in_params_array+1;\r
-                               object [] new_pos_values = new object [argc];\r
-\r
-                               for (int p = 0; p < argc; p++)\r
-                                       new_pos_values [p] = pos_values [p];\r
-                               pos_values = new_pos_values;\r
-                       }\r
-\r
-                       try {\r
-                               if (named_args.Count > 0) {\r
-                                       prop_info_arr = new PropertyInfo [prop_infos.Count];\r
-                                       field_info_arr = new FieldInfo [field_infos.Count];\r
-                                       field_values_arr = new object [field_values.Count];\r
-                                       prop_values_arr = new object [prop_values.Count];\r
-\r
-                                       field_infos.CopyTo  (field_info_arr, 0);\r
-                                       field_values.CopyTo (field_values_arr, 0);\r
-\r
-                                       prop_values.CopyTo  (prop_values_arr, 0);\r
-                                       prop_infos.CopyTo   (prop_info_arr, 0);\r
-\r
-                                       cb = new CustomAttributeBuilder (\r
-                                               (ConstructorInfo) constructor, pos_values,\r
-                                               prop_info_arr, prop_values_arr,\r
-                                               field_info_arr, field_values_arr);\r
-                               }\r
-                               else\r
-                                       cb = new CustomAttributeBuilder (\r
-                                               (ConstructorInfo) constructor, pos_values);\r
-                       } catch (NullReferenceException) {\r
-                               // \r
-                               // Don't know what to do here\r
-                               //\r
-                               Report.Warning (\r
-                                       -100, Location, "NullReferenceException while trying to create attribute. Something's wrong!");\r
-                       } catch (Exception e) {\r
-                               //\r
-                               // Sample:\r
-                               // using System.ComponentModel;\r
-                               // [DefaultValue (CollectionChangeAction.Add)]\r
-                               // class X { static void Main () {} }\r
-                               //\r
-                               Report.Warning (\r
-                                       -23, Location,\r
-                                       "The compiler can not encode this attribute in .NET due to\n" +\r
-                                       "\ta bug in the .NET runtime.  Try the Mono runtime.\nThe error was: " + e.Message);\r
-                       }\r
-                       \r
-                       return cb;\r
-               }\r
-\r
-               static string GetValidPlaces (Attribute attr)\r
-               {\r
-                       StringBuilder sb = new StringBuilder ();\r
-                       AttributeTargets targets = 0;\r
-                       \r
-                       TypeContainer a = TypeManager.LookupAttr (attr.Type);\r
-\r
-                       if (a == null) {\r
-                               \r
-                               System.Attribute [] attrs = null;\r
-                               \r
-                               try {\r
-                                       attrs = System.Attribute.GetCustomAttributes (attr.Type);\r
-                                       \r
-                               } catch {\r
-                                       Report.Error (-20, attr.Location, "Cannot find attribute type " + attr.Name +\r
-                                                     " (maybe you forgot to set the usage using the" +\r
-                                                     " AttributeUsage attribute ?).");\r
-                                       return null;\r
-                               }\r
-                                       \r
-                               foreach (System.Attribute tmp in attrs)\r
-                                       if (tmp is AttributeUsageAttribute) {\r
-                                               targets = ((AttributeUsageAttribute) tmp).ValidOn;\r
-                                               break;\r
-                                       }\r
-                       } else\r
-                               targets = a.Targets;\r
-\r
-                       \r
-                       if ((targets & AttributeTargets.Assembly) != 0)\r
-                               sb.Append ("'assembly' ");\r
-\r
-                       if ((targets & AttributeTargets.Class) != 0)\r
-                               sb.Append ("'class' ");\r
-\r
-                       if ((targets & AttributeTargets.Constructor) != 0)\r
-                               sb.Append ("'constructor' ");\r
-\r
-                       if ((targets & AttributeTargets.Delegate) != 0)\r
-                               sb.Append ("'delegate' ");\r
-\r
-                       if ((targets & AttributeTargets.Enum) != 0)\r
-                               sb.Append ("'enum' ");\r
-\r
-                       if ((targets & AttributeTargets.Event) != 0)\r
-                               sb.Append ("'event' ");\r
-\r
-                       if ((targets & AttributeTargets.Field) != 0)\r
-                               sb.Append ("'field' ");\r
-\r
-                       if ((targets & AttributeTargets.Interface) != 0)\r
-                               sb.Append ("'interface' ");\r
-\r
-                       if ((targets & AttributeTargets.Method) != 0)\r
-                               sb.Append ("'method' ");\r
-\r
-                       if ((targets & AttributeTargets.Module) != 0)\r
-                               sb.Append ("'module' ");\r
-\r
-                       if ((targets & AttributeTargets.Parameter) != 0)\r
-                               sb.Append ("'parameter' ");\r
-\r
-                       if ((targets & AttributeTargets.Property) != 0)\r
-                               sb.Append ("'property' ");\r
-\r
-                       if ((targets & AttributeTargets.ReturnValue) != 0)\r
-                               sb.Append ("'return value' ");\r
-\r
-                       if ((targets & AttributeTargets.Struct) != 0)\r
-                               sb.Append ("'struct' ");\r
-\r
-                       return sb.ToString ();\r
-\r
-               }\r
-\r
-               public static void Error_AttributeNotValidForElement (Attribute a, Location loc)\r
-               {\r
-                       Report.Error (\r
-                               592, loc, "Attribute '" + a.Name +\r
-                               "' is not valid on this declaration type. " +\r
-                               "It is valid on " + GetValidPlaces (a) + "declarations only.");\r
-               }\r
-\r
-               public static bool CheckAttribute (Attribute a, object element)\r
-               {\r
-                       TypeContainer attr = TypeManager.LookupAttr (a.Type);\r
-                       AttributeTargets targets = 0;\r
-\r
-                       \r
-                       if (attr == null) {\r
-                               System.Attribute [] attrs = null;\r
-                               \r
-                               try {\r
-                                       attrs = System.Attribute.GetCustomAttributes (a.Type);\r
-\r
-                               } catch {\r
-                                       Report.Error (-20, a.Location, "Cannot find attribute type " + a.Name +\r
-                                                     " (maybe you forgot to set the usage using the" +\r
-                                                     " AttributeUsage attribute ?).");\r
-                                       return false;\r
-                               }\r
-                                       \r
-                               foreach (System.Attribute tmp in attrs)\r
-                                       if (tmp is AttributeUsageAttribute) \r
-                                               targets = ((AttributeUsageAttribute) tmp).ValidOn;\r
-                       } else\r
-                               targets = attr.Targets;\r
-\r
-                       if (element is Class) {\r
-                               if ((targets & AttributeTargets.Class) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                               \r
-                       } else if (element is Struct) {\r
-                               if ((targets & AttributeTargets.Struct) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is Constructor) {\r
-                               if ((targets & AttributeTargets.Constructor) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is Delegate) {\r
-                               if ((targets & AttributeTargets.Delegate) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is Enum) {\r
-                               if ((targets & AttributeTargets.Enum) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is Event || element is InterfaceEvent) {\r
-                               if ((targets & AttributeTargets.Event) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is Field || element is FieldBuilder) {\r
-                               if ((targets & AttributeTargets.Field) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is Interface) {\r
-                               if ((targets & AttributeTargets.Interface) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is Method || element is Operator || element is InterfaceMethod || element is Accessor) {\r
-                               if ((targets & AttributeTargets.Method) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is ParameterBuilder) {\r
-                               if ((targets & AttributeTargets.Parameter) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is Property || element is Indexer ||\r
-                                  element is InterfaceProperty || element is InterfaceIndexer) {\r
-                               if ((targets & AttributeTargets.Property) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       } else if (element is AssemblyBuilder){\r
-                               if ((targets & AttributeTargets.Assembly) != 0)\r
-                                       return true;\r
-                               else\r
-                                       return false;\r
-                       }\r
-\r
-                       return false;\r
-               }\r
-\r
-               //\r
-               // This method should be invoked to pull the IndexerName attribute from an\r
-               // Indexer if it exists.\r
-               //\r
-               public static string ScanForIndexerName (EmitContext ec, Attributes opt_attrs)\r
-               {\r
-                       if (opt_attrs == null)\r
-                               return null;\r
-                       if (opt_attrs.AttributeSections == null)\r
-                               return null;\r
-\r
-                       foreach (AttributeSection asec in opt_attrs.AttributeSections) {\r
-                               if (asec.Attributes == null)\r
-                                       continue;\r
-\r
-                               foreach (Attribute a in asec.Attributes){\r
-                                       if (a.ResolveType (ec) == null)\r
-                                               return null;\r
-                                       \r
-                                       if (a.Type != TypeManager.indexer_name_type)\r
-                                               continue;\r
-\r
-                                       //\r
-                                       // So we have found an IndexerName, pull the data out.\r
-                                       //\r
-                                       if (a.Arguments == null || a.Arguments [0] == null){\r
-                                               Error_AttributeConstructorMismatch (a.Location);\r
-                                               return null;\r
-                                       }\r
-                                       ArrayList pos_args = (ArrayList) a.Arguments [0];\r
-                                       if (pos_args.Count == 0){\r
-                                               Error_AttributeConstructorMismatch (a.Location);\r
-                                               return null;\r
-                                       }\r
-                                       \r
-                                       Argument arg = (Argument) pos_args [0];\r
-                                       if (!arg.Resolve (ec, a.Location))\r
-                                               return null;\r
-                                       \r
-                                       Expression e = arg.Expr;\r
-                                       if (!(e is StringConstant)){\r
-                                               Error_AttributeConstructorMismatch (a.Location);\r
-                                               return null;\r
-                                       }\r
-\r
-                                       //\r
-                                       // Remove the attribute from the list\r
-                                       //\r
-                                       asec.Attributes.Remove (a);\r
-\r
-                                       return (((StringConstant) e).Value);\r
-                               }\r
-                       }\r
-                       return null;\r
-               }\r
-\r
-               //\r
-               // This pulls the condition name out of a Conditional attribute\r
-               //\r
-               public string Conditional_GetConditionName ()\r
-               {\r
-                       //\r
-                       // So we have a Conditional, pull the data out.\r
-                       //\r
-                       if (Arguments == null || Arguments [0] == null){\r
-                               Error_AttributeConstructorMismatch (Location);\r
-                               return null;\r
-                       }\r
-\r
-                       ArrayList pos_args = (ArrayList) Arguments [0];\r
-                       if (pos_args.Count != 1){\r
-                               Error_AttributeConstructorMismatch (Location);\r
-                               return null;\r
-                       }\r
-\r
-                       Argument arg = (Argument) pos_args [0]; \r
-                       if (!(arg.Expr is StringConstant)){\r
-                               Error_AttributeConstructorMismatch (Location);\r
-                               return null;\r
-                       }\r
-\r
-                       return ((StringConstant) arg.Expr).Value;\r
-               }\r
-\r
-               //\r
-               // This pulls the obsolete message and error flag out of an Obsolete attribute\r
-               //\r
-               public string Obsolete_GetObsoleteMessage (out bool is_error)\r
-               {\r
-                       is_error = false;\r
-                       //\r
-                       // So we have an Obsolete, pull the data out.\r
-                       //\r
-                       if (Arguments == null || Arguments [0] == null)\r
-                               return "";\r
-\r
-                       ArrayList pos_args = (ArrayList) Arguments [0];\r
-                       if (pos_args.Count == 0)\r
-                               return "";\r
-                       else if (pos_args.Count > 2){\r
-                               Error_AttributeConstructorMismatch (Location);\r
-                               return null;\r
-                       }\r
-\r
-                       Argument arg = (Argument) pos_args [0]; \r
-                       if (!(arg.Expr is StringConstant)){\r
-                               Error_AttributeConstructorMismatch (Location);\r
-                               return null;\r
-                       }\r
-\r
-                       if (pos_args.Count == 2){\r
-                               Argument arg2 = (Argument) pos_args [1];\r
-                               if (!(arg2.Expr is BoolConstant)){\r
-                                       Error_AttributeConstructorMismatch (Location);\r
-                                       return null;\r
-                               }\r
-                               is_error = ((BoolConstant) arg2.Expr).Value;\r
-                       }\r
-\r
-                       return ((StringConstant) arg.Expr).Value;\r
-               }\r
-\r
-               static object GetFieldValue (Attribute a, string name) {\r
-                       int i;\r
-                       if (a.field_info_arr == null)\r
-                               return null;\r
-                       i = 0;\r
-                       foreach (FieldInfo fi in a.field_info_arr) {\r
-                               if (fi.Name == name)\r
-                                       return a.field_values_arr [i];\r
-                               i++;\r
-                       }\r
-                       return null;\r
-               }\r
-\r
-               static UnmanagedMarshal GetMarshal (Attribute a) {\r
-                       UnmanagedMarshal marshal;\r
-\r
-                       if (a.UnmanagedType == UnmanagedType.CustomMarshaler) {\r
-                               MethodInfo define_custom = typeof (UnmanagedMarshal).GetMethod ("DefineCustom", BindingFlags.Static | BindingFlags.Public);\r
-                               if (define_custom == null) {\r
-                                       return null;\r
-                               }\r
-                               object[] args = new object [4];\r
-                               args [0] = GetFieldValue (a, "MarshalTypeRef");\r
-                               args [1] = GetFieldValue (a, "MarshalCookie");\r
-                               args [2] = GetFieldValue (a, "MarshalType");\r
-                               args [3] = Guid.Empty;\r
-                               marshal = (UnmanagedMarshal) define_custom.Invoke (null, args);\r
-                       /*\r
-                        * need to special case other special marshal types\r
-                        */\r
-                       } else {\r
-                               marshal = UnmanagedMarshal.DefineUnmanagedMarshal (a.UnmanagedType);\r
-                       }\r
-                       return marshal;\r
-               }\r
-\r
-               //\r
-               // Applies the attributes to the `builder'.\r
-               //\r
-               public static void ApplyAttributes (EmitContext ec, object builder, object kind,\r
-                                                   Attributes opt_attrs)\r
-               {\r
-                       Type attr_type = null;\r
-                       \r
-                       if (opt_attrs == null)\r
-                               return;\r
-                       if (opt_attrs.AttributeSections == null)\r
-                               return;\r
-\r
-                       ArrayList emitted_attrs = new ArrayList ();\r
-                       ArrayList emitted_targets = new ArrayList ();\r
-\r
-                       foreach (AttributeSection asec in opt_attrs.AttributeSections) {\r
-                               string attr_target = asec.Target;\r
-                               \r
-                               if (asec.Attributes == null)\r
-                                       continue;\r
-\r
-                               if (attr_target == "assembly" && !(builder is AssemblyBuilder))\r
-                                       continue;\r
-\r
-                               if (attr_target == "return" && !(builder is ParameterBuilder))\r
-                                       continue;\r
-                               \r
-                               foreach (Attribute a in asec.Attributes) {\r
-                                       Location loc = a.Location;\r
-                                       CustomAttributeBuilder cb = a.Resolve (ec);\r
-                                       attr_type = a.Type;\r
-\r
-                                       if (cb == null) \r
-                                               continue;\r
-                                       \r
-                                       if (!(kind is TypeContainer))\r
-                                               if (!CheckAttribute (a, kind)) {\r
-                                                       Error_AttributeNotValidForElement (a, loc);\r
-                                                       return;\r
-                                               }\r
-\r
-                                       //\r
-                                       // Perform the check for duplicate attributes\r
-                                       //\r
-                                       if (emitted_attrs.Contains (attr_type) &&\r
-                                           emitted_targets.Contains (attr_target) &&\r
-                                           !TypeManager.AreMultipleAllowed (attr_type)) {\r
-                                               Report.Error (579, loc, "Duplicate '" + a.Name + "' attribute");\r
-                                               return;\r
-                                       }\r
-\r
-                                       if (kind is Method || kind is Operator || kind is InterfaceMethod ||\r
-                                           kind is Accessor) {\r
-                                               if (attr_type == TypeManager.methodimpl_attr_type) {\r
-                                                       if (a.ImplOptions == MethodImplOptions.InternalCall)\r
-                                                               ((MethodBuilder) builder).\r
-                                                               SetImplementationFlags (\r
-                                                                       MethodImplAttributes.InternalCall |\r
-                                                                       MethodImplAttributes.Runtime);\r
-                                                       else\r
-                                                               ((MethodBuilder) builder).SetCustomAttribute (cb);\r
-                                               } else if (attr_type != TypeManager.dllimport_type){\r
-                                                       ((MethodBuilder) builder).SetCustomAttribute (cb);\r
-                                               }\r
-                                       } else if (kind is Constructor) {\r
-                                               ((ConstructorBuilder) builder).SetCustomAttribute (cb);\r
-                                       } else if (kind is Field) {\r
-                                               ((FieldBuilder) builder).SetCustomAttribute (cb);\r
-                                       } else if (kind is Property || kind is Indexer ||\r
-                                                  kind is InterfaceProperty || kind is InterfaceIndexer) {\r
-                                               ((PropertyBuilder) builder).SetCustomAttribute (cb);\r
-                                       } else if (kind is Event || kind is InterfaceEvent) {\r
-                                               ((MyEventBuilder) builder).SetCustomAttribute (cb);\r
-                                       } else if (kind is ParameterBuilder) {\r
-\r
-                                               if (attr_type == TypeManager.marshal_as_attr_type) {\r
-                                                       UnmanagedMarshal marshal = GetMarshal (a);\r
-                                                       if (marshal == null) {\r
-                                                               Report.Warning (-24, loc,\r
-                                                                       "The Microsoft Runtime cannot set this marshal info. " +\r
-                                                                       "Please use the Mono runtime instead.");\r
-                                                       } else {\r
-                                                               ((ParameterBuilder) builder).SetMarshal (marshal);\r
-                                                       }\r
-                                               } else { \r
-\r
-                                                       try {\r
-                                                               ((ParameterBuilder) builder).SetCustomAttribute (cb);\r
-                                                       } catch (System.ArgumentException) {\r
-                                                               Report.Warning (-24, loc,\r
-                                                                               "The Microsoft Runtime cannot set attributes \n" +\r
-                                                                               "on the return type of a method. Please use the \n" +\r
-                                                                               "Mono runtime instead.");\r
-                                                       }\r
-\r
-                                               }\r
-                                       } else if (kind is Enum) {\r
-                                               ((TypeBuilder) builder).SetCustomAttribute (cb); \r
-\r
-                                       } else if (kind is TypeContainer) {\r
-                                               TypeContainer tc = (TypeContainer) kind;\r
-                                               \r
-                                               if (a.UsageAttr) {\r
-                                                       tc.Targets = a.Targets;\r
-                                                       tc.AllowMultiple = a.AllowMultiple;\r
-                                                       tc.Inherited = a.Inherited;\r
-\r
-                                                       TypeManager.RegisterAttributeAllowMultiple (tc.TypeBuilder,\r
-                                                                                                   tc.AllowMultiple);\r
-                                                       \r
-                                               } else if (attr_type == TypeManager.default_member_type) {\r
-                                                       if (tc.Indexers != null) {\r
-                                                               Report.Error (646, loc,\r
-                                                                     "Cannot specify the DefaultMember attribute on" +\r
-                                                                     " a type containing an indexer");\r
-                                                               return;\r
-                                                       }\r
-\r
-                                               } else {\r
-                                                       if (!CheckAttribute (a, kind)) {\r
-                                                               Error_AttributeNotValidForElement (a, loc);\r
-                                                               return;\r
-                                                       }\r
-                                               }\r
-\r
-                                               try {\r
-                                                       ((TypeBuilder) builder).SetCustomAttribute (cb);\r
-                                               } catch (System.ArgumentException) {\r
-                                                       Report.Warning (\r
-                                                               -21, loc,\r
-                                               "The CharSet named property on StructLayout\n"+\r
-                                               "\tdoes not work correctly on Microsoft.NET\n"+\r
-                                               "\tYou might want to remove the CharSet declaration\n"+\r
-                                               "\tor compile using the Mono runtime instead of the\n"+\r
-                                               "\tMicrosoft .NET runtime");\r
-                                               }\r
-                                               \r
-                                       } else if (kind is Interface) {\r
-                                               Interface iface = (Interface) kind;\r
-\r
-                                               if ((attr_type == TypeManager.default_member_type) &&\r
-                                                   (iface.InterfaceIndexers != null)) {\r
-                                                       Report.Error (\r
-                                                               646, loc,\r
-                                                               "Cannot specify the DefaultMember attribute on" +\r
-                                                               " a type containing an indexer");\r
-                                                       return;\r
-                                               }\r
-\r
-                                               if (!CheckAttribute (a, kind)) {\r
-                                                       Error_AttributeNotValidForElement (a, loc);\r
-                                                       return;\r
-                                               }\r
-\r
-                                               ((TypeBuilder) builder).SetCustomAttribute (cb);\r
-                                       } else if (kind is AssemblyBuilder){\r
-                                               ((AssemblyBuilder) builder).SetCustomAttribute (cb);\r
-                                       } else if (kind is ModuleBuilder) {\r
-                                               ((ModuleBuilder) builder).SetCustomAttribute (cb);\r
-                                       } else if (kind is FieldBuilder) {\r
-                                               if (attr_type == TypeManager.marshal_as_attr_type) {\r
-                                                       UnmanagedMarshal marshal = GetMarshal (a);\r
-                                                       if (marshal == null) {\r
-                                                               Report.Warning (-24, loc,\r
-                                                                       "The Microsoft Runtime cannot set this marshal info. " +\r
-                                                                       "Please use the Mono runtime instead.");\r
-                                                       } else {\r
-                                                               ((ParameterBuilder) builder).SetMarshal (marshal);\r
-                                                       }\r
-                                               } else { \r
-                                                       ((FieldBuilder) builder).SetCustomAttribute (cb);\r
-                                               }\r
-                                       } else\r
-                                               throw new Exception ("Unknown kind: " + kind);\r
-\r
-                                       //\r
-                                       // Once an attribute type has been emitted once we\r
-                                       // keep track of the info to prevent multiple occurences\r
-                                       // for attributes which do not explicitly allow it\r
-                                       //\r
-                                       if (!emitted_attrs.Contains (attr_type))\r
-                                               emitted_attrs.Add (attr_type);\r
-\r
-                                       //\r
-                                       // We keep of this target-wise and so emitted targets\r
-                                       // are tracked too\r
-                                       //\r
-                                       if (!emitted_targets.Contains (attr_target))\r
-                                               emitted_targets.Add (attr_target);\r
-                               }\r
-                               \r
-                               \r
-                       }\r
-               }\r
-\r
-               public MethodBuilder DefinePInvokeMethod (EmitContext ec, TypeBuilder builder, string name,\r
-                                                         MethodAttributes flags, Type ret_type, Type [] param_types)\r
-               {\r
-                       //\r
-                       // We extract from the attribute the information we need \r
-                       //\r
-\r
-                       if (Arguments == null) {\r
-                               Console.WriteLine ("Internal error : this is not supposed to happen !");\r
-                               return null;\r
-                       }\r
-\r
-                       Type = CheckAttributeType (ec);\r
-                       if (Type == null)\r
-                               return null;\r
-                       \r
-                       ArrayList named_args = new ArrayList ();\r
-                       \r
-                       ArrayList pos_args = (ArrayList) Arguments [0];\r
-                       if (Arguments.Count > 1)\r
-                               named_args = (ArrayList) Arguments [1];\r
-                       \r
-\r
-                       string dll_name = null;\r
-                       \r
-                       Argument tmp = (Argument) pos_args [0];\r
-\r
-                       if (!tmp.Resolve (ec, Location))\r
-                               return null;\r
-                       \r
-                       if (tmp.Expr is Constant)\r
-                               dll_name = (string) ((Constant) tmp.Expr).GetValue ();\r
-                       else { \r
-                               Error_AttributeArgumentNotValid (Location);\r
-                               return null;\r
-                       }\r
-\r
-                       // Now we process the named arguments\r
-                       CallingConvention cc = CallingConvention.Winapi;\r
-                       CharSet charset = CharSet.Ansi;\r
-                       bool preserve_sig = true;\r
-                       bool exact_spelling = false;\r
-                       bool set_last_err = false;\r
-                       string entry_point = null;\r
-\r
-                       for (int i = 0; i < named_args.Count; i++) {\r
-\r
-                               DictionaryEntry de = (DictionaryEntry) named_args [i];\r
-\r
-                               string member_name = (string) de.Key;\r
-                               Argument a  = (Argument) de.Value;\r
-\r
-                               if (!a.Resolve (ec, Location))\r
-                                       return null;\r
-\r
-                               Expression member = Expression.MemberLookup (\r
-                                       ec, Type, member_name, \r
-                                       MemberTypes.Field | MemberTypes.Property,\r
-                                       BindingFlags.Public | BindingFlags.Instance,\r
-                                       Location);\r
-\r
-                               if (member == null || !(member is FieldExpr)) {\r
-                                       Error_InvalidNamedArgument (member_name);\r
-                                       return null;\r
-                               }\r
-\r
-                               if (member is FieldExpr) {\r
-                                       FieldExpr fe = (FieldExpr) member;\r
-                                       FieldInfo fi = fe.FieldInfo;\r
-\r
-                                       if (fi.IsInitOnly) {\r
-                                               Error_InvalidNamedArgument (member_name);\r
-                                               return null;\r
-                                       }\r
-\r
-                                       if (a.Expr is Constant) {\r
-                                               Constant c = (Constant) a.Expr;\r
-                                               \r
-                                               if (member_name == "CallingConvention")\r
-                                                       cc = (CallingConvention) c.GetValue ();\r
-                                               else if (member_name == "CharSet")\r
-                                                       charset = (CharSet) c.GetValue ();\r
-                                               else if (member_name == "EntryPoint")\r
-                                                       entry_point = (string) c.GetValue ();\r
-                                               else if (member_name == "SetLastError")\r
-                                                       set_last_err = (bool) c.GetValue ();\r
-                                               else if (member_name == "ExactSpelling")\r
-                                                       exact_spelling = (bool) c.GetValue ();\r
-                                               else if (member_name == "PreserveSig")\r
-                                                       preserve_sig = (bool) c.GetValue ();\r
-                                       } else { \r
-                                               Error_AttributeArgumentNotValid (Location);\r
-                                               return null;\r
-                                       }\r
-                                       \r
-                               }\r
-                       }\r
-\r
-                       if (entry_point == null)\r
-                               entry_point = name;\r
-                       \r
-                       MethodBuilder mb = builder.DefinePInvokeMethod (\r
-                               name, dll_name, entry_point, flags | MethodAttributes.HideBySig,\r
-                               CallingConventions.Standard,\r
-                               ret_type,\r
-                               param_types,\r
-                               cc,\r
-                               charset);\r
-\r
-                       if (preserve_sig)\r
-                               mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);\r
-                       \r
-                       return mb;\r
-               }\r
-               \r
-       }\r
-       \r
-       public class AttributeSection {\r
-               public readonly string    Target;\r
-               public readonly ArrayList Attributes;\r
-               \r
-               public AttributeSection (string target, ArrayList attrs)\r
-               {\r
-                       Target = target;\r
-                       Attributes = attrs;\r
-               }\r
-               \r
-       }\r
-\r
-       public class Attributes {\r
-               public ArrayList AttributeSections;\r
-\r
-               public Attributes (AttributeSection a)\r
-               {\r
-                       AttributeSections = new ArrayList ();\r
-                       AttributeSections.Add (a);\r
-\r
-               }\r
-\r
-               public void AddAttributeSection (AttributeSection a)\r
-               {\r
-                       if (a != null && !AttributeSections.Contains (a))\r
-                               AttributeSections.Add (a);\r
-               }\r
-\r
-               public bool Contains (Type t)\r
-               {\r
-                       foreach (AttributeSection attr_section in AttributeSections){\r
-                               foreach (Attribute a in attr_section.Attributes){\r
-                                       if (a.Type == t)\r
-                                               return true;\r
-                               }\r
-                       }\r
-                        \r
-                       return false;\r
-               }\r
-       }\r
-}\r
+//
+// attribute.cs: Attribute Handler
+//
+// Author: Ravi Pratap (ravi@ximian.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+//
+
+using System;
+using System.Diagnostics;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace Mono.CSharp {
+
+       /// <summary>
+       ///   Base class for objects that can have Attributes applied to them.
+       /// </summary>
+       public abstract class Attributable {
+               /// <summary>
+               ///   Attributes for this type
+               /// </summary>
+               Attributes attributes;
+
+               public Attributable(Attributes attrs)
+               {
+                       attributes = attrs;
+                       if (attributes != null)
+                               attributes.CheckTargets (ValidAttributeTargets);
+               }
+
+               public Attributes OptAttributes 
+               {
+                       get {
+                               return attributes;
+                       }
+                       set {
+                               attributes = value;
+                               if (attributes != null)
+                                       attributes.CheckTargets (ValidAttributeTargets);
+                       }
+               }
+
+               /// <summary>
+               /// Use member-specific procedure to apply attribute @a in @cb to the entity being built in @builder
+               /// </summary>
+               public abstract void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb);
+
+               /// <summary>
+               /// Returns combination of enabled AttributeTargets
+               /// </summary>
+               public abstract AttributeTargets AttributeTargets { get; }
+
+               public abstract bool IsClsCompliaceRequired (DeclSpace ds);
+
+               /// <summary>
+               /// Gets list of valid attribute targets for explicit target declaration.
+               /// The first array item is default target. Don't break this rule.
+               /// </summary>
+               protected abstract string[] ValidAttributeTargets { get; }
+       };
+
+       public class Attribute {
+               public string Target;
+               public readonly string    Name;
+               public readonly ArrayList Arguments;
+
+               public readonly Location Location;
+
+               public Type Type;
+               
+               // Is non-null if type is AttributeUsageAttribute
+               AttributeUsageAttribute usage_attribute;
+
+               public AttributeUsageAttribute UsageAttribute {
+                       get {
+                               return usage_attribute;
+                       }
+               }
+               
+               MethodImplOptions ImplOptions;
+               UnmanagedType     UnmanagedType;
+               CustomAttributeBuilder cb;
+       
+               // non-null if named args present after Resolve () is called
+               PropertyInfo [] prop_info_arr;
+               FieldInfo [] field_info_arr;
+               object [] field_values_arr;
+               object [] prop_values_arr;
+               object [] pos_values;
+
+               static PtrHashtable usage_attr_cache = new PtrHashtable ();
+               
+               public Attribute (string target, string name, ArrayList args, Location loc)
+               {
+                       Name = name;
+                       Arguments = args;
+                       Location = loc;
+                       Target = target;
+               }
+
+               void Error_InvalidNamedArgument (string name)
+               {
+                       Report.Error (617, Location, "'" + name + "' is not a valid named attribute " +
+                                     "argument. Named attribute arguments must be fields which are not " +
+                                     "readonly, static or const, or properties with a set accessor which "+
+                                     "are not static.");
+               }
+
+               static void Error_AttributeArgumentNotValid (Location loc)
+               {
+                       Report.Error (182, loc,
+                                     "An attribute argument must be a constant expression, typeof " +
+                                     "expression or array creation expression");
+               }
+
+               static void Error_TypeParameterInAttribute (Location loc)
+               {
+                       Report.Error (
+                               -202, loc, "Can not use a type parameter in an attribute");
+               }
+
+               void Error_AttributeConstructorMismatch ()
+               {
+                       Report.Error (-6, Location,
+                                      "Could not find a constructor for this argument list.");
+               }
+
+               /// <summary>
+                ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
+                /// </summary>
+               protected virtual Type CheckAttributeType (EmitContext ec, bool complain)
+               {
+                       TypeExpr t1 = RootContext.LookupType (ec.DeclSpace, Name, true, Location);
+                       // FIXME: Shouldn't do this for quoted attributes: [@A]
+                       TypeExpr t2 = RootContext.LookupType (ec.DeclSpace, Name + "Attribute", true, Location);
+
+                       String err0616 = null;
+                       if (t1 != null && ! t1.IsAttribute) {
+                               t1 = null;
+                               err0616 = "'" + Name + "': is not an attribute class";
+                       }
+                       if (t2 != null && ! t2.IsAttribute) {
+                               t2 = null;
+                               err0616 = (err0616 != null) 
+                                       ? "Neither '" + Name + "' nor '" + Name + "Attribute' is an attribute class"
+                                       : "'" + Name + "Attribute': is not an attribute class";
+                       }
+
+                       if (t1 != null && t2 != null) {
+                               Report.Error(1614, Location, "'" + Name + "': is ambiguous; " 
+                                            + " use either '@" + Name + "' or '" + Name + "Attribute'");
+                               return null;
+                       }
+                       if (t1 != null)
+                               return t1.ResolveType (ec);
+                       if (t2 != null)
+                               return t2.ResolveType (ec);
+                       if (err0616 != null) {
+                               Report.Error (616, Location, err0616);
+                               return null;
+                       }
+
+                       if (complain)
+                               Report.Error (246, Location, 
+                                             "Could not find attribute '" + Name 
+                                             + "' (are you missing a using directive or an assembly reference ?)");
+                       return null;
+               }
+
+               public Type ResolveType (EmitContext ec, bool complain)
+               {
+                       if (Type == null)
+                               Type = CheckAttributeType (ec, complain);
+                       return Type;
+               }
+
+               /// <summary>
+               ///   Validates the guid string
+               /// </summary>
+               bool ValidateGuid (string guid)
+               {
+                       try {
+                               new Guid (guid);
+                               return true;
+                       } catch {
+                               Report.Error (647, Location, "Format of GUID is invalid: " + guid);
+                               return false;
+                       }
+               }
+
+               string GetFullMemberName (string member)
+               {
+                       return Type.FullName + '.' + member;
+               }
+
+               //
+               // Given an expression, if the expression is a valid attribute-argument-expression
+               // returns an object that can be used to encode it, or null on failure.
+               //
+               public static bool GetAttributeArgumentExpression (Expression e, Location loc, out object result)
+               {
+                       if (e is Constant) {
+                               result = ((Constant) e).GetValue ();
+                               return true;
+                       } else if (e is TypeOf) {
+                               result = ((TypeOf) e).TypeArg;
+                               return true;
+                       } else if (e is ArrayCreation){
+                               result =  ((ArrayCreation) e).EncodeAsAttribute ();
+                               if (result != null)
+                                       return true;
+                       } else if (e is EmptyCast) {
+                               result = e;
+                               if (((EmptyCast) e).Child is Constant) {
+                                       result = ((Constant) ((EmptyCast)e).Child).GetValue();
+                               }
+                               return true;
+                       }
+
+                       result = null;
+                       Error_AttributeArgumentNotValid (loc);
+                       return false;
+               }
+               
+               public CustomAttributeBuilder Resolve (EmitContext ec)
+               {
+                       Type oldType = Type;
+                       
+                       // Sanity check.
+                       Type = CheckAttributeType (ec, true);
+                       if (oldType == null && Type == null)
+                               return null;
+                       if (oldType != null && oldType != Type) {
+                               Report.Error (-6, Location,
+                                             "Attribute {0} resolved to different types at different times: {1} vs. {2}",
+                                             Name, oldType, Type);
+                               return null;
+                       }
+
+                       bool MethodImplAttr = false;
+                       bool MarshalAsAttr = false;
+                       bool GuidAttr = false;
+                       bool usage_attr = false;
+
+                       bool DoCompares = true;
+
+                        //
+                        // If we are a certain special attribute, we
+                        // set the information accordingly
+                        //
+                        
+                       if (Type == TypeManager.attribute_usage_type)
+                               usage_attr = true;
+                       else if (Type == TypeManager.methodimpl_attr_type)
+                               MethodImplAttr = true;
+                       else if (Type == TypeManager.marshal_as_attr_type)
+                               MarshalAsAttr = true;
+                       else if (Type == TypeManager.guid_attr_type)
+                               GuidAttr = true;
+                       else
+                               DoCompares = false;
+
+                       // Now we extract the positional and named arguments
+                       
+                       ArrayList pos_args = new ArrayList ();
+                       ArrayList named_args = new ArrayList ();
+                       int pos_arg_count = 0;
+                       
+                       if (Arguments != null) {
+                               pos_args = (ArrayList) Arguments [0];
+                               if (pos_args != null)
+                                       pos_arg_count = pos_args.Count;
+                               if (Arguments.Count > 1)
+                                       named_args = (ArrayList) Arguments [1];
+                       }
+
+                       pos_values = new object [pos_arg_count];
+
+                       //
+                       // First process positional arguments 
+                       //
+
+                       int i;
+                       for (i = 0; i < pos_arg_count; i++) {
+                               Argument a = (Argument) pos_args [i];
+                               Expression e;
+
+                               if (!a.Resolve (ec, Location))
+                                       return null;
+
+                               e = a.Expr;
+
+                               object val;
+                               if (!GetAttributeArgumentExpression (e, Location, out val))
+                                       return null;
+                               
+                               pos_values [i] = val;
+                               if (DoCompares){
+                                       if (usage_attr)
+                                               usage_attribute = new AttributeUsageAttribute ((AttributeTargets) pos_values [0]);
+                                       else if (MethodImplAttr)
+                                               this.ImplOptions = (MethodImplOptions) pos_values [0];
+                                       else if (GuidAttr){
+                                               //
+                                               // we will later check the validity of the type
+                                               //
+                                               if (pos_values [0] is string){
+                                                       if (!ValidateGuid ((string) pos_values [0]))
+                                                               return null;
+                                               }
+                                               
+                                       } else if (MarshalAsAttr)
+                                               this.UnmanagedType =
+                                               (System.Runtime.InteropServices.UnmanagedType) pos_values [0];
+                               }
+                       }
+
+                       //
+                       // Now process named arguments
+                       //
+
+                       ArrayList field_infos = null;
+                       ArrayList prop_infos  = null;
+                       ArrayList field_values = null;
+                       ArrayList prop_values = null;
+
+                       if (named_args.Count > 0) {
+                               field_infos = new ArrayList ();
+                               prop_infos  = new ArrayList ();
+                               field_values = new ArrayList ();
+                               prop_values = new ArrayList ();
+                       }
+
+                       Hashtable seen_names = new Hashtable();
+                       
+                       for (i = 0; i < named_args.Count; i++) {
+                               DictionaryEntry de = (DictionaryEntry) named_args [i];
+                               string member_name = (string) de.Key;
+                               Argument a  = (Argument) de.Value;
+                               Expression e;
+
+                               if (seen_names.Contains(member_name)) {
+                                       Report.Error(643, Location, "'" + member_name + "' duplicate named attribute argument");
+                                       return null;
+                               }                               
+                               seen_names.Add(member_name, 1);
+                               
+                               if (!a.Resolve (ec, Location))
+                                       return null;
+
+                               Expression member = Expression.MemberLookup (
+                                       ec, Type, member_name,
+                                       MemberTypes.Field | MemberTypes.Property,
+                                       BindingFlags.Public | BindingFlags.Instance,
+                                       Location);
+
+                               if (member == null) {
+                                       member = Expression.MemberLookup (ec, Type, member_name,
+                                               MemberTypes.Field | MemberTypes.Property, BindingFlags.NonPublic | BindingFlags.Instance,
+                                               Location);
+
+                                       if (member != null) {
+                                               Report.Error_T (122, Location, GetFullMemberName (member_name));
+                                               return null;
+                                       }
+                               }
+
+                               if (member == null || !(member is PropertyExpr || member is FieldExpr)) {
+                                       Error_InvalidNamedArgument (member_name);
+                                       return null;
+                               }
+
+                               e = a.Expr;
+                               if (e is TypeParameterExpr){
+                                       Error_TypeParameterInAttribute (Location);
+                                       return null;
+                               }
+                                       
+                               if (member is PropertyExpr) {
+                                       PropertyExpr pe = (PropertyExpr) member;
+                                       PropertyInfo pi = pe.PropertyInfo;
+
+                                       if (!pi.CanWrite) {
+                                               Error_InvalidNamedArgument (member_name);
+                                               return null;
+                                       }
+
+                                       Constant c = e as Constant;
+                                       if (c != null) {
+                                               if (c.Type != pi.PropertyType) {
+                                                       c = Const.ChangeType (Location, c, pi.PropertyType);
+                                                       if (c == null)
+                                                               return null;
+                                               }
+                                               
+                                               object o = c.GetValue ();
+                                               prop_values.Add (o);
+                                               
+                                               if (usage_attribute != null) {
+                                                       if (member_name == "AllowMultiple")
+                                                               usage_attribute.AllowMultiple = (bool) o;
+                                                       if (member_name == "Inherited")
+                                                               usage_attribute.Inherited = (bool) o;
+                                               }
+                                               
+                                       } else if (e is TypeOf) {
+                                               prop_values.Add (((TypeOf) e).TypeArg);
+                                       } else if (e is ArrayCreation) {
+                                               prop_values.Add (((ArrayCreation) e).EncodeAsAttribute());
+                                       } else {
+                                               Error_AttributeArgumentNotValid (Location);
+                                               return null;
+                                       }
+                                       
+                                       prop_infos.Add (pi);
+                                       
+                               } else if (member is FieldExpr) {
+                                       FieldExpr fe = (FieldExpr) member;
+                                       FieldInfo fi = fe.FieldInfo;
+
+                                       if (fi.IsInitOnly) {
+                                               Error_InvalidNamedArgument (member_name);
+                                               return null;
+                                       }
+
+                                       //
+                                       // Handle charset here, and set the TypeAttributes
+                                       
+                                       Constant c = e as Constant;
+                                       if (c != null) {
+                                               if (c.Type != fi.FieldType){
+                                                       c = Const.ChangeType (Location, c, fi.FieldType);
+                                                       if (c == null)
+                                                               return null;
+                                               } 
+                                               
+                                               object value = c.GetValue ();
+                                               field_values.Add (value);
+                                       } else if (e is TypeOf) {
+                                               field_values.Add (((TypeOf) e).TypeArg);
+                                       } else {
+                                               Error_AttributeArgumentNotValid (Location);
+                                               return null;
+                                       }
+                                       
+                                       field_infos.Add (fi);
+                               }
+                       }
+
+                       Expression mg = Expression.MemberLookup (
+                               ec, Type, ".ctor", MemberTypes.Constructor,
+                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                                Location);
+
+                       if (mg == null) {
+                               Error_AttributeConstructorMismatch ();
+                               return null;
+                       }
+
+                       MethodBase constructor = Invocation.OverloadResolve (
+                               ec, (MethodGroupExpr) mg, pos_args, false, Location);
+
+                       if (constructor == null) {
+                               Error_AttributeConstructorMismatch ();
+                               return null;
+                       }
+
+                       //
+                       // Now we perform some checks on the positional args as they
+                       // cannot be null for a constructor which expects a parameter
+                       // of type object
+                       //
+
+                       ParameterData pd = Invocation.GetParameterData (constructor);
+
+                       int group_in_params_array = Int32.MaxValue;
+                       int pc = pd.Count;
+                       if (pc > 0 && pd.ParameterModifier (pc-1) == Parameter.Modifier.PARAMS)
+                               group_in_params_array = pc-1;
+
+                       for (int j = 0; j < pos_arg_count; ++j) {
+                               Argument a = (Argument) pos_args [j];
+                               
+                               if (a.Expr is NullLiteral && pd.ParameterType (j) == TypeManager.object_type) {
+                                       Error_AttributeArgumentNotValid (Location);
+                                       return null;
+                               }
+
+                               if (j < group_in_params_array)
+                                       continue;
+                               
+                               if (j == group_in_params_array){
+                                       object v = pos_values [j];
+                                       int count = pos_arg_count - j;
+
+                                       object [] array = new object [count];
+                                       pos_values [j] = array;
+                                       array [0] = v;
+                               } else {
+                                       object [] array = (object []) pos_values [group_in_params_array];
+
+                                       array [j - group_in_params_array] = pos_values [j];
+                               }
+                       }
+
+                       //
+                       // Adjust the size of the pos_values if it had params
+                       //
+                       if (group_in_params_array != Int32.MaxValue){
+                               int argc = group_in_params_array+1;
+                               object [] new_pos_values = new object [argc];
+
+                               for (int p = 0; p < argc; p++)
+                                       new_pos_values [p] = pos_values [p];
+                               pos_values = new_pos_values;
+                       }
+
+                       try {
+                               if (named_args.Count > 0) {
+                                       prop_info_arr = new PropertyInfo [prop_infos.Count];
+                                       field_info_arr = new FieldInfo [field_infos.Count];
+                                       field_values_arr = new object [field_values.Count];
+                                       prop_values_arr = new object [prop_values.Count];
+
+                                       field_infos.CopyTo  (field_info_arr, 0);
+                                       field_values.CopyTo (field_values_arr, 0);
+
+                                       prop_values.CopyTo  (prop_values_arr, 0);
+                                       prop_infos.CopyTo   (prop_info_arr, 0);
+
+                                       cb = new CustomAttributeBuilder (
+                                               (ConstructorInfo) constructor, pos_values,
+                                               prop_info_arr, prop_values_arr,
+                                               field_info_arr, field_values_arr);
+                               }
+                               else
+                                       cb = new CustomAttributeBuilder (
+                                               (ConstructorInfo) constructor, pos_values);
+                       } catch (NullReferenceException) {
+                               // 
+                               // Don't know what to do here
+                               //
+                               Report.Warning (
+                                       -101, Location, "NullReferenceException while trying to create attribute." +
+                                        "Something's wrong!");
+                       } catch (Exception e) {
+                               //
+                               // Sample:
+                               // using System.ComponentModel;
+                               // [DefaultValue (CollectionChangeAction.Add)]
+                               // class X { static void Main () {} }
+                               //
+                               Report.Warning (
+                                       -23, Location, "The compiler can not encode this attribute in .NET due to a bug in the .NET runtime. Try the Mono runtime. The exception was: " + e.Message);
+                       }
+                       
+                       return cb;
+               }
+
+               /// <summary>
+               ///   Get a string containing a list of valid targets for the attribute 'attr'
+               /// </summary>
+               static string GetValidTargets (Attribute attr)
+               {
+                       StringBuilder sb = new StringBuilder ();
+                       AttributeTargets targets = attr.GetAttributeUsage ().ValidOn;
+
+                       if ((targets & AttributeTargets.Assembly) != 0)
+                               sb.Append ("'assembly' ");
+
+                       if ((targets & AttributeTargets.Class) != 0)
+                               sb.Append ("'class' ");
+
+                       if ((targets & AttributeTargets.Constructor) != 0)
+                               sb.Append ("'constructor' ");
+
+                       if ((targets & AttributeTargets.Delegate) != 0)
+                               sb.Append ("'delegate' ");
+
+                       if ((targets & AttributeTargets.Enum) != 0)
+                               sb.Append ("'enum' ");
+
+                       if ((targets & AttributeTargets.Event) != 0)
+                               sb.Append ("'event' ");
+
+                       if ((targets & AttributeTargets.Field) != 0)
+                               sb.Append ("'field' ");
+
+                       if ((targets & AttributeTargets.Interface) != 0)
+                               sb.Append ("'interface' ");
+
+                       if ((targets & AttributeTargets.Method) != 0)
+                               sb.Append ("'method' ");
+
+                       if ((targets & AttributeTargets.Module) != 0)
+                               sb.Append ("'module' ");
+
+                       if ((targets & AttributeTargets.Parameter) != 0)
+                               sb.Append ("'parameter' ");
+
+                       if ((targets & AttributeTargets.Property) != 0)
+                               sb.Append ("'property' ");
+
+                       if ((targets & AttributeTargets.ReturnValue) != 0)
+                               sb.Append ("'return' ");
+
+                       if ((targets & AttributeTargets.Struct) != 0)
+                               sb.Append ("'struct' ");
+
+                       return sb.ToString ();
+
+               }
+
+               public static void Error_AttributeNotValidForElement (Attribute a, Location loc)
+               {
+                       Report.Error (
+                               592, loc, "Attribute '" + a.Name +
+                               "' is not valid on this declaration type. " +
+                               "It is valid on " + GetValidTargets (a) + "declarations only.");
+               }
+
+
+               /// <summary>
+               /// Returns AttributeUsage attribute for this type
+               /// </summary>
+               public AttributeUsageAttribute GetAttributeUsage ()
+               {
+                       AttributeUsageAttribute ua = usage_attr_cache [Type] as AttributeUsageAttribute;
+                       if (ua != null)
+                               return ua;
+
+                       Class attr_class = TypeManager.LookupClass (Type);
+
+                       if (attr_class == null) {
+                               object[] usage_attr = Type.GetCustomAttributes (TypeManager.attribute_usage_type, true);
+                               ua = (AttributeUsageAttribute)usage_attr [0];
+                               usage_attr_cache.Add (Type, ua);
+                               return ua;
+                       }
+               
+                       return attr_class.AttributeUsage;
+               }
+
+
+               //
+               // This pulls the condition name out of a Conditional attribute
+               //
+               public string Conditional_GetConditionName ()
+               {
+                       //
+                       // So we have a Conditional, pull the data out.
+                       //
+                       if (Arguments == null || Arguments [0] == null){
+                               Error_AttributeConstructorMismatch ();
+                               return null;
+                       }
+
+                       ArrayList pos_args = (ArrayList) Arguments [0];
+                       if (pos_args.Count != 1){
+                               Error_AttributeConstructorMismatch ();
+                               return null;
+                       }
+
+                       Argument arg = (Argument) pos_args [0]; 
+                       if (!(arg.Expr is StringConstant)){
+                               Error_AttributeConstructorMismatch ();
+                               return null;
+                       }
+
+                       return ((StringConstant) arg.Expr).Value;
+               }
+
+               public string IndexerName_GetIndexerName (EmitContext ec)
+               {
+                       if (Arguments == null || Arguments [0] == null){
+                               Error_AttributeConstructorMismatch ();
+                               return null;
+                       }
+                       ArrayList pos_args = (ArrayList) Arguments [0];
+                       if (pos_args.Count != 1) {
+                               Error_AttributeConstructorMismatch ();
+                               return null;
+                       }
+                       
+                       Argument arg = (Argument) pos_args [0];
+                       if (!arg.Resolve (ec, Location))
+                               return null;
+                       
+                       StringConstant sc = arg.Expr as StringConstant;
+                       if (sc == null){
+                               Error_AttributeConstructorMismatch ();
+                               return null;
+                       }
+                       
+                       return sc.Value;
+               }
+
+               /// <summary>
+               /// Creates the instance of ObsoleteAttribute from this attribute instance
+               /// </summary>
+               public ObsoleteAttribute GetObsoleteAttribute (DeclSpace ds)
+               {
+                       if (pos_values == null) {
+                               EmitContext ec = new EmitContext (ds, ds, Location, null, null, 0, false);
+
+                               // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
+                               // But because a lot of attribute class code must be rewritten will be better to wait...
+                               Resolve (ec);
+                       }
+
+                       // Some error occurred
+                       if (pos_values == null)
+                               return null;
+
+                       if (pos_values.Length == 0)
+                               return new ObsoleteAttribute ();
+
+                       if (pos_values.Length == 1)
+                               return new ObsoleteAttribute ((string)pos_values [0]);
+
+                       return new ObsoleteAttribute ((string)pos_values [0], (bool)pos_values [1]);
+               }
+
+               /// <summary>
+               /// Returns value of CLSCompliantAttribute contructor parameter but because the method can be called
+               /// before ApplyAttribute. We need to resolve the arguments.
+               /// This situation occurs when class deps is differs from Emit order.  
+               /// </summary>
+               public bool GetClsCompliantAttributeValue (DeclSpace ds)
+               {
+                       if (pos_values == null) {
+                               EmitContext ec = new EmitContext (ds, ds, Location, null, null, 0, false);
+
+                               // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
+                               // But because a lot of attribute class code must be rewritten will be better to wait...
+                               Resolve (ec);
+                       }
+
+                       // Some error occurred
+                       if (pos_values [0] == null)
+                               return false;
+
+                       return (bool)pos_values [0];
+               }
+
+               public object GetPositionalValue (int i)
+               {
+                       return (pos_values == null) ? null : pos_values[i];
+               }
+
+               object GetFieldValue (string name)
+                {
+                       int i;
+                       if (field_info_arr == null)
+                               return null;
+                       i = 0;
+                       foreach (FieldInfo fi in field_info_arr) {
+                               if (fi.Name == name)
+                                       return field_values_arr [i];
+                               i++;
+                       }
+                       return null;
+               }
+
+               public UnmanagedMarshal GetMarshal ()
+               {
+                       object o = GetFieldValue ("ArraySubType");
+                       UnmanagedType array_sub_type = o == null ? UnmanagedType.I4 : (UnmanagedType) o;
+                       
+                       switch (UnmanagedType) {
+                       case UnmanagedType.CustomMarshaler:
+                               MethodInfo define_custom = typeof (UnmanagedMarshal).GetMethod ("DefineCustom",
+                                                                       BindingFlags.Static | BindingFlags.Public);
+                               if (define_custom == null)
+                                       return null;
+                               
+                               object [] args = new object [4];
+                               args [0] = GetFieldValue ("MarshalTypeRef");
+                               args [1] = GetFieldValue ("MarshalCookie");
+                               args [2] = GetFieldValue ("MarshalType");
+                               args [3] = Guid.Empty;
+                               return (UnmanagedMarshal) define_custom.Invoke (null, args);
+                               
+                       case UnmanagedType.LPArray:                             
+                               return UnmanagedMarshal.DefineLPArray (array_sub_type);
+                       
+                       case UnmanagedType.SafeArray:
+                               return UnmanagedMarshal.DefineSafeArray (array_sub_type);
+                       
+                       case UnmanagedType.ByValArray:
+                               return UnmanagedMarshal.DefineByValArray ((int) GetFieldValue ("SizeConst"));
+                       
+                       case UnmanagedType.ByValTStr:
+                               return UnmanagedMarshal.DefineByValTStr ((int) GetFieldValue ("SizeConst"));
+                       
+                       default:
+                               return UnmanagedMarshal.DefineUnmanagedMarshal (UnmanagedType);
+                       }
+               }
+
+               public bool IsInternalCall
+               {
+                       get { return ImplOptions == MethodImplOptions.InternalCall; }
+               }
+
+               /// <summary>
+               /// Emit attribute for Attributable symbol
+               /// </summary>
+               public void Emit (EmitContext ec, Attributable ias, ListDictionary emitted_attr)
+               {
+                       CustomAttributeBuilder cb = Resolve (ec);
+                       if (cb == null)
+                               return;
+
+                       AttributeUsageAttribute usage_attr = GetAttributeUsage ();
+                       if ((usage_attr.ValidOn & ias.AttributeTargets) == 0) {
+                                       Error_AttributeNotValidForElement (this, Location);
+                               return;
+                       }
+
+                       ias.ApplyAttributeBuilder (this, cb);
+
+                       if (!usage_attr.AllowMultiple && emitted_attr.Contains (Target)) {
+                               Report.Error (579, Location, "Duplicate '" + Name + "' attribute");
+                       }
+
+                       emitted_attr [Type] = Target;
+
+                       // Here we are testing attribute arguments for array usage (error 3016)
+                       if (ias.IsClsCompliaceRequired (ec.DeclSpace)) {
+                               if (Arguments == null)
+                                       return;
+
+                               ArrayList pos_args = (ArrayList) Arguments [0];
+                               if (pos_args != null) {
+                                       foreach (Argument arg in pos_args) { 
+                                               // Type is undefined (was error 246)
+                                               if (arg.Type == null)
+                                                       return;
+
+                                               if (arg.Type.IsArray) {
+                                                       Report.Error_T (3016, Location);
+                                                       return;
+                                               }
+                                       }
+                               }
+                       
+                               if (Arguments.Count < 2)
+                                       return;
+                       
+                               ArrayList named_args = (ArrayList) Arguments [1];
+                               foreach (DictionaryEntry de in named_args) {
+                                       Argument arg  = (Argument) de.Value;
+
+                                       // Type is undefined (was error 246)
+                                       if (arg.Type == null)
+                                               return;
+
+                                       if (arg.Type.IsArray) {
+                                               Report.Error_T (3016, Location);
+                                               return;
+                                       }
+                               }
+                       }
+               }
+
+               public object GetValue (EmitContext ec, Constant c, Type target)
+               {
+                       if (Convert.ImplicitConversionExists (ec, c, target))
+                               return c.GetValue ();
+
+                       Convert.Error_CannotImplicitConversion (Location, c.Type, target);
+                       return null;
+               }
+               
+               public MethodBuilder DefinePInvokeMethod (EmitContext ec, TypeBuilder builder, string name,
+                                                         MethodAttributes flags, Type ret_type, Type [] param_types)
+               {
+                       //
+                       // We extract from the attribute the information we need 
+                       //
+
+                       if (Arguments == null) {
+                               Console.WriteLine ("Internal error : this is not supposed to happen !");
+                               return null;
+                       }
+
+                       ResolveType (ec, true);
+                       if (Type == null)
+                               return null;
+                       
+                       ArrayList named_args = new ArrayList ();
+                       
+                       ArrayList pos_args = (ArrayList) Arguments [0];
+                       if (Arguments.Count > 1)
+                               named_args = (ArrayList) Arguments [1];
+                       
+
+                       string dll_name = null;
+                       
+                       Argument tmp = (Argument) pos_args [0];
+
+                       if (!tmp.Resolve (ec, Location))
+                               return null;
+                       
+                       if (tmp.Expr is Constant)
+                               dll_name = (string) ((Constant) tmp.Expr).GetValue ();
+                       else { 
+                               Error_AttributeArgumentNotValid (Location);
+                               return null;
+                       }
+
+                       // Now we process the named arguments
+                       CallingConvention cc = CallingConvention.Winapi;
+                       CharSet charset = CharSet.Ansi;
+                       bool preserve_sig = true;
+#if FIXME
+                       bool exact_spelling = false;
+#endif
+                       bool set_last_err = false;
+                       string entry_point = null;
+
+                       for (int i = 0; i < named_args.Count; i++) {
+
+                               DictionaryEntry de = (DictionaryEntry) named_args [i];
+
+                               string member_name = (string) de.Key;
+                               Argument a  = (Argument) de.Value;
+
+                               if (!a.Resolve (ec, Location))
+                                       return null;
+
+                               Expression member = Expression.MemberLookup (
+                                       ec, Type, member_name, 
+                                       MemberTypes.Field | MemberTypes.Property,
+                                       BindingFlags.Public | BindingFlags.Instance,
+                                       Location);
+
+                               if (member == null || !(member is FieldExpr)) {
+                                       Error_InvalidNamedArgument (member_name);
+                                       return null;
+                               }
+
+                               if (member is FieldExpr) {
+                                       FieldExpr fe = (FieldExpr) member;
+                                       FieldInfo fi = fe.FieldInfo;
+
+                                       if (fi.IsInitOnly) {
+                                               Error_InvalidNamedArgument (member_name);
+                                               return null;
+                                       }
+
+                                       if (a.Expr is Constant) {
+                                               Constant c = (Constant) a.Expr;
+
+                                               try {
+                                                       if (member_name == "CallingConvention"){
+                                                               object val = GetValue (ec, c, typeof (CallingConvention));
+                                                               if (val == null)
+                                                                       return null;
+                                                               cc = (CallingConvention) val;
+                                                       } else if (member_name == "CharSet"){
+                                                               charset = (CharSet) c.GetValue ();
+                                                       } else if (member_name == "EntryPoint")
+                                                               entry_point = (string) c.GetValue ();
+                                                       else if (member_name == "SetLastError")
+                                                               set_last_err = (bool) c.GetValue ();
+#if FIXME
+                                                       else if (member_name == "ExactSpelling")
+                                                               exact_spelling = (bool) c.GetValue ();
+#endif
+                                                       else if (member_name == "PreserveSig")
+                                                               preserve_sig = (bool) c.GetValue ();
+                                               } catch (InvalidCastException){
+                                                       Error_InvalidNamedArgument (member_name);
+                                                       Error_AttributeArgumentNotValid (Location);
+                                               }
+                                       } else { 
+                                               Error_AttributeArgumentNotValid (Location);
+                                               return null;
+                                       }
+                                       
+                               }
+                       }
+
+                       if (entry_point == null)
+                               entry_point = name;
+                       if (set_last_err)
+                               charset = (CharSet)((int)charset | 0x40);
+                       
+                       MethodBuilder mb = builder.DefinePInvokeMethod (
+                               name, dll_name, entry_point, flags | MethodAttributes.HideBySig,
+                               CallingConventions.Standard,
+                               ret_type,
+                               param_types,
+                               cc,
+                               charset);
+
+                       if (preserve_sig)
+                               mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);
+                       
+                       return mb;
+               }
+
+               private Expression GetValue () 
+               {
+                       if ((Arguments == null) || (Arguments.Count < 1))
+                               return null;
+                       ArrayList al = (ArrayList) Arguments [0];
+                       if ((al == null) || (al.Count < 1))
+                               return null;
+                       Argument arg = (Argument) al [0];
+                       if ((arg == null) || (arg.Expr == null))
+                               return null;
+                       return arg.Expr;
+               }
+
+               public string GetString () 
+               {
+                       Expression e = GetValue ();
+                       if (e is StringLiteral)
+                               return (e as StringLiteral).Value;
+                       return null;
+               }
+
+               public bool GetBoolean () 
+               {
+                       Expression e = GetValue ();
+                       if (e is BoolLiteral)
+                               return (e as BoolLiteral).Value;
+                       return false;
+               }
+       }
+       
+
+       /// <summary>
+       /// For global attributes (assembly, module) we need special handling.
+       /// Attributes can be located in the several files
+       /// </summary>
+       public class GlobalAttribute: Attribute
+       {
+               public readonly NamespaceEntry ns;
+
+               public GlobalAttribute (TypeContainer container, string target, string name, ArrayList args, Location loc):
+                       base (target, name, args, loc)
+               {
+                       ns = container.NamespaceEntry;
+               }
+
+               protected override Type CheckAttributeType (EmitContext ec, bool complain)
+               {
+                       NamespaceEntry old = ec.DeclSpace.NamespaceEntry;
+                       if (old == null || old.NS == null || old.NS == Namespace.Root) 
+                               ec.DeclSpace.NamespaceEntry = ns;
+                       return base.CheckAttributeType (ec, complain);
+               }
+       }
+
+       public class Attributes {
+               public ArrayList Attrs;
+
+               public Attributes (Attribute a)
+               {
+                       Attrs = new ArrayList ();
+                       Attrs.Add (a);
+               }
+
+               public Attributes (ArrayList attrs)
+               {
+                       Attrs = attrs;
+               }
+
+               public void AddAttributes (ArrayList attrs)
+               {
+                       Attrs.AddRange (attrs);
+               }
+
+               /// <summary>
+               /// Checks whether attribute target is valid for the current element
+               /// </summary>
+               public void CheckTargets (string[] possible_targets)
+               {
+                       foreach (Attribute a in Attrs) {
+                               if (a.Target == null) {
+                                       a.Target = possible_targets [0];
+                                       continue;
+                               }
+
+                               if (((IList) possible_targets).Contains (a.Target))
+                                       continue;
+
+                               StringBuilder sb = new StringBuilder ();
+                               foreach (string s in possible_targets) {
+                                       sb.Append (s);
+                                       sb.Append (", ");
+                               }
+                               sb.Remove (sb.Length - 2, 2);
+                               Report.Error_T (657, a.Location, a.Target, sb.ToString ());
+                       }
+               }
+
+               private Attribute Search (Type t, EmitContext ec, bool complain)
+               {
+                       foreach (Attribute a in Attrs) {
+                               if (a.ResolveType (ec, false) == t)
+                                       return a;
+                       }
+                       return null;
+               }
+
+               public Attribute Search (Type t, EmitContext ec)
+               {
+                       return Search (t, ec, true);
+               }
+
+               public void Emit (EmitContext ec, Attributable ias)
+               {
+                       ListDictionary ld = new ListDictionary ();
+
+                       foreach (Attribute a in Attrs)
+                               a.Emit (ec, ias, ld);
+               }
+
+               public bool Contains (Type t, EmitContext ec)
+               {
+                        return Search (t, ec) != null;
+               }
+
+               public Attribute GetClsCompliantAttribute (EmitContext ec)
+               {
+                       return Search (TypeManager.cls_compliant_attribute_type, ec, false);
+               }
+
+               /// <summary>
+               /// Pulls the IndexerName attribute from an Indexer if it exists.
+               /// </summary>
+               public string ScanForIndexerName (EmitContext ec)
+               {
+                       Attribute a = Search (TypeManager.indexer_name_type, ec);
+                       if (a == null)
+                               return null;
+
+                       // Remove the attribute from the list
+                       //TODO: It is very close to hack and it can crash here
+                       Attrs.Remove (a);
+
+                       return a.IndexerName_GetIndexerName (ec);
+               }
+
+       }
+
+       /// <summary>
+       /// Helper class for attribute verification routine.
+       /// </summary>
+       sealed class AttributeTester
+       {
+               static PtrHashtable analyzed_types = new PtrHashtable ();
+               static PtrHashtable analyzed_member_obsolete = new PtrHashtable ();
+
+               private AttributeTester ()
+               {
+               }
+
+               /// <summary>
+               /// Returns true if parameters of two compared methods are CLS-Compliant.
+               /// It tests differing only in ref or out, or in array rank.
+               /// </summary>
+               public static bool AreOverloadedMethodParamsClsCompliant (Type[] types_a, Type[] types_b) 
+               {
+                       if (types_a == null || types_b == null)
+                               return true;
+
+                       if (types_a.Length != types_b.Length)
+                               return true;
+
+                       for (int i = 0; i < types_b.Length; ++i) {
+                               Type aType = types_a [i];
+                               Type bType = types_b [i];
+
+                               if (aType.IsArray && bType.IsArray && aType.GetArrayRank () != bType.GetArrayRank () && aType.GetElementType () == bType.GetElementType ()) {
+                                       return false;
+                               }
+
+                               Type aBaseType = aType;
+                               bool is_either_ref_or_out = false;
+
+                               if (aType.IsByRef || aType.IsPointer) {
+                                       aBaseType = aType.GetElementType ();
+                                       is_either_ref_or_out = true;
+                               }
+
+                               Type bBaseType = bType;
+                               if (bType.IsByRef || bType.IsPointer) 
+                               {
+                                       bBaseType = bType.GetElementType ();
+                                       is_either_ref_or_out = !is_either_ref_or_out;
+                               }
+
+                               if (aBaseType != bBaseType)
+                                       continue;
+
+                               if (is_either_ref_or_out)
+                                       return false;
+                       }
+                       return true;
+               }
+
+               /// <summary>
+               /// Goes through all parameters and test if they are CLS-Compliant.
+               /// </summary>
+               public static bool AreParametersCompliant (Parameter[] fixedParameters, Location loc)
+               {
+                       if (fixedParameters == null)
+                               return true;
+
+                       foreach (Parameter arg in fixedParameters) {
+                               if (!AttributeTester.IsClsCompliant (arg.ParameterType)) {
+                                       Report.Error_T (3001, loc, arg.GetSignatureForError ());
+                                       return false;
+                               }
+                       }
+                       return true;
+               }
+
+
+               /// <summary>
+               /// This method tests the CLS compliance of external types. It doesn't test type visibility.
+               /// </summary>
+               public static bool IsClsCompliant (Type type) 
+               {
+                       if (type == null)
+                               return true;
+
+                       object type_compliance = analyzed_types[type];
+                       if (type_compliance != null)
+                               return type_compliance == TRUE;
+
+                       if (type.IsPointer) {
+                               analyzed_types.Add (type, null);
+                               return false;
+                       }
+
+                       bool result;
+                       if (type.IsArray || type.IsByRef)       {
+                               result = IsClsCompliant (TypeManager.GetElementType (type));
+                       } else {
+                               result = AnalyzeTypeCompliance (type);
+                       }
+                       analyzed_types.Add (type, result ? TRUE : FALSE);
+                       return result;
+               }                
+
+               static object TRUE = new object ();
+               static object FALSE = new object ();
+
+               /// <summary>
+               /// Non-hierarchical CLS Compliance analyzer
+               /// </summary>
+               public static bool IsComplianceRequired (MemberInfo mi, DeclSpace ds)
+               {
+                       DeclSpace temp_ds = TypeManager.LookupDeclSpace (mi.DeclaringType);
+
+                       // Type is external, we can get attribute directly
+                       if (temp_ds == null) {
+                               object[] cls_attribute = mi.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
+                               return (cls_attribute.Length == 1 && ((CLSCompliantAttribute)cls_attribute[0]).IsCompliant);
+                       }
+
+                       string tmp_name;
+                       // Interface doesn't store full name
+                       if (temp_ds is Interface)
+                               tmp_name = mi.Name;
+                       else
+                               tmp_name = String.Concat (temp_ds.Name, ".", mi.Name);
+
+                       MemberCore mc = temp_ds.GetDefinition (tmp_name) as MemberCore;
+                       return mc.IsClsCompliaceRequired (ds);
+               }
+
+               public static void VerifyModulesClsCompliance ()
+               {
+                       Module[] modules = TypeManager.Modules;
+                       if (modules == null)
+                               return;
+
+                       // The first module is generated assembly
+                       for (int i = 1; i < modules.Length; ++i) {
+                               Module module = modules [i];
+                               if (!IsClsCompliant (module)) {
+                                       Report.Error_T (3013, module.Name);
+                                       return;
+                               }
+                       }
+               }
+
+               static bool IsClsCompliant (ICustomAttributeProvider attribute_provider) 
+               {
+                       object[] CompliantAttribute = attribute_provider.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
+                       if (CompliantAttribute.Length == 0)
+                               return false;
+
+                       return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;
+               }
+
+               static bool AnalyzeTypeCompliance (Type type)
+               {
+                       DeclSpace ds = TypeManager.LookupDeclSpace (type);
+                       if (ds != null) {
+                               return ds.IsClsCompliaceRequired (ds.Parent);
+                       }
+
+                       if (type.IsGenericParameter)
+                               return false;
+
+                       object[] CompliantAttribute = type.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
+                       if (CompliantAttribute.Length == 0) 
+                               return IsClsCompliant (type.Assembly);
+
+                       return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;
+               }
+
+               /// <summary>
+               /// Returns instance of ObsoleteAttribute when method is obsolete
+               /// </summary>
+               public static ObsoleteAttribute GetMethodObsoleteAttribute (MethodBase mb)
+               {
+                       IMethodData mc = TypeManager.GetMethod (mb);
+                       if (mc != null) 
+                               return mc.GetObsoleteAttribute ();
+
+                       // TODO: remove after Constructor will be ready for IMethodData
+                       if (mb.DeclaringType is TypeBuilder)
+                               return null;
+
+                       return GetMemberObsoleteAttribute (mb);
+               }
+
+               /// <summary>
+               /// Returns instance of ObsoleteAttribute when member is obsolete
+               /// </summary>
+               public static ObsoleteAttribute GetMemberObsoleteAttribute (MemberInfo mi)
+               {
+                       object type_obsolete = analyzed_member_obsolete [mi];
+                       if (type_obsolete == FALSE)
+                               return null;
+
+                       if (type_obsolete != null)
+                               return (ObsoleteAttribute)type_obsolete;
+
+                       ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false) as ObsoleteAttribute;
+                       analyzed_member_obsolete.Add (mi, oa == null ? FALSE : oa);
+                       return oa;
+               }
+
+               /// <summary>
+               /// Common method for Obsolete error/warning reporting.
+               /// </summary>
+               public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc)
+               {
+                       if (oa.IsError) {
+                               Report.Error_T (619, loc, member, oa.Message);
+                               return;
+                       }
+
+                       if (oa.Message == null) {
+                               Report.Warning_T (612, loc, member);
+                               return;
+                       }
+                       Report.Warning_T (618, loc, member, oa.Message);
+               }
+       }
+}