2007-03-15 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / mcs / attribute.cs
index 19afc6c1ae7656b2675b06e4bbf6d05e2551f374..c92254c81d07442e755f1f219939389aba30922d 100644 (file)
@@ -21,6 +21,7 @@ using System.Runtime.CompilerServices;
 using System.Security; 
 using System.Security.Permissions;
 using System.Text;
+using System.IO;
 
 namespace Mono.CSharp {
 
@@ -31,11 +32,12 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Attributes for this type
                /// </summary>
-               Attributes attributes;
+               protected Attributes attributes;
 
                public Attributable (Attributes attrs)
                {
-                       attributes = attrs;
+                       if (attrs != null)
+                               OptAttributes = attrs;
                }
 
                public Attributes OptAttributes 
@@ -45,6 +47,10 @@ namespace Mono.CSharp {
                        }
                        set {
                                attributes = value;
+
+                               if (attributes != null) {
+                                       attributes.AttachTo (this);
+                               }
                        }
                }
 
@@ -58,7 +64,9 @@ namespace Mono.CSharp {
                /// </summary>
                public abstract AttributeTargets AttributeTargets { get; }
 
-               public abstract bool IsClsCompliaceRequired (DeclSpace ds);
+               public abstract IResolveContext ResolveContext { get; }
+
+               public abstract bool IsClsComplianceRequired ();
 
                /// <summary>
                /// Gets list of valid attribute targets for explicit target declaration.
@@ -71,19 +79,27 @@ namespace Mono.CSharp {
                public readonly string ExplicitTarget;
                public AttributeTargets Target;
 
+               // TODO: remove this member
                public readonly string    Name;
                public readonly Expression LeftExpr;
                public readonly string Identifier;
 
-               public readonly ArrayList Arguments;
+               readonly ArrayList PosArguments;
+               ArrayList NamedArguments;
 
                public readonly Location Location;
 
                public Type Type;
 
                bool resolve_error;
+               readonly bool nameEscaped;
+
+               // It can contain more onwers when the attribute is applied to multiple fiels.
+               Attributable[] owners;
 
-               static AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
+               static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
+               static Assembly orig_sec_assembly;
+               public static readonly object[] EmptyObject = new object [0];
 
                // non-null if named args present after Resolve () is called
                PropertyInfo [] prop_info_arr;
@@ -92,42 +108,89 @@ namespace Mono.CSharp {
                object [] prop_values_arr;
                object [] pos_values;
 
-               static PtrHashtable usage_attr_cache = new PtrHashtable ();
+               static PtrHashtable usage_attr_cache;
+               // Cache for parameter-less attributes
+               static PtrHashtable att_cache;
                
-               public Attribute (string target, Expression left_expr, string identifier, ArrayList args, Location loc)
+               public Attribute (string target, Expression left_expr, string identifier, object[] args, Location loc, bool nameEscaped)
                {
                        LeftExpr = left_expr;
                        Identifier = identifier;
                        Name = LeftExpr == null ? identifier : LeftExpr + "." + identifier;
-                       Arguments = args;
+                       if (args != null) {
+                               PosArguments = (ArrayList)args [0];
+                               NamedArguments = (ArrayList)args [1];                           
+                       }
                        Location = loc;
                        ExplicitTarget = target;
+                       this.nameEscaped = nameEscaped;
+               }
+
+               static Attribute ()
+               {
+                       Reset ();
+               }
+
+               public static void Reset ()
+               {
+                       usage_attr_cache = new PtrHashtable ();
+                       att_cache = new PtrHashtable ();
+               }
+
+               public void AttachTo (Attributable owner)
+               {
+                       if (this.owners == null) {
+                               this.owners = new Attributable[1] { owner };
+                               return;
+                       }
+
+                       // When the same attribute is attached to multiple fiels
+                       // we use this extra_owners as a list of owners. The attribute
+                       // then can be removed because will be emitted when first owner
+                       // is served
+                       Attributable[] new_array = new Attributable [this.owners.Length + 1];
+                       owners.CopyTo (new_array, 0);
+                       new_array [owners.Length] = owner;
+                       this.owners = new_array;
+                       owner.OptAttributes = null;
                }
 
                void Error_InvalidNamedArgument (string name)
                {
-                       Report.Error (617, Location, "Invalid attribute argument: '{0}'.  Argument must be fields " +
-                                     "fields which are not readonly, static or const;  or read-write instance properties.",
-                                     name);
+                       Report.Error (617, Location, "`{0}' is not a valid named attribute argument. Named attribute arguments " +
+                                     "must be fields which are not readonly, static, const or read-write properties which are " +
+                                     "public and not static",
+                             name);
                }
 
                void Error_InvalidNamedAgrumentType (string name)
                {
-                       Report.Error (655, Location, "'{0}' is not a valid named attribute argument because its type is not valid attribute type", name);
+                       Report.Error (655, Location, "`{0}' is not a valid named attribute argument because it is not a valid " +
+                                     "attribute parameter type", name);
                }
 
-               static void Error_AttributeArgumentNotValid (string extra, Location loc)
+               public static void Error_AttributeArgumentNotValid (Location loc)
                {
                        Report.Error (182, loc,
                                      "An attribute argument must be a constant expression, typeof " +
-                                     "expression or array creation expression" + extra);
+                                     "expression or array creation expression");
+               }
+               
+               static void Error_TypeParameterInAttribute (Location loc)
+               {
+                       Report.Error (
+                               -202, loc, "Can not use a type parameter in an attribute");
                }
 
-               static void Error_AttributeArgumentNotValid (Location loc)
+               public void Error_MissingGuidAttribute ()
                {
-                       Error_AttributeArgumentNotValid ("", loc);
+                       Report.Error (596, Location, "The Guid attribute must be specified with the ComImport attribute");
+               }
+
+               public void Error_MisusedExtensionAttribute ()
+               {
+                       Report.Error (1112, Location, "Do not use `{0}' directly. Use parameter modifier `this' instead", GetSignatureForError ());
                }
-               
 
                /// <summary>
                /// This is rather hack. We report many emit attribute error with same error to be compatible with
@@ -135,7 +198,8 @@ namespace Mono.CSharp {
                /// </summary>
                public void Error_AttributeEmitError (string inner)
                {
-                       Report.Error (647, Location, "Error emitting '{0}' attribute because '{1}'", Name, inner);
+                       Report.Error (647, Location, "Error during emitting `{0}' attribute. The reason is `{1}'",
+                                     TypeManager.CSharpName (Type), inner);
                }
 
                public void Error_InvalidSecurityParent ()
@@ -143,166 +207,131 @@ namespace Mono.CSharp {
                        Error_AttributeEmitError ("it is attached to invalid parent");
                }
 
-               void Error_AttributeConstructorMismatch ()
-               {
-                       Report.Error (-6, Location,
-                                      "Could not find a constructor for this argument list.");
+               Attributable Owner {
+                       get {
+                               return owners [0];
+                       }
                }
 
-
-               protected virtual FullNamedExpression ResolveAsTypeStep (Expression expr, EmitContext ec)
+               protected virtual TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec, bool silent)
                {
-                       return expr.ResolveAsTypeStep (ec);
+                       return expr.ResolveAsTypeTerminal (ec, silent);
                }
 
-               void ResolvePossibleAttributeTypes (EmitContext ec, out Type t1, out Type t2)
+               Type ResolvePossibleAttributeType (string name, bool silent, ref bool is_attr)
                {
-                       t1 = null;
-                       t2 = null;
+                       IResolveContext rc = Owner.ResolveContext;
 
-                       FullNamedExpression n1 = null;
-                       FullNamedExpression n2 = null;
-                       string IdentifierAttribute = Identifier + "Attribute";
+                       TypeExpr te;
                        if (LeftExpr == null) {
-                               n1 = ResolveAsTypeStep (new SimpleName (Identifier, Location), ec);
-
-                               // FIXME: Shouldn't do this for quoted attributes: [@A]
-                               n2 = ResolveAsTypeStep (new SimpleName (IdentifierAttribute, Location), ec);
+                               te = ResolveAsTypeTerminal (new SimpleName (name, Location), rc, silent);
                        } else {
-                               FullNamedExpression l = ResolveAsTypeStep (LeftExpr, ec);
-                               if (l == null) {
-                                       Report.Error (246, Location, "Couldn't find namespace or type '{0}'", LeftExpr);
-                                       return;
-                               }
-                               n1 = new MemberAccess (l, Identifier, Location).ResolveNamespaceOrType (ec, true);
-
-                               // FIXME: Shouldn't do this for quoted attributes: [X.@A]
-                               n2 = new MemberAccess (l, IdentifierAttribute, Location).ResolveNamespaceOrType (ec, true);
+                               te = ResolveAsTypeTerminal (new MemberAccess (LeftExpr, name), rc, silent);
                        }
 
-                       TypeExpr te1 = n1 == null ? null : n1 as TypeExpr;
-                       TypeExpr te2 = n2 == null ? null : n2 as TypeExpr;                      
+                       if (te == null)
+                               return null;
 
-                       if (te1 != null)
-                               t1 = te1.ResolveType (ec);
-                       if (te2 != null)
-                               t2 = te2.ResolveType (ec);
+                       Type t = te.Type;
+                       if (TypeManager.IsSubclassOf (t, TypeManager.attribute_type)) {
+                               is_attr = true;
+                       } else if (!silent) {
+                               Report.SymbolRelatedToPreviousError (t);
+                               Report.Error (616, Location, "`{0}': is not an attribute class", TypeManager.CSharpName (t));
+                       }
+                       return t;
                }
 
                /// <summary>
-                ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
-                /// </summary>
-               Type CheckAttributeType (EmitContext ec)
+               ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
+               /// </summary>
+               void ResolveAttributeType ()
                {
-                       Type t1, t2;
-
-                       ResolvePossibleAttributeTypes (ec, out t1, out t2);
+                       bool t1_is_attr = false;
+                       Type t1 = ResolvePossibleAttributeType (Identifier, true, ref t1_is_attr);
 
-                       String err0616 = null;
+                       bool t2_is_attr = false;
+                       Type t2 = nameEscaped ? null :
+                               ResolvePossibleAttributeType (Identifier + "Attribute", true, ref t2_is_attr);
 
-                       if (t1 != null && ! t1.IsSubclassOf (TypeManager.attribute_type)) {
-                               t1 = null;
-                               err0616 = "'{0}' is not an attribute class";
-                       }
-                       if (t2 != null && ! t2.IsSubclassOf (TypeManager.attribute_type)) {
-                               t2 = null;
-                               err0616 = (err0616 != null) 
-                                       ? "Neither '{0}' nor '{0}Attribute' is an attribute class"
-                                       : "'{0}Attribute': is not an attribute class";
+                       if (t1_is_attr && t2_is_attr) {
+                               Report.Error (1614, Location, "`{0}' is ambiguous between `{0}' and `{0}Attribute'. " +
+                                             "Use either `@{0}' or `{0}Attribute'", GetSignatureForError ());
+                               resolve_error = true;
+                               return;
                        }
 
-                       if (t1 != null && t2 != null) {
-                               Report.Error (1614, Location, "'{0}' is ambiguous; use either '@{0}' or '{0}Attribute'", Name);
-                               return null;
+                       if (t1_is_attr) {
+                               Type = t1;
+                               return;
                        }
-                       if (t1 != null)
-                               return t1;
-                       if (t2 != null)
-                               return t2;
 
-                       if (err0616 != null) {
-                               Report.Error (616, Location, err0616, Name);
-                               return null;
+                       if (t2_is_attr) {
+                               Type = t2;
+                               return;
                        }
 
-                       Report.Error (246, Location, 
-                                     "Could not find attribute '{0}' (are you missing a using directive or an assembly reference ?)",
-                                     Name);
+                       if (t1 == null && t2 == null)
+                               ResolvePossibleAttributeType (Identifier, false, ref t1_is_attr);
+                       if (t1 != null)
+                               ResolvePossibleAttributeType (Identifier, false, ref t1_is_attr);
+                       if (t2 != null)
+                               ResolvePossibleAttributeType (Identifier + "Attribute", false, ref t2_is_attr);
 
                        resolve_error = true;
-                       return null;
                }
 
-               public virtual Type ResolveType (EmitContext ec)
+               public virtual Type ResolveType ()
                {
                        if (Type == null && !resolve_error)
-                               Type = CheckAttributeType (ec);
+                               ResolveAttributeType ();
                        return Type;
                }
 
-               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, Type arg_type, out object result)
+               public string GetSignatureForError ()
                {
-                       if (e is EnumConstant) {
-                               if (RootContext.StdLib)
-                                       result = ((EnumConstant)e).GetValueAsEnumType ();
-                               else
-                                       result = ((EnumConstant)e).GetValue ();
+                       if (Type != null)
+                               return TypeManager.CSharpName (Type);
 
-                               return true;
-                       }
-
-                       Constant constant = e as Constant;
-                       if (constant != null) {
-                               if (e.Type != arg_type) {
-                                       constant = Const.ChangeType (loc, constant, arg_type);
-                                       if (constant == null) {
-                                               result = null;
-                                               Error_AttributeArgumentNotValid (loc);
-                                               return false;
-                                       }
-                               }
-                               result = constant.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) {
-                               Expression child = ((EmptyCast)e).Child;
-                               return GetAttributeArgumentExpression (child, loc, child.Type, out result);
-                       }
-
-                       result = null;
-                       Error_AttributeArgumentNotValid (loc);
-                       return false;
+                       return LeftExpr == null ? Identifier : LeftExpr.GetSignatureForError () + "." + Identifier;
                }
 
                bool IsValidArgumentType (Type t)
                {
+                       if (t.IsArray)
+                               t = t.GetElementType ();
+
                        return TypeManager.IsPrimitiveType (t) ||
-                               (t.IsArray && TypeManager.IsPrimitiveType (t.GetElementType ())) ||
                                TypeManager.IsEnumType (t) ||
                                t == TypeManager.string_type ||
                                t == TypeManager.object_type ||
                                t == TypeManager.type_type;
                }
 
-               // Cache for parameter-less attributes
-               static PtrHashtable att_cache = new PtrHashtable ();
+               [Conditional ("GMCS_SOURCE")]
+               void ApplyModuleCharSet ()
+               {
+                       if (Type != TypeManager.dllimport_type)
+                               return;
+
+                       if (!CodeGen.Module.HasDefaultCharSet)
+                               return;
+
+                       const string CharSetEnumMember = "CharSet";
+                       if (NamedArguments == null) {
+                               NamedArguments = new ArrayList (1);
+                       } else {
+                               foreach (DictionaryEntry de in NamedArguments) {
+                                       if ((string)de.Key == CharSetEnumMember)
+                                               return;
+                               }
+                       }
+                       
+                       NamedArguments.Add (new DictionaryEntry (CharSetEnumMember,
+                               new Argument (Constant.CreateConstant (typeof (CharSet), CodeGen.Module.DefaultCharSet, Location))));
+               }
 
-               public CustomAttributeBuilder Resolve (EmitContext ec)
+               public CustomAttributeBuilder Resolve ()
                {
                        if (resolve_error)
                                return null;
@@ -310,18 +339,22 @@ namespace Mono.CSharp {
                        resolve_error = true;
 
                        if (Type == null) {
-                               Type = CheckAttributeType (ec);
-
+                               ResolveAttributeType ();
                                if (Type == null)
                                        return null;
                        }
 
                        if (Type.IsAbstract) {
-                               Report.Error (653, Location, "Cannot apply attribute class '{0}' because it is abstract", Name);
+                               Report.Error (653, Location, "Cannot apply attribute class `{0}' because it is abstract", GetSignatureForError ());
                                return null;
                        }
 
-                       if (Arguments == null) {
+                       ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (Type);
+                       if (obsolete_attr != null) {
+                               AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location);
+                       }
+
+                       if (PosArguments == null && NamedArguments == null) {
                                object o = att_cache [Type];
                                if (o != null) {
                                        resolve_error = false;
@@ -329,279 +362,299 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       ConstructorInfo ctor = ResolveArguments (ec);
-                       CustomAttributeBuilder cb;
+                       Attributable owner = Owner;
+                       EmitContext ec = new EmitContext (owner.ResolveContext, owner.ResolveContext.DeclContainer, owner.ResolveContext.DeclContainer,
+                               Location, null, null, owner.ResolveContext.DeclContainer.ModFlags, false);
+                       ec.IsAnonymousMethodAllowed = false;
+
+                       ConstructorInfo ctor = ResolveConstructor (ec);
+                       if (ctor == null) {
+                               if (Type is TypeBuilder && 
+                                   TypeManager.LookupDeclSpace (Type).MemberCache == null)
+                                       // The attribute type has been DefineType'd, but not Defined.  Let's not treat it as an error.
+                                       // It'll be resolved again when the attached-to entity is emitted.
+                                       resolve_error = false;
+                               return null;
+                       }
 
+                       ApplyModuleCharSet ();
+
+                       CustomAttributeBuilder cb;
                        try {
-                               if (prop_info_arr != null || field_info_arr != null) {
-                                       cb = new CustomAttributeBuilder (
-                                               ctor, pos_values,
-                                               prop_info_arr, prop_values_arr,
-                                               field_info_arr, field_values_arr);
-                               } else {
-                                       cb = new CustomAttributeBuilder (
-                                               ctor, pos_values);
+                               if (NamedArguments == null) {
+                                       cb = new CustomAttributeBuilder (ctor, pos_values);
 
                                        if (pos_values.Length == 0)
                                                att_cache.Add (Type, cb);
+
+                                       resolve_error = false;
+                                       return cb;
                                }
+
+                               if (!ResolveNamedArguments (ec)) {
+                                       return null;
+                               }
+
+                               cb = new CustomAttributeBuilder (ctor, pos_values,
+                                               prop_info_arr, prop_values_arr,
+                                               field_info_arr, field_values_arr);
+
+                               resolve_error = false;
+                               return cb;
                        }
                        catch (Exception) {
                                Error_AttributeArgumentNotValid (Location);
                                return null;
                        }
-
-                       resolve_error = false;
-                       return cb;
                }
 
-               protected virtual ConstructorInfo ResolveArguments (EmitContext ec)
+               protected virtual ConstructorInfo ResolveConstructor (EmitContext ec)
                {
-                       // Now we extract the positional and named arguments
-                       
-                       ArrayList pos_args = null;
-                       ArrayList named_args = null;
-                       int pos_arg_count = 0;
-                       int named_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];
-                                       named_arg_count = named_args.Count;
+                       if (PosArguments != null) {
+                               for (int i = 0; i < PosArguments.Count; i++) {
+                                       Argument a = (Argument) PosArguments [i];
+
+                                       if (!a.Resolve (ec, Location))
+                                               return null;
                                }
                        }
 
+                       Expression mg = Expression.MemberLookup (ec.ContainerType,
+                               Type, ".ctor", MemberTypes.Constructor,
+                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Location);
+
+                       if (mg == null)
+                               return null;
+
+                       MethodBase constructor = ((MethodGroupExpr)mg).OverloadResolve (
+                               ec, PosArguments, false, Location);
+
+                       if (constructor == null)
+                               return null;
+
+                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (constructor);
+                       if (oa != null && !Owner.ResolveContext.IsInObsoleteScope) {
+                               AttributeTester.Report_ObsoleteMessage (oa, mg.GetSignatureForError (), mg.Location);
+                       }
+
+                       if (PosArguments == null) {
+                               pos_values = EmptyObject;
+                               return (ConstructorInfo)constructor;
+                       }
+
+                       ParameterData pd = TypeManager.GetParameterData (constructor);
+
+                       int pos_arg_count = PosArguments.Count;
+                       int last_real_param = pd.Count;
+
                        pos_values = new object [pos_arg_count];
 
-                       //
-                       // First process positional arguments 
-                       //
+                       if (pd.HasParams) {
+                               // When the params is not filled we need to put one
+                               if (last_real_param > pos_arg_count) {
+                                       object [] new_pos_values = new object [pos_arg_count + 1];
+                                       pos_values.CopyTo (new_pos_values, 0);
+                                       new_pos_values [pos_arg_count] = new object [] {} ;
+                                       pos_values = new_pos_values;
+                               }
+                               last_real_param--;
+                       }
 
-                       int i;
-                       for (i = 0; i < pos_arg_count; i++) {
-                               Argument a = (Argument) pos_args [i];
-                               Expression e;
+                       for (int j = 0; j < pos_arg_count; ++j) {
+                               Argument a = (Argument) PosArguments [j];
 
-                               if (!a.Resolve (ec, Location))
+                               if (!a.Expr.GetAttributableValue (a.Type, out pos_values [j]))
                                        return null;
+                               
+                               if (j < last_real_param)
+                                       continue;
+                               
+                               if (j == last_real_param) {
+                                       object [] array = new object [pos_arg_count - last_real_param];
+                                       array [0] = pos_values [j];
+                                       pos_values [j] = array;
+                                       continue;
+                               }
 
-                               e = a.Expr;
+                               object [] params_array = (object []) pos_values [last_real_param];
+                               params_array [j - last_real_param] = pos_values [j];
+                       }
 
-                               object val;
-                               if (!GetAttributeArgumentExpression (e, Location, a.Type, out val))
+                       // Adjust the size of the pos_values if it had params
+                       if (last_real_param != pos_arg_count) {
+                               object [] new_pos_values = new object [last_real_param + 1];
+                               Array.Copy (pos_values, new_pos_values, last_real_param + 1);
+                               pos_values = new_pos_values;
+                       }
+
+                       // Here we do the checks which should be done by corlib or by runtime.
+                       // However Zoltan doesn't like it and every Mono compiler has to do it again.
+                       
+                       if (Type == TypeManager.guid_attr_type) {
+                               try {
+                                       new Guid ((string)pos_values [0]);
+                               }
+                               catch (Exception e) {
+                                       Error_AttributeEmitError (e.Message);
                                        return null;
+                               }
+                       }
 
-                               pos_values [i] = val;
+                       if (Type == TypeManager.attribute_usage_type && (int)pos_values [0] == 0) {
+                               Report.Error (591, Location, "Invalid value for argument to `System.AttributeUsage' attribute");
+                               return null;
+                       }
 
-                               if (i == 0 && Type == TypeManager.attribute_usage_type && (int)val == 0) {
-                                       Report.Error (591, Location, "Invalid value for argument to 'System.AttributeUsage' attribute");
+                       if (Type == TypeManager.indexer_name_type || Type == TypeManager.conditional_attribute_type) {
+                               if (!Tokenizer.IsValidIdentifier ((string)pos_values [0])) {
+                                       Report.Error (633, ((Argument)PosArguments[0]).Expr.Location,
+                                               "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
                                        return null;
                                }
                        }
 
-                       //
-                       // Now process named arguments
-                       //
+                       if (Type == TypeManager.methodimpl_attr_type && pos_values.Length == 1 &&
+                               pd.ParameterType (0) == TypeManager.short_type &&
+                               !System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0].ToString ())) {
+                               Error_AttributeEmitError ("Incorrect argument value.");
+                               return null;
+                       }
 
-                       ArrayList field_infos = null;
-                       ArrayList prop_infos  = null;
-                       ArrayList field_values = null;
-                       ArrayList prop_values = null;
-                       Hashtable seen_names = null;
+                       return (ConstructorInfo)constructor;
+               }
 
-                       if (named_arg_count > 0) {
-                               field_infos = new ArrayList ();
-                               prop_infos  = new ArrayList ();
-                               field_values = new ArrayList ();
-                               prop_values = new ArrayList ();
+               protected virtual bool ResolveNamedArguments (EmitContext ec)
+               {
+                       int named_arg_count = NamedArguments.Count;
 
-                               seen_names = new Hashtable();
-                       }
+                       ArrayList field_infos = new ArrayList (named_arg_count);
+                       ArrayList prop_infos  = new ArrayList (named_arg_count);
+                       ArrayList field_values = new ArrayList (named_arg_count);
+                       ArrayList prop_values = new ArrayList (named_arg_count);
+
+                       ArrayList seen_names = new ArrayList(named_arg_count);
                        
-                       for (i = 0; i < named_arg_count; i++) {
-                               DictionaryEntry de = (DictionaryEntry) named_args [i];
+                       foreach (DictionaryEntry de in NamedArguments) {
                                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;
+                                       return false;
                                }                               
-                               seen_names.Add(member_name, 1);
-                               
+                               seen_names.Add(member_name);
+
+                               Argument a = (Argument) de.Value;
                                if (!a.Resolve (ec, Location))
-                                       return null;
+                                       return false;
 
                                Expression member = Expression.MemberLookup (
-                                       ec, Type, member_name,
+                                       ec.ContainerType, Type, member_name,
                                        MemberTypes.Field | MemberTypes.Property,
                                        BindingFlags.Public | BindingFlags.Instance,
                                        Location);
 
                                if (member == null) {
-                                       member = Expression.MemberLookup (ec, Type, member_name,
+                                       member = Expression.MemberLookup (ec.ContainerType, Type, member_name,
                                                MemberTypes.Field | MemberTypes.Property, BindingFlags.NonPublic | BindingFlags.Instance,
                                                Location);
 
                                        if (member != null) {
-                                               Report.Error (122, Location, "'{0}' is inaccessible due to its protection level", GetFullMemberName (member_name));
-                                               return null;
+                                               Report.SymbolRelatedToPreviousError (member.Type);
+                                               Expression.ErrorIsInaccesible (Location, member.GetSignatureForError ());
+                                               return false;
                                        }
                                }
 
                                if (member == null){
-                                       Report.Error (117, Location, "Attribute `{0}' does not contain a definition for `{1}'",
-                                                     Type, member_name);
-                                       return null;
+                                       Expression.Error_TypeDoesNotContainDefinition (Location, Type, member_name);
+                                       return false;
                                }
                                
                                if (!(member is PropertyExpr || member is FieldExpr)) {
                                        Error_InvalidNamedArgument (member_name);
-                                       return null;
+                                       return false;
+                               }
+
+                               if (a.Expr is TypeParameterExpr){
+                                       Error_TypeParameterInAttribute (Location);
+                                       return false;
                                }
 
-                               e = a.Expr;
+                               ObsoleteAttribute obsolete_attr;
+
                                if (member is PropertyExpr) {
-                                       PropertyExpr pe = (PropertyExpr) member;
-                                       PropertyInfo pi = pe.PropertyInfo;
+                                       PropertyInfo pi = ((PropertyExpr) member).PropertyInfo;
 
                                        if (!pi.CanWrite || !pi.CanRead) {
                                                Report.SymbolRelatedToPreviousError (pi);
                                                Error_InvalidNamedArgument (member_name);
-                                               return null;
+                                               return false;
                                        }
 
                                        if (!IsValidArgumentType (pi.PropertyType)) {
                                                Report.SymbolRelatedToPreviousError (pi);
                                                Error_InvalidNamedAgrumentType (member_name);
-                                               return null;
+                                               return false;
                                        }
 
                                        object value;
-                                       if (!GetAttributeArgumentExpression (e, Location, pi.PropertyType, out value))
-                                               return null;
+                                       if (!a.Expr.GetAttributableValue (pi.PropertyType, out value))
+                                               return false;
+
+                                       PropertyBase pb = TypeManager.GetProperty (pi);
+                                       if (pb != null)
+                                               obsolete_attr = pb.GetObsoleteAttribute ();
+                                       else
+                                               obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (pi);
 
                                        prop_values.Add (value);
                                        prop_infos.Add (pi);
                                        
-                               } else if (member is FieldExpr) {
-                                       FieldExpr fe = (FieldExpr) member;
-                                       FieldInfo fi = fe.FieldInfo;
+                               } else {
+                                       FieldInfo fi = ((FieldExpr) member).FieldInfo;
 
                                        if (fi.IsInitOnly) {
                                                Error_InvalidNamedArgument (member_name);
-                                               return null;
+                                               return false;
                                        }
 
                                        if (!IsValidArgumentType (fi.FieldType)) {
                                                Report.SymbolRelatedToPreviousError (fi);
                                                Error_InvalidNamedAgrumentType (member_name);
-                                               return null;
+                                               return false;
                                        }
 
                                        object value;
-                                       if (!GetAttributeArgumentExpression (e, Location, fi.FieldType, out value))
-                                               return null;
+                                       if (!a.Expr.GetAttributableValue (fi.FieldType, out value))
+                                               return false;
+
+                                       FieldBase fb = TypeManager.GetField (fi);
+                                       if (fb != null)
+                                               obsolete_attr = fb.GetObsoleteAttribute ();
+                                       else
+                                               obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (fi);
 
                                        field_values.Add (value);                                       
                                        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;
+                               if (obsolete_attr != null && !Owner.ResolveContext.IsInObsoleteScope)
+                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location);
                        }
 
-                       MethodBase constructor = Invocation.OverloadResolve (
-                               ec, (MethodGroupExpr) mg, pos_args, false, Location);
+                       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];
 
-                       if (constructor == null) {
-                               return null;
-                       }
+                       field_infos.CopyTo  (field_info_arr, 0);
+                       field_values.CopyTo (field_values_arr, 0);
 
-                       //
-                       // Now we perform some checks on the positional args as they
-                       // cannot be null for a constructor which expects a parameter
-                       // of type object
-                       //
+                       prop_values.CopyTo  (prop_values_arr, 0);
+                       prop_infos.CopyTo   (prop_info_arr, 0);
 
-                       ParameterData pd = TypeManager.GetParameterData (constructor);
-
-                       int last_real_param = pd.Count;
-                       if (pd.HasParams) {
-                               // When the params is not filled we need to put one
-                               if (last_real_param > pos_arg_count) {
-                                       object [] new_pos_values = new object [pos_arg_count + 1];
-                                       pos_values.CopyTo (new_pos_values, 0);
-                                       new_pos_values [pos_arg_count] = new object [] {} ;
-                                       pos_values = new_pos_values;
-                               }
-                               last_real_param--;
-                       }
-
-                       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;
-                               }
-
-                               object value = pos_values [j];
-                               if (value != null && a.Type != value.GetType () && TypeManager.IsPrimitiveType (a.Type)) {
-                                       bool fail;
-                                       pos_values [j] = TypeManager.ChangeType (value, a.Type, out fail);
-                                       if (fail) {
-                                               // TODO: Can failed ?
-                                               throw new NotImplementedException ();
-                                       }
-                               }
-
-                               if (j < last_real_param)
-                                       continue;
-                               
-                               if (j == last_real_param) {
-                                       object [] array = new object [pos_arg_count - last_real_param];
-                                       array [0] = pos_values [j];
-                                       pos_values [j] = array;
-                                       continue;
-                               }
-
-                               object [] params_array = (object []) pos_values [last_real_param];
-                               params_array [j - last_real_param] = pos_values [j];
-                       }
-
-                       // Adjust the size of the pos_values if it had params
-                       if (last_real_param != pos_arg_count) {
-                               object [] new_pos_values = new object [last_real_param + 1];
-                               Array.Copy (pos_values, new_pos_values, last_real_param + 1);
-                               pos_values = new_pos_values;
-                       }
-
-                       if (named_arg_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);
-                       }
-
-                       return (ConstructorInfo) constructor;
+                       return true;
                }
 
                /// <summary>
@@ -610,58 +663,61 @@ namespace Mono.CSharp {
                public string GetValidTargets ()
                {
                        StringBuilder sb = new StringBuilder ();
-                       AttributeTargets targets = GetAttributeUsage (null).ValidOn;
+                       AttributeTargets targets = GetAttributeUsage ().ValidOn;
 
                        if ((targets & AttributeTargets.Assembly) != 0)
-                               sb.Append ("'assembly' ");
+                               sb.Append ("assembly, ");
 
-                       if ((targets & AttributeTargets.Class) != 0)
-                               sb.Append ("'class' ");
+                       if ((targets & AttributeTargets.Module) != 0)
+                               sb.Append ("module, ");
 
-                       if ((targets & AttributeTargets.Constructor) != 0)
-                               sb.Append ("'constructor' ");
+                       if ((targets & AttributeTargets.Class) != 0)
+                               sb.Append ("class, ");
 
-                       if ((targets & AttributeTargets.Delegate) != 0)
-                               sb.Append ("'delegate' ");
+                       if ((targets & AttributeTargets.Struct) != 0)
+                               sb.Append ("struct, ");
 
                        if ((targets & AttributeTargets.Enum) != 0)
-                               sb.Append ("'enum' ");
+                               sb.Append ("enum, ");
 
-                       if ((targets & AttributeTargets.Event) != 0)
-                               sb.Append ("'event' ");
+                       if ((targets & AttributeTargets.Constructor) != 0)
+                               sb.Append ("constructor, ");
 
-                       if ((targets & AttributeTargets.Field) != 0)
-                               sb.Append ("'field' ");
+                       if ((targets & AttributeTargets.Method) != 0)
+                               sb.Append ("method, ");
 
-                       if ((targets & AttributeTargets.Interface) != 0)
-                               sb.Append ("'interface' ");
+                       if ((targets & AttributeTargets.Property) != 0)
+                               sb.Append ("property, indexer, ");
 
-                       if ((targets & AttributeTargets.Method) != 0)
-                               sb.Append ("'method' ");
+                       if ((targets & AttributeTargets.Field) != 0)
+                               sb.Append ("field, ");
 
-                       if ((targets & AttributeTargets.Module) != 0)
-                               sb.Append ("'module' ");
+                       if ((targets & AttributeTargets.Event) != 0)
+                               sb.Append ("event, ");
+
+                       if ((targets & AttributeTargets.Interface) != 0)
+                               sb.Append ("interface, ");
 
                        if ((targets & AttributeTargets.Parameter) != 0)
-                               sb.Append ("'parameter' ");
+                               sb.Append ("parameter, ");
 
-                       if ((targets & AttributeTargets.Property) != 0)
-                               sb.Append ("'property' ");
+                       if ((targets & AttributeTargets.Delegate) != 0)
+                               sb.Append ("delegate, ");
 
                        if ((targets & AttributeTargets.ReturnValue) != 0)
-                               sb.Append ("'return' ");
-
-                       if ((targets & AttributeTargets.Struct) != 0)
-                               sb.Append ("'struct' ");
-
-                       return sb.ToString ();
+                               sb.Append ("return, ");
 
+#if NET_2_0
+                       if ((targets & AttributeTargets.GenericParameter) != 0)
+                               sb.Append ("type parameter, ");
+#endif                 
+                       return sb.Remove (sb.Length - 2, 2).ToString ();
                }
 
                /// <summary>
                /// Returns AttributeUsage attribute for this type
                /// </summary>
-               AttributeUsageAttribute GetAttributeUsage (EmitContext ec)
+               AttributeUsageAttribute GetAttributeUsage ()
                {
                        AttributeUsageAttribute ua = usage_attr_cache [Type] as AttributeUsageAttribute;
                        if (ua != null)
@@ -678,22 +734,22 @@ namespace Mono.CSharp {
 
                        Attribute a = attr_class.OptAttributes == null
                                ? null
-                               : attr_class.OptAttributes.Search (TypeManager.attribute_usage_type, attr_class.EmitContext);
+                               : attr_class.OptAttributes.Search (TypeManager.attribute_usage_type);
 
                        ua = a == null
                                ? DefaultUsageAttribute 
-                               : a.GetAttributeUsageAttribute (attr_class.EmitContext);
+                               : a.GetAttributeUsageAttribute ();
 
                        usage_attr_cache.Add (Type, ua);
                        return ua;
                }
 
-               AttributeUsageAttribute GetAttributeUsageAttribute (EmitContext ec)
+               AttributeUsageAttribute GetAttributeUsageAttribute ()
                {
                        if (pos_values == null)
                                // 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);
+                               Resolve ();
 
                        if (resolve_error)
                                return DefaultUsageAttribute;
@@ -714,12 +770,12 @@ namespace Mono.CSharp {
                /// <summary>
                /// Returns custom name of indexer
                /// </summary>
-               public string GetIndexerAttributeValue (EmitContext ec)
+               public string GetIndexerAttributeValue ()
                {
                        if (pos_values == null)
                                // 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);
+                               Resolve ();
 
                        if (resolve_error)
                                return null;
@@ -730,12 +786,12 @@ namespace Mono.CSharp {
                /// <summary>
                /// Returns condition of ConditionalAttribute
                /// </summary>
-               public string GetConditionalAttributeValue (EmitContext ec)
+               public string GetConditionalAttributeValue ()
                {
                        if (pos_values == null)
                                // 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);
+                               Resolve ();
 
                        if (resolve_error)
                                return null;
@@ -746,12 +802,12 @@ namespace Mono.CSharp {
                /// <summary>
                /// Creates the instance of ObsoleteAttribute from this attribute instance
                /// </summary>
-               public ObsoleteAttribute GetObsoleteAttribute (EmitContext ec)
+               public ObsoleteAttribute GetObsoleteAttribute ()
                {
                        if (pos_values == null)
                                // 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);
+                               Resolve ();
 
                        if (resolve_error)
                                return null;
@@ -770,12 +826,12 @@ namespace Mono.CSharp {
                /// before ApplyAttribute. We need to resolve the arguments.
                /// This situation occurs when class deps is differs from Emit order.  
                /// </summary>
-               public bool GetClsCompliantAttributeValue (EmitContext ec)
+               public bool GetClsCompliantAttributeValue ()
                {
                        if (pos_values == null)
                                // 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);
+                               Resolve ();
 
                        if (resolve_error)
                                return false;
@@ -783,27 +839,79 @@ namespace Mono.CSharp {
                        return (bool)pos_values [0];
                }
 
+               public Type GetCoClassAttributeValue ()
+               {
+                       if (pos_values == null)
+                               Resolve ();
+
+                       if (resolve_error)
+                               return null;
+
+                       return (Type)pos_values [0];
+               }
+
+               public bool CheckTarget ()
+               {
+                       string[] valid_targets = Owner.ValidAttributeTargets;
+                       if (ExplicitTarget == null || ExplicitTarget == valid_targets [0]) {
+                               Target = Owner.AttributeTargets;
+                               return true;
+                       }
+
+                       // TODO: we can skip the first item
+                       if (((IList) valid_targets).Contains (ExplicitTarget)) {
+                               switch (ExplicitTarget) {
+                                       case "return": Target = AttributeTargets.ReturnValue; return true;
+                                       case "param": Target = AttributeTargets.Parameter; return true;
+                                       case "field": Target = AttributeTargets.Field; return true;
+                                       case "method": Target = AttributeTargets.Method; return true;
+                                       case "property": Target = AttributeTargets.Property; return true;
+                               }
+                               throw new InternalErrorException ("Unknown explicit target: " + ExplicitTarget);
+                       }
+                               
+                       StringBuilder sb = new StringBuilder ();
+                       foreach (string s in valid_targets) {
+                               sb.Append (s);
+                               sb.Append (", ");
+                       }
+                       sb.Remove (sb.Length - 2, 2);
+                       Report.Error (657, Location, "`{0}' is not a valid attribute location for this declaration. " +
+                               "Valid attribute locations for this declaration are `{1}'", ExplicitTarget, sb.ToString ());
+                       return false;
+               }
+
                /// <summary>
                /// Tests permitted SecurityAction for assembly or other types
                /// </summary>
                public bool CheckSecurityActionValidity (bool for_assembly)
                {
-                       SecurityAction action  = GetSecurityActionValue ();
-
-                       if ((action == SecurityAction.RequestMinimum || action == SecurityAction.RequestOptional || action == SecurityAction.RequestRefuse) && for_assembly)
-                               return true;
+                       SecurityAction action = GetSecurityActionValue ();
 
-                       if (!for_assembly) {
-                               if (action < SecurityAction.Demand || action > SecurityAction.InheritanceDemand) {
-                                       Error_AttributeEmitError ("SecurityAction is out of range");
-                                       return false;
-                               }
+                       switch (action) {
+                       case SecurityAction.Demand:
+                       case SecurityAction.Assert:
+                       case SecurityAction.Deny:
+                       case SecurityAction.PermitOnly:
+                       case SecurityAction.LinkDemand:
+                       case SecurityAction.InheritanceDemand:
+                               if (!for_assembly)
+                                       return true;
+                               break;
 
-                               if ((action != SecurityAction.RequestMinimum && action != SecurityAction.RequestOptional && action != SecurityAction.RequestRefuse) && !for_assembly)
+                       case SecurityAction.RequestMinimum:
+                       case SecurityAction.RequestOptional:
+                       case SecurityAction.RequestRefuse:
+                               if (for_assembly)
                                        return true;
+                               break;
+
+                       default:
+                               Error_AttributeEmitError ("SecurityAction is out of range");
+                               return false;
                        }
 
-                       Error_AttributeEmitError (String.Concat ("SecurityAction '", action, "' is not valid for this declaration"));
+                       Error_AttributeEmitError (String.Concat ("SecurityAction `", action, "' is not valid for this declaration"));
                        return false;
                }
 
@@ -818,14 +926,35 @@ namespace Mono.CSharp {
                /// <returns></returns>
                public void ExtractSecurityPermissionSet (ListDictionary permissions)
                {
-                       if (TypeManager.LookupDeclSpace (Type) != null && RootContext.StdLib) {
-                               Error_AttributeEmitError ("security custom attributes can not be referenced from defining assembly");
-                               return;
+                       Type orig_assembly_type = null;
+
+                       if (TypeManager.LookupDeclSpace (Type) != null) {
+                               if (!RootContext.StdLib) {
+                                       orig_assembly_type = Type.GetType (Type.FullName);
+                               } else {
+                                       string orig_version_path = Environment.GetEnvironmentVariable ("__SECURITY_BOOTSTRAP_DB");
+                                       if (orig_version_path == null) {
+                                               Error_AttributeEmitError ("security custom attributes can not be referenced from defining assembly");
+                                               return;
+                                       }
+
+                                       if (orig_sec_assembly == null) {
+                                               string file = Path.Combine (orig_version_path, Driver.OutputFile);
+                                               orig_sec_assembly = Assembly.LoadFile (file);
+                                       }
+
+                                       orig_assembly_type = orig_sec_assembly.GetType (Type.FullName, true);
+                                       if (orig_assembly_type == null) {
+                                               Report.Warning (-112, 1, Location, "Self-referenced security attribute `{0}' " +
+                                                               "was not found in previous version of assembly");
+                                               return;
+                                       }
+                               }
                        }
 
                        SecurityAttribute sa;
-                       // For all assemblies except corlib we can avoid all hacks
-                       if (RootContext.StdLib) {
+                       // For all non-selfreferencing security attributes we can avoid all hacks
+                       if (orig_assembly_type == null) {
                                sa = (SecurityAttribute) Activator.CreateInstance (Type, pos_values);
 
                                if (prop_info_arr != null) {
@@ -835,15 +964,14 @@ namespace Mono.CSharp {
                                        }
                                }
                        } else {
-                               Type temp_type = Type.GetType (Type.FullName);
-                               // HACK: All mscorlib attributes have same ctor syntax
-                               sa = (SecurityAttribute) Activator.CreateInstance (temp_type, new object[] { GetSecurityActionValue () } );
+                               // HACK: All security attributes have same ctor syntax
+                               sa = (SecurityAttribute) Activator.CreateInstance (orig_assembly_type, new object[] { GetSecurityActionValue () } );
 
-                               // All types are from newly created corlib but for invocation with old we need to convert them
+                               // All types are from newly created assembly but for invocation with old one we need to convert them
                                if (prop_info_arr != null) {
                                        for (int i = 0; i < prop_info_arr.Length; ++i) {
                                                PropertyInfo emited_pi = prop_info_arr [i];
-                                               PropertyInfo pi = temp_type.GetProperty (emited_pi.Name, emited_pi.PropertyType);
+                                               PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name, emited_pi.PropertyType);
 
                                                object old_instance = pi.PropertyType.IsEnum ?
                                                        System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) :
@@ -888,7 +1016,7 @@ namespace Mono.CSharp {
                        ps.AddPermission (perm);
                }
 
-               object GetValue (object value)
+               static object GetValue (object value)
                {
                        if (value is EnumConstant)
                                return ((EnumConstant) value).GetValue ();
@@ -896,7 +1024,7 @@ namespace Mono.CSharp {
                                return value;                           
                }
 
-               object GetPropertyValue (string name)
+               public object GetPropertyValue (string name)
                {
                        if (prop_info_arr == null)
                                return null;
@@ -923,9 +1051,18 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               //
+               // Theoretically, we can get rid of this, since FieldBuilder.SetCustomAttribute()
+               // and ParameterBuilder.SetCustomAttribute() are supposed to handle this attribute.
+               // However, we can't, since it appears that the .NET 1.1 SRE hangs when given a MarshalAsAttribute.
+               //
                public UnmanagedMarshal GetMarshal (Attributable attr)
                {
-                       UnmanagedType UnmanagedType = (UnmanagedType)System.Enum.Parse (typeof (UnmanagedType), pos_values [0].ToString ());
+                       UnmanagedType UnmanagedType;
+                       if (!RootContext.StdLib || pos_values [0].GetType () != typeof (UnmanagedType))
+                               UnmanagedType = (UnmanagedType) System.Enum.ToObject (typeof (UnmanagedType), pos_values [0]);
+                       else
+                               UnmanagedType = (UnmanagedType) pos_values [0];
 
                        object value = GetFieldValue ("SizeParamIndex");
                        if (value != null && UnmanagedType != UnmanagedType.LPArray) {
@@ -934,12 +1071,12 @@ namespace Mono.CSharp {
                        }
 
                        object o = GetFieldValue ("ArraySubType");
-                       UnmanagedType array_sub_type = o == null ? UnmanagedType.I4 : (UnmanagedType) o;
-                       
+                       UnmanagedType array_sub_type = o == null ? (UnmanagedType) 0x50 /* NATIVE_MAX */ : (UnmanagedType) o;
+
                        switch (UnmanagedType) {
                        case UnmanagedType.CustomMarshaler: {
                                MethodInfo define_custom = typeof (UnmanagedMarshal).GetMethod ("DefineCustom",
-                                                                       BindingFlags.Static | BindingFlags.Public);
+                                       BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                                if (define_custom == null) {
                                        Report.RuntimeMissingSupport (Location, "set marshal info");
                                        return null;
@@ -957,7 +1094,8 @@ namespace Mono.CSharp {
                                object size_param_index = GetFieldValue ("SizeParamIndex");
 
                                if ((size_const != null) || (size_param_index != null)) {
-                                       MethodInfo define_array = typeof (UnmanagedMarshal).GetMethod ("DefineLPArrayInternal", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
+                                       MethodInfo define_array = typeof (UnmanagedMarshal).GetMethod ("DefineLPArrayInternal",
+                                               BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                                        if (define_array == null) {
                                                Report.RuntimeMissingSupport (Location, "set marshal info");
                                                return null;
@@ -974,18 +1112,18 @@ namespace Mono.CSharp {
                        }
                        case UnmanagedType.SafeArray:
                                return UnmanagedMarshal.DefineSafeArray (array_sub_type);
-                       
+
                        case UnmanagedType.ByValArray:
-                               FieldMember fm = attr as FieldMember;
+                               FieldBase fm = attr as FieldBase;
                                if (fm == null) {
                                        Error_AttributeEmitError ("Specified unmanaged type is only valid on fields");
                                        return null;
                                }
                                return UnmanagedMarshal.DefineByValArray ((int) GetFieldValue ("SizeConst"));
-                       
+
                        case UnmanagedType.ByValTStr:
                                return UnmanagedMarshal.DefineByValTStr ((int) GetFieldValue ("SizeConst"));
-                       
+
                        default:
                                return UnmanagedMarshal.DefineUnmanagedMarshal (UnmanagedType);
                        }
@@ -996,62 +1134,94 @@ namespace Mono.CSharp {
                        return (CharSet)System.Enum.Parse (typeof (CharSet), pos_values [0].ToString ());
                }
 
-               public MethodImplOptions GetMethodImplOptions ()
-               {
-                       return (MethodImplOptions)System.Enum.Parse (typeof (MethodImplOptions), pos_values [0].ToString ());
+               public bool IsInternalMethodImplAttribute {
+                       get {
+                               if (Type != TypeManager.methodimpl_attr_type)
+                                       return false;
+
+                               MethodImplOptions options;
+                               if (pos_values[0].GetType () != typeof (MethodImplOptions))
+                                       options = (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values[0]);
+                               else
+                                       options = (MethodImplOptions)pos_values[0];
+
+                               return (options & MethodImplOptions.InternalCall) != 0;
+                       }
                }
 
                public LayoutKind GetLayoutKindValue ()
                {
-                       return (LayoutKind)System.Enum.Parse (typeof (LayoutKind), pos_values [0].ToString ());
+                       if (!RootContext.StdLib || pos_values [0].GetType () != typeof (LayoutKind))
+                               return (LayoutKind)System.Enum.ToObject (typeof (LayoutKind), pos_values [0]);
+
+                       return (LayoutKind)pos_values [0];
+               }
+
+               public object GetParameterDefaultValue ()
+               {
+                       return pos_values [0];
+               }
+
+               public override bool Equals (object obj)
+               {
+                       Attribute a = obj as Attribute;
+                       if (a == null)
+                               return false;
+
+                       return Type == a.Type && Target == a.Target;
+               }
+
+               public override int GetHashCode ()
+               {
+                       return base.GetHashCode ();
                }
 
                /// <summary>
                /// Emit attribute for Attributable symbol
                /// </summary>
-               public void Emit (EmitContext ec, Attributable ias, ListDictionary emitted_attr)
+               public void Emit (ListDictionary allEmitted)
                {
-                       CustomAttributeBuilder cb = Resolve (ec);
+                       CustomAttributeBuilder cb = Resolve ();
                        if (cb == null)
                                return;
 
-                       AttributeUsageAttribute usage_attr = GetAttributeUsage (ec);
+                       AttributeUsageAttribute usage_attr = GetAttributeUsage ();
                        if ((usage_attr.ValidOn & Target) == 0) {
-                               Report.Error (592, Location, "Attribute '{0}' is not valid on this declaration type. It is valid on {1} declarations only.", Name, GetValidTargets ());
+                               Report.Error (592, Location, "The attribute `{0}' is not valid on this declaration type. " +
+                                             "It is valid on `{1}' declarations only",
+                                       GetSignatureForError (), GetValidTargets ());
                                return;
                        }
 
                        try {
-                               ias.ApplyAttributeBuilder (this, cb);
+                               foreach (Attributable owner in owners)
+                                       owner.ApplyAttributeBuilder (this, cb);
                        }
                        catch (Exception e) {
                                Error_AttributeEmitError (e.Message);
                                return;
                        }
 
-                       if (!usage_attr.AllowMultiple) {
-                               ArrayList emitted_targets = (ArrayList)emitted_attr [Type];
-                               if (emitted_targets == null) {
-                                       emitted_targets = new ArrayList ();
-                                       emitted_attr.Add (Type, emitted_targets);
-                               } else if (emitted_targets.Contains (Target)) {
-                                       Report.Error (579, Location, "Duplicate '" + Name + "' attribute");
-                                       return;
+                       if (!usage_attr.AllowMultiple && allEmitted != null) {
+                               if (allEmitted.Contains (this)) {
+                                       ArrayList a = allEmitted [this] as ArrayList;
+                                       if (a == null) {
+                                               a = new ArrayList (2);
+                                               allEmitted [this] = a;
+                                       }
+                                       a.Add (this);
+                               } else {
+                                       allEmitted.Add (this, null);
                                }
-                               emitted_targets.Add (Target);
                        }
 
                        if (!RootContext.VerifyClsCompliance)
                                return;
 
                        // 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) { 
+                       if (Owner.IsClsComplianceRequired ()) {
+                               if (PosArguments != null) {
+                                       foreach (Argument arg in PosArguments) { 
                                                // Type is undefined (was error 246)
                                                if (arg.Type == null)
                                                        return;
@@ -1063,11 +1233,10 @@ namespace Mono.CSharp {
                                        }
                                }
                        
-                               if (Arguments.Count < 2)
+                               if (NamedArguments == null)
                                        return;
                        
-                               ArrayList named_args = (ArrayList) Arguments [1];
-                               foreach (DictionaryEntry de in named_args) {
+                               foreach (DictionaryEntry de in NamedArguments) {
                                        Argument arg  = (Argument) de.Value;
 
                                        // Type is undefined (was error 246)
@@ -1081,115 +1250,13 @@ namespace Mono.CSharp {
                                }
                        }
                }
-               
-               public MethodBuilder DefinePInvokeMethod (EmitContext ec, TypeBuilder builder, string name,
-                                                         MethodAttributes flags, Type ret_type, Type [] param_types)
-               {
-                       if (pos_values == null)
-                               // 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);
-
-                       if (resolve_error)
-                               return null;
-                       
-                       string dll_name = (string)pos_values [0];
-
-                       // Default settings
-                       CallingConvention cc = CallingConvention.Winapi;
-                       CharSet charset = CodeGen.Module.DefaultCharSet;
-                       bool preserve_sig = true;
-                       string entry_point = name;
-                       bool best_fit_mapping = false;
-                       bool throw_on_unmappable = false;
-
-                       bool best_fit_mapping_set = false;
-                       bool throw_on_unmappable_set = false;
-
-                       MethodInfo set_best_fit = null;
-                       MethodInfo set_throw_on = null;
-
-                       if (field_info_arr != null) {
-                               int char_set_extra = 0;
-
-                               for (int i = 0; i < field_info_arr.Length; i++) {
-                                       switch (field_info_arr [i].Name) {
-                                               case "BestFitMapping":
-                                                       best_fit_mapping = (bool) field_values_arr [i];
-                                                       best_fit_mapping_set = true;
-                                                       break;
-                                               case "CallingConvention":
-                                                       cc = (CallingConvention) field_values_arr [i];
-                                                       break;
-                                               case "CharSet":
-                                                       charset = (CharSet) field_values_arr [i];
-                                                       break;
-                                               case "EntryPoint":
-                                                       entry_point = (string) field_values_arr [i];
-                                                       break;
-                                               case "ExactSpelling":
-                                                       char_set_extra |= 0x01;
-                                                       break;
-                                               case "PreserveSig":
-                                                       preserve_sig = (bool) field_values_arr [i];
-                                                       break;
-                                               case "SetLastError":
-                                                       char_set_extra |= 0x40;
-                                                       break;
-                                               case "ThrowOnUnmappableChar":
-                                                       throw_on_unmappable = (bool) field_values_arr [i];
-                                                       throw_on_unmappable_set = true;
-                                                       break;
-                                               default: 
-                                                       throw new InternalErrorException (field_info_arr [i].ToString ());
-                                       }
-                               }
-                               charset |= (CharSet)char_set_extra;
-                       }
-
-                       if (throw_on_unmappable_set || best_fit_mapping_set) {
-                               set_best_fit = typeof (MethodBuilder).GetMethod ("set_BestFitMapping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-                               set_throw_on = typeof (MethodBuilder).GetMethod ("set_ThrowOnUnmappableChar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-
-                               if ((set_best_fit == null) || (set_throw_on == null)) {
-                                       Report.Error (-1, Location,
-                                                                 "The ThrowOnUnmappableChar and BestFitMapping attributes can only be emitted when running on the mono runtime.");
-                                       return null;
-                               }
-                       }
-
-                       try {
-                               MethodBuilder mb = builder.DefinePInvokeMethod (
-                                       name, dll_name, entry_point, flags | MethodAttributes.HideBySig | MethodAttributes.PinvokeImpl,
-                                       CallingConventions.Standard, ret_type, param_types, cc, charset);
-
-                               if (preserve_sig)
-                                       mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);
-
-                               if (throw_on_unmappable_set)
-                                       set_throw_on.Invoke (mb, 0, null, new object [] { throw_on_unmappable }, null);
-                               if (best_fit_mapping_set)
-                                       set_best_fit.Invoke (mb, 0, null, new object [] { best_fit_mapping }, null);
-                       
-                               return mb;
-                       }
-                       catch (ArgumentException e) {
-                               Error_AttributeEmitError (e.Message);
-                               return null;
-                       }
-               }
 
                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))
+                       if (PosArguments == null || PosArguments.Count < 1)
                                return null;
-                       return arg.Expr;
+
+                       return ((Argument) PosArguments [0]).Expr;
                }
 
                public string GetString () 
@@ -1207,6 +1274,14 @@ namespace Mono.CSharp {
                                return (e as BoolLiteral).Value;
                        return false;
                }
+
+               public Type GetArgumentType ()
+               {
+                       TypeOf e = GetValue () as TypeOf;
+                       if (e == null)
+                               return null;
+                       return e.TypeArgument;
+               }
        }
        
 
@@ -1214,53 +1289,64 @@ namespace Mono.CSharp {
        /// For global attributes (assembly, module) we need special handling.
        /// Attributes can be located in the several files
        /// </summary>
-       public class GlobalAttribute: Attribute
+       public class GlobalAttribute : Attribute
        {
                public readonly NamespaceEntry ns;
 
-               public GlobalAttribute (TypeContainer container, string target, 
-                                       Expression left_expr, string identifier, ArrayList args, Location loc):
-                       base (target, left_expr, identifier, args, loc)
+               public GlobalAttribute (NamespaceEntry ns, string target, 
+                                       Expression left_expr, string identifier, object[] args, Location loc, bool nameEscaped):
+                       base (target, left_expr, identifier, args, loc, nameEscaped)
                {
-                       ns = container.NamespaceEntry;
+                       this.ns = ns;
                }
 
                void Enter ()
                {
-                       // RootContext.Tree.Types has a single NamespaceEntry which gets overwritten
+                       // RootContext.ToplevelTypes has a single NamespaceEntry which gets overwritten
                        // each time a new file is parsed.  However, we need to use the NamespaceEntry
                        // in effect where the attribute was used.  Since code elsewhere cannot assume
                        // that the NamespaceEntry is right, just overwrite it.
                        //
-                       // Precondition: RootContext.Tree.Types == null
+                       // Precondition: RootContext.ToplevelTypes == null
 
-                       if (RootContext.Tree.Types.NamespaceEntry != null)
+                       if (RootContext.ToplevelTypes.NamespaceEntry != null)
                                throw new InternalErrorException (Location + " non-null NamespaceEntry");
 
-                       RootContext.Tree.Types.NamespaceEntry = ns;
+                       RootContext.ToplevelTypes.NamespaceEntry = ns;
                }
 
                void Leave ()
                {
-                       RootContext.Tree.Types.NamespaceEntry = null;
+                       RootContext.ToplevelTypes.NamespaceEntry = null;
                }
 
-               protected override FullNamedExpression ResolveAsTypeStep (Expression expr, EmitContext ec)
+               protected override TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec, bool silent)
                {
                        try {
                                Enter ();
-                               return base.ResolveAsTypeStep (expr, ec);
+                               return base.ResolveAsTypeTerminal (expr, ec, silent);
                        }
                        finally {
                                Leave ();
                        }
                }
 
-               protected override ConstructorInfo ResolveArguments (EmitContext ec)
+               protected override ConstructorInfo ResolveConstructor (EmitContext ec)
                {
                        try {
                                Enter ();
-                               return base.ResolveArguments (ec);
+                               return base.ResolveConstructor (ec);
+                       }
+                       finally {
+                               Leave ();
+                       }
+               }
+
+               protected override bool ResolveNamedArguments (EmitContext ec)
+               {
+                       try {
+                               Enter ();
+                               return base.ResolveNamedArguments (ec);
                        }
                        finally {
                                Leave ();
@@ -1269,7 +1355,7 @@ namespace Mono.CSharp {
        }
 
        public class Attributes {
-               public ArrayList Attrs;
+               public readonly ArrayList Attrs;
 
                public Attributes (Attribute a)
                {
@@ -1287,46 +1373,28 @@ namespace Mono.CSharp {
                        Attrs.AddRange (attrs);
                }
 
+               public void AttachTo (Attributable attributable)
+               {
+                       foreach (Attribute a in Attrs)
+                               a.AttachTo (attributable);
+               }
+
                /// <summary>
                /// Checks whether attribute target is valid for the current element
                /// </summary>
-               public bool CheckTargets (Attributable member)
+               public bool CheckTargets ()
                {
-                       string[] valid_targets = member.ValidAttributeTargets;
                        foreach (Attribute a in Attrs) {
-                               if (a.ExplicitTarget == null || a.ExplicitTarget == valid_targets [0]) {
-                                       a.Target = member.AttributeTargets;
-                                       continue;
-                               }
-
-                               // TODO: we can skip the first item
-                               if (((IList) valid_targets).Contains (a.ExplicitTarget)) {
-                                       switch (a.ExplicitTarget) {
-                                               case "return": a.Target = AttributeTargets.ReturnValue; continue;
-                                               case "param": a.Target = AttributeTargets.Parameter; continue;
-                                               case "field": a.Target = AttributeTargets.Field; continue;
-                                               case "method": a.Target = AttributeTargets.Method; continue;
-                                               case "property": a.Target = AttributeTargets.Property; continue;
-                                       }
-                                       throw new InternalErrorException ("Unknown explicit target: " + a.ExplicitTarget);
-                               }
-
-                               StringBuilder sb = new StringBuilder ();
-                               foreach (string s in valid_targets) {
-                                       sb.Append (s);
-                                       sb.Append (", ");
-                               }
-                               sb.Remove (sb.Length - 2, 2);
-                               Report.Error (657, a.Location, "'{0}' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are '{1}'", a.ExplicitTarget, sb.ToString ());
-                               return false;
+                               if (!a.CheckTarget ())
+                                       return false;
                        }
                        return true;
                }
 
-               public Attribute Search (Type t, EmitContext ec)
+               public Attribute Search (Type t)
                {
                        foreach (Attribute a in Attrs) {
-                               if (a.ResolveType (ec) == t)
+                               if (a.ResolveType () == t)
                                        return a;
                        }
                        return null;
@@ -1335,12 +1403,12 @@ namespace Mono.CSharp {
                /// <summary>
                /// Returns all attributes of type 't'. Use it when attribute is AllowMultiple = true
                /// </summary>
-               public Attribute[] SearchMulti (Type t, EmitContext ec)
+               public Attribute[] SearchMulti (Type t)
                {
                        ArrayList ar = null;
 
                        foreach (Attribute a in Attrs) {
-                               if (a.ResolveType (ec) == t) {
+                               if (a.ResolveType () == t) {
                                        if (ar == null)
                                                ar = new ArrayList ();
                                        ar.Add (a);
@@ -1350,19 +1418,33 @@ namespace Mono.CSharp {
                        return ar == null ? null : ar.ToArray (typeof (Attribute)) as Attribute[];
                }
 
-               public void Emit (EmitContext ec, Attributable ias)
+               public void Emit ()
                {
-                       CheckTargets (ias);
+                       CheckTargets ();
 
-                       ListDictionary ld = new ListDictionary ();
+                       ListDictionary ld = Attrs.Count > 1 ? new ListDictionary () : null;
 
                        foreach (Attribute a in Attrs)
-                               a.Emit (ec, ias, ld);
+                               a.Emit (ld);
+
+                       if (ld == null || ld.Count == 0)
+                               return;
+
+                       foreach (DictionaryEntry d in ld) {
+                               if (d.Value == null)
+                                       continue;
+
+                               foreach (Attribute collision in (ArrayList)d.Value)
+                                       Report.SymbolRelatedToPreviousError (collision.Location, "");
+
+                               Attribute a = (Attribute)d.Key;
+                               Report.Error (579, a.Location, "The attribute `{0}' cannot be applied multiple times", a.GetSignatureForError ());
+                       }
                }
 
-               public bool Contains (Type t, EmitContext ec)
+               public bool Contains (Type t)
                {
-                        return Search (t, ec) != null;
+                       return Search (t) != null;
                }
        }
 
@@ -1371,40 +1453,73 @@ namespace Mono.CSharp {
        /// </summary>
        sealed class AttributeTester
        {
-               static PtrHashtable analyzed_types = new PtrHashtable ();
-               static PtrHashtable analyzed_types_obsolete = new PtrHashtable ();
-               static PtrHashtable analyzed_member_obsolete = new PtrHashtable ();
-               static PtrHashtable analyzed_method_excluded = new PtrHashtable ();
+               static PtrHashtable analyzed_types;
+               static PtrHashtable analyzed_types_obsolete;
+               static PtrHashtable analyzed_member_obsolete;
+               static PtrHashtable analyzed_method_excluded;
 
 #if NET_2_0
-               static PtrHashtable fixed_buffer_cache = new PtrHashtable ();
+               static PtrHashtable fixed_buffer_cache;
 #endif
 
                static object TRUE = new object ();
                static object FALSE = new object ();
 
+               static AttributeTester ()
+               {
+                       Reset ();
+               }
+
                private AttributeTester ()
                {
                }
 
+               public static void Reset ()
+               {
+                       analyzed_types = new PtrHashtable ();
+                       analyzed_types_obsolete = new PtrHashtable ();
+                       analyzed_member_obsolete = new PtrHashtable ();
+                       analyzed_method_excluded = new PtrHashtable ();
+#if NET_2_0
+                       fixed_buffer_cache = new PtrHashtable ();
+#endif
+               }
+
+               public enum Result {
+                       Ok,
+                       RefOutArrayError,
+                       ArrayArrayError
+               }
+
                /// <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) 
+               public static Result AreOverloadedMethodParamsClsCompliant (Type[] types_a, Type[] types_b) 
                {
                        if (types_a == null || types_b == null)
-                               return true;
+                               return Result.Ok;
 
                        if (types_a.Length != types_b.Length)
-                               return true;
+                               return Result.Ok;
 
+                       Result result = Result.Ok;
                        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;
+                               if (aType.IsArray && bType.IsArray) {
+                                       Type a_el_type = aType.GetElementType ();
+                                       Type b_el_type = bType.GetElementType ();
+                                       if (aType.GetArrayRank () != bType.GetArrayRank () && a_el_type == b_el_type) {
+                                               result = Result.RefOutArrayError;
+                                               continue;
+                                       }
+
+                                       if (a_el_type.IsArray || b_el_type.IsArray) {
+                                               result = Result.ArrayArrayError;
+                                               continue;
+                                       }
                                }
 
                                Type aBaseType = aType;
@@ -1423,32 +1538,14 @@ namespace Mono.CSharp {
                                }
 
                                if (aBaseType != bBaseType)
-                                       continue;
+                                       return Result.Ok;
 
                                if (is_either_ref_or_out)
-                                       return false;
+                                       result = Result.RefOutArrayError;
                        }
-                       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 (3001, loc, "Argument type '{0}' is not CLS-compliant", arg.GetSignatureForError ());
-                                       return false;
-                               }
-                       }
-                       return true;
+                       return result;
                }
 
-
                /// <summary>
                /// This method tests the CLS compliance of external types. It doesn't test type visibility.
                /// </summary>
@@ -1481,6 +1578,10 @@ namespace Mono.CSharp {
                /// </summary>
                public static IFixedBuffer GetFixedBuffer (FieldInfo fi)
                {
+                       // Fixed buffer helper type is generated as value type
+                       if (!fi.FieldType.IsValueType)
+                               return null;
+
                        FieldBase fb = TypeManager.GetField (fi);
                        if (fb != null) {
                                return fb as IFixedBuffer;
@@ -1505,12 +1606,12 @@ namespace Mono.CSharp {
                        return (IFixedBuffer)o;
 #else
                        return null;
-#endif
+#endif         
                }
 
                public static void VerifyModulesClsCompliance ()
                {
-                       Module[] modules = TypeManager.Modules;
+                       Module[] modules = RootNamespace.Global.Modules;
                        if (modules == null)
                                return;
 
@@ -1518,49 +1619,24 @@ namespace Mono.CSharp {
                        for (int i = 1; i < modules.Length; ++i) {
                                Module module = modules [i];
                                if (!IsClsCompliant (module)) {
-                                       Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute to match the assembly", module.Name);
+                                       Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute " +
+                                                     "to match the assembly", module.Name);
                                        return;
                                }
                        }
                }
 
-               /// <summary>
-               /// Tests container name for CLS-Compliant name (differing only in case)
-               /// </summary>
-               public static void VerifyTopLevelNameClsCompliance ()
+               public static Type GetImportedIgnoreCaseClsType (string name)
                {
-                       Hashtable locase_table = new Hashtable ();
-
-                       // Convert imported type names to lower case and ignore not cls compliant
-                       foreach (DictionaryEntry de in TypeManager.all_imported_types) {
-                               Type t = (Type)de.Value;
-                               if (!AttributeTester.IsClsCompliant (t))
+                       foreach (Assembly a in RootNamespace.Global.Assemblies) {
+                               Type t = a.GetType (name, false, true);
+                               if (t == null)
                                        continue;
 
-                               locase_table.Add (((string)de.Key).ToLower (System.Globalization.CultureInfo.InvariantCulture), t);
-                       }
-
-                       foreach (DictionaryEntry de in RootContext.Tree.AllDecls) {
-                               if (!(de.Key is MemberName))
-                                       throw new InternalErrorException ("");
-                               DeclSpace decl = (DeclSpace) de.Value;
-                               if (!decl.IsClsCompliaceRequired (decl))
-                                       continue;
-
-                               string lcase = decl.Name.ToLower (System.Globalization.CultureInfo.InvariantCulture);
-                               if (!locase_table.Contains (lcase)) {
-                                       locase_table.Add (lcase, decl);
-                                       continue;
-                               }
-
-                               object conflict = locase_table [lcase];
-                               if (conflict is Type)
-                                       Report.SymbolRelatedToPreviousError ((Type)conflict);
-                               else
-                                       Report.SymbolRelatedToPreviousError ((MemberCore)conflict);
-
-                               Report.Error (3005, decl.Location, "Identifier '{0}' differing only in case is not CLS-compliant", decl.GetSignatureForError ());
+                               if (IsClsCompliant (t))
+                                       return t;
                        }
+                       return null;
                }
 
                static bool IsClsCompliant (ICustomAttributeProvider attribute_provider) 
@@ -1574,11 +1650,15 @@ namespace Mono.CSharp {
 
                static bool AnalyzeTypeCompliance (Type type)
                {
+                       type = TypeManager.DropGenericTypeArguments (type);
                        DeclSpace ds = TypeManager.LookupDeclSpace (type);
                        if (ds != null) {
-                               return ds.IsClsCompliaceRequired (ds.Parent);
+                               return ds.IsClsComplianceRequired ();
                        }
 
+                       if (TypeManager.IsGenericParameter (type))
+                               return true;
+
                        object[] CompliantAttribute = type.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
                        if (CompliantAttribute.Length == 0) 
                                return IsClsCompliant (type.Assembly);
@@ -1586,6 +1666,13 @@ namespace Mono.CSharp {
                        return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;
                }
 
+               // Registers the core type as we assume that they will never be obsolete which
+               // makes things easier for bootstrap and faster (we don't need to query Obsolete attribute).
+               public static void RegisterNonObsoleteType (Type type)
+               {
+                       analyzed_types_obsolete [type] = FALSE;
+               }
+
                /// <summary>
                /// Returns instance of ObsoleteAttribute when type is obsolete
                /// </summary>
@@ -1599,9 +1686,11 @@ namespace Mono.CSharp {
                                return (ObsoleteAttribute)type_obsolete;
 
                        ObsoleteAttribute result = null;
-                       if (type.IsByRef || type.IsArray || type.IsPointer) {
+                       if (TypeManager.HasElementType (type)) {
                                result = GetObsoleteAttribute (TypeManager.GetElementType (type));
-                       } else {
+                       } else if (TypeManager.IsGenericParameter (type) || TypeManager.IsGenericType (type))
+                               return null;
+                       else {
                                DeclSpace type_ds = TypeManager.LookupDeclSpace (type);
 
                                // Type is external, we can get attribute directly
@@ -1610,11 +1699,12 @@ namespace Mono.CSharp {
                                        if (attribute.Length == 1)
                                                result = (ObsoleteAttribute)attribute [0];
                                } else {
-                                       result = type_ds.GetObsoleteAttribute (type_ds);
+                                       result = type_ds.GetObsoleteAttribute ();
                                }
                        }
 
-                       analyzed_types_obsolete.Add (type, result == null ? FALSE : result);
+                       // Cannot use .Add because of corlib bootstrap
+                       analyzed_types_obsolete [type] = result == null ? FALSE : result;
                        return result;
                }
 
@@ -1631,9 +1721,13 @@ namespace Mono.CSharp {
                        if (mb.DeclaringType is TypeBuilder)
                                return null;
 
-                       PropertyInfo pi = PropertyExpr.AccessorTable [mb] as PropertyInfo;
-                       if (pi != null)
-                               return GetMemberObsoleteAttribute (pi);
+                       MemberInfo mi = TypeManager.GetPropertyFromAccessor (mb);
+                       if (mi != null)
+                               return GetMemberObsoleteAttribute (mi);
+
+                       mi = TypeManager.GetEventFromAccessor (mb);
+                       if (mi != null)
+                               return GetMemberObsoleteAttribute (mi);
 
                        return GetMemberObsoleteAttribute (mb);
                }
@@ -1650,7 +1744,11 @@ namespace Mono.CSharp {
                        if (type_obsolete != null)
                                return (ObsoleteAttribute)type_obsolete;
 
-                       ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false) as ObsoleteAttribute;
+                       if ((mi.DeclaringType is TypeBuilder) || TypeManager.IsGenericType (mi.DeclaringType))
+                               return null;
+
+                       ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false)
+                               as ObsoleteAttribute;
                        analyzed_member_obsolete.Add (mi, oa == null ? FALSE : oa);
                        return oa;
                }
@@ -1661,25 +1759,29 @@ namespace Mono.CSharp {
                public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc)
                {
                        if (oa.IsError) {
-                               Report.Error (619, loc, "'{0}' is obsolete: '{1}'", member, oa.Message);
+                               Report.Error (619, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
                                return;
                        }
 
                        if (oa.Message == null) {
-                               Report.Warning (612, loc, "'{0}' is obsolete", member);
+                               Report.Warning (612, 1, loc, "`{0}' is obsolete", member);
                                return;
                        }
-                       if (RootContext.WarningLevel >= 2)
-                               Report.Warning (618, loc, "'{0}' is obsolete: '{1}'", member, oa.Message);
+                       Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
                }
 
                public static bool IsConditionalMethodExcluded (MethodBase mb)
                {
+                       mb = TypeManager.DropGenericMethodArguments (mb);
+                       if ((mb is MethodBuilder) || (mb is ConstructorBuilder))
+                               return false;
+
                        object excluded = analyzed_method_excluded [mb];
                        if (excluded != null)
                                return excluded == TRUE ? true : false;
-                       
-                       ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true) as ConditionalAttribute[];
+
+                       ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true)
+                               as ConditionalAttribute[];
                        if (attrs.Length == 0) {
                                analyzed_method_excluded.Add (mb, FALSE);
                                return false;
@@ -1719,5 +1821,25 @@ namespace Mono.CSharp {
 
                        return class_decl.IsExcluded ();
                }
+
+               public static Type GetCoClassAttribute (Type type)
+               {
+                       TypeContainer tc = TypeManager.LookupInterface (type);
+                       if (tc == null) {
+                               object[] o = type.GetCustomAttributes (TypeManager.coclass_attr_type, false);
+                               if (o.Length < 1)
+                                       return null;
+                               return ((System.Runtime.InteropServices.CoClassAttribute)o[0]).CoClass;
+                       }
+
+                       if (tc.OptAttributes == null)
+                               return null;
+
+                       Attribute a = tc.OptAttributes.Search (TypeManager.coclass_attr_type);
+                       if (a == null)
+                               return null;
+
+                       return a.GetCoClassAttributeValue ();
+               }
        }
 }