* Makefile: Build the make-map.exe in Mono.Unix.Native; add /nowarn:0618 to
[mono.git] / mcs / mcs / attribute.cs
index 84c622491ff0f354890f325b26f6b646ee1f86b3..7a046567ef9cd4e969ac62ccecd1bf9e17f2a014 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 {
 
@@ -71,6 +72,7 @@ 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;
@@ -83,13 +85,11 @@ namespace Mono.CSharp {
 
                bool resolve_error;
 
-               public AttributeUsageAttribute UsageAttribute;
-               public static AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
+               readonly bool nameEscaped;
+
+               static AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
+               static Assembly orig_sec_assembly;
 
-               MethodImplOptions ImplOptions;
-               UnmanagedType     UnmanagedType;
-               CustomAttributeBuilder cb;
-       
                // non-null if named args present after Resolve () is called
                PropertyInfo [] prop_info_arr;
                FieldInfo [] field_info_arr;
@@ -99,7 +99,7 @@ namespace Mono.CSharp {
 
                static PtrHashtable usage_attr_cache = new PtrHashtable ();
                
-               public Attribute (string target, Expression left_expr, string identifier, ArrayList args, Location loc)
+               public Attribute (string target, Expression left_expr, string identifier, ArrayList args, Location loc, bool nameEscaped)
                {
                        LeftExpr = left_expr;
                        Identifier = identifier;
@@ -107,13 +107,18 @@ namespace Mono.CSharp {
                        Arguments = args;
                        Location = loc;
                        ExplicitTarget = target;
+                       this.nameEscaped = nameEscaped;
                }
 
                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 it is not a valid attribute parameter type", name);
                }
 
                static void Error_AttributeArgumentNotValid (string extra, Location loc)
@@ -135,7 +140,7 @@ 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,117 +148,90 @@ namespace Mono.CSharp {
                        Error_AttributeEmitError ("it is attached to invalid parent");
                }
 
-               void Error_AttributeConstructorMismatch ()
+               protected virtual FullNamedExpression ResolveAsTypeTerminal (Expression expr, EmitContext ec, bool silent)
                {
-                       Report.Error (-6, Location,
-                                      "Could not find a constructor for this argument list.");
+                       return expr.ResolveAsTypeTerminal (ec, silent);
                }
 
-               void ResolvePossibleAttributeTypes (EmitContext ec, out Type t1, out Type t2)
+               protected virtual FullNamedExpression ResolveAsTypeStep (Expression expr, EmitContext ec, bool silent)
                {
-                       t1 = null;
-                       t2 = null;
+                       return expr.ResolveAsTypeStep (ec, silent);
+               }
 
-                       FullNamedExpression n1 = null;
-                       FullNamedExpression n2 = null;
-                       string IdentifierAttribute = Identifier + "Attribute";
+               Type ResolvePossibleAttributeType (EmitContext ec, string name, bool silent, ref bool is_attr)
+               {
+                       FullNamedExpression fn;
                        if (LeftExpr == null) {
-                               n1 = new SimpleName (Identifier, Location).ResolveAsTypeStep (ec);
-
-                               // FIXME: Shouldn't do this for quoted attributes: [@A]
-                               n2 = new SimpleName (IdentifierAttribute, Location).ResolveAsTypeStep (ec);
+                               fn = ResolveAsTypeTerminal (new SimpleName (name, Location), ec, silent);
                        } else {
-                               FullNamedExpression l = LeftExpr.ResolveAsTypeStep (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);
+                               fn = ResolveAsTypeStep (LeftExpr, ec, silent);
+                               if (fn == null)
+                                       return null;
+                               fn = new MemberAccess (fn, name, Location).ResolveAsTypeTerminal (ec, silent);
                        }
 
-                       TypeExpr te1 = n1 == null ? null : n1 as TypeExpr;
-                       TypeExpr te2 = n2 == null ? null : n2 as TypeExpr;                      
+                       TypeExpr te = fn 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 (t.IsSubclassOf (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 (EmitContext ec)
                {
-                       Type t1, t2;
-
-                       ResolvePossibleAttributeTypes (ec, out t1, out t2);
-
-                       string NameAttribute = Name + "Attribute";
+                       bool t1_is_attr = false;
+                       Type t1 = ResolvePossibleAttributeType (ec, Identifier, true, ref t1_is_attr);
 
-                       String err0616 = null;
+                       bool t2_is_attr = false;
+                       Type t2 = nameEscaped ? null :
+                               ResolvePossibleAttributeType (ec, Identifier + "Attribute", true, ref t2_is_attr);
 
-                       if (t1 != null && ! t1.IsSubclassOf (TypeManager.attribute_type)) {
-                               t1 = null;
-                               err0616 = "'" + Name + "': is not an attribute class";
-                       }
-                       if (t2 != null && ! t2.IsSubclassOf (TypeManager.attribute_type)) {
-                               t2 = null;
-                               err0616 = (err0616 != null) 
-                                       ? "Neither '" + Name + "' nor '" + NameAttribute +"' is an attribute class"
-                                       : "'" + Name + "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, "'" + Name + "': is ambiguous; " 
-                                            + " use either '@" + Name + "' or '" + NameAttribute + "'");
-                               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);
-                               return null;
+                       if (t2_is_attr) {
+                               Type = t2;
+                               return;
                        }
 
-                       Report.Error (246, Location, 
-                                     "Could not find attribute '" + Name 
-                                     + "' (are you missing a using directive or an assembly reference ?)");
+                       if (t1 == null && t2 == null)
+                               ResolvePossibleAttributeType (ec, Identifier, false, ref t1_is_attr);
+                       if (t1 != null)
+                               ResolvePossibleAttributeType (ec, Identifier, false, ref t1_is_attr);
+                       if (t2 != null)
+                               ResolvePossibleAttributeType (ec, Identifier + "Attribute", false, ref t2_is_attr);
 
                        resolve_error = true;
-                       return null;
                }
 
                public virtual Type ResolveType (EmitContext ec)
                {
-                       if (Type == null)
-                               Type = CheckAttributeType (ec);
+                       if (Type == null && !resolve_error)
+                               ResolveAttributeType (ec);
                        return Type;
                }
 
-               /// <summary>
-               ///   Validates the guid string
-               /// </summary>
-               bool ValidateGuid (string guid)
+               public string GetSignatureForError ()
                {
-                       try {
-                               new Guid (guid);
-                               return true;
-                       } catch {
-                               Report.Error (647, Location, "Format of GUID is invalid: " + guid);
-                               return false;
-                       }
-               }
-
-               string GetFullMemberName (string member)
-               {
-                       return Type.FullName + '.' + member;
+                       return LeftExpr == null ? Identifier : LeftExpr.GetSignatureForError () + "." + Identifier;
                }
 
                //
@@ -262,26 +240,14 @@ namespace Mono.CSharp {
                //
                public static bool GetAttributeArgumentExpression (Expression e, Location loc, Type arg_type, out object result)
                {
-                       if (e is EnumConstant) {
-                               if (RootContext.StdLib)
-                                       result = ((EnumConstant)e).GetValueAsEnumType ();
-                               else
-                                       result = ((EnumConstant)e).GetValue ();
-
-                               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;
-                                       }
+                               constant = constant.ToType (arg_type, loc);
+                               if (constant == null) {
+                                       result = null;
+                                       return false;
                                }
-                               result = constant.GetValue ();
+                               result = constant.GetTypedValue ();
                                return true;
                        } else if (e is TypeOf) {
                                result = ((TypeOf) e).TypeArg;
@@ -293,74 +259,103 @@ namespace Mono.CSharp {
                        } else if (e is EmptyCast) {
                                Expression child = ((EmptyCast)e).Child;
                                return GetAttributeArgumentExpression (child, loc, child.Type, out result);
+                       } else if (e is As) {
+                               As as_e = (As) e;
+                               return GetAttributeArgumentExpression (as_e.Expr, loc, as_e.ProbeType.Type, out result);
                        }
 
                        result = null;
                        Error_AttributeArgumentNotValid (loc);
                        return false;
                }
-               
-               public virtual CustomAttributeBuilder Resolve (EmitContext ec)
+
+               bool IsValidArgumentType (Type t)
+               {
+                       if (t.IsArray)
+                               t = t.GetElementType ();
+
+                       return TypeManager.IsPrimitiveType (t) ||
+                               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 ();
+
+               public CustomAttributeBuilder Resolve (EmitContext ec)
                {
                        if (resolve_error)
                                return null;
 
                        resolve_error = true;
 
-                       Type oldType = Type;
-                       
-                       // Sanity check.
-                       Type = CheckAttributeType (ec); // TODO: I really don't think we need such expensive double check
+                       if (Type == null) {
+                               ResolveAttributeType (ec);
+                               if (Type == null)
+                                       return null;
+                       }
 
-                       if (oldType == null && Type == null)
-                               return null;
-                       if (oldType != null && oldType != Type){
-                               Report.Error (-27, Location,
-                                             "Attribute {0} resolved to different types at different times: {1} vs. {2}",
-                                             Name, oldType, Type);
+                       if (Type.IsAbstract) {
+                               Report.Error (653, Location, "Cannot apply attribute class `{0}' because it is abstract", GetSignatureForError ());
                                return null;
                        }
 
-                       if (Type.IsAbstract) {
-                               Report.Error (653, Location, "Cannot apply attribute class '{0}' because it is abstract", Name);
+                       if (Arguments == null) {
+                               object o = att_cache [Type];
+                               if (o != null) {
+                                       resolve_error = false;
+                                       return (CustomAttributeBuilder)o;
+                               }
+                       }
+
+                       ConstructorInfo ctor = ResolveArguments (ec);
+                       if (ctor == null)
+                               return null;
+
+                       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 (pos_values.Length == 0)
+                                               att_cache.Add (Type, cb);
+                               }
+                       }
+                       catch (Exception) {
+                               Error_AttributeArgumentNotValid (Location);
                                return null;
                        }
 
-                       bool MethodImplAttr = false;
-                       bool MarshalAsAttr = false;
-                       bool GuidAttr = false;
-                       bool usage_attr = false;
-
-                       bool DoCompares = true;
-
-                        //
-                        // If we are a certain special attribute, we
-                        // set the information accordingly
-                        //
-                        
-                       if (Type == TypeManager.attribute_usage_type)
-                               usage_attr = true;
-                       else if (Type == TypeManager.methodimpl_attr_type)
-                               MethodImplAttr = true;
-                       else if (Type == TypeManager.marshal_as_attr_type)
-                               MarshalAsAttr = true;
-                       else if (Type == TypeManager.guid_attr_type)
-                               GuidAttr = true;
-                       else
-                               DoCompares = false;
+                       resolve_error = false;
+                       return cb;
+               }
 
+               protected virtual ConstructorInfo ResolveArguments (EmitContext ec)
+               {
                        // Now we extract the positional and named arguments
                        
-                       ArrayList pos_args = new ArrayList ();
-                       ArrayList named_args = new ArrayList ();
+                       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)
+                               if (Arguments.Count > 1) {
                                        named_args = (ArrayList) Arguments [1];
+                                       named_arg_count = named_args.Count;
+                               }
                        }
 
                        pos_values = new object [pos_arg_count];
@@ -385,27 +380,9 @@ namespace Mono.CSharp {
 
                                pos_values [i] = val;
 
-                               if (DoCompares){
-                                       if (usage_attr) {
-                                               if ((int)val == 0) {
-                                                       Report.Error (591, Location, "Invalid value for argument to 'System.AttributeUsage' attribute");
-                                                       return null;
-                                               }
-                                               UsageAttribute = new AttributeUsageAttribute ((AttributeTargets)val);
-                                       } else if (MethodImplAttr) {
-                                               this.ImplOptions = (MethodImplOptions) val;
-                                       } else if (GuidAttr){
-                                               //
-                                               // we will later check the validity of the type
-                                               //
-                                               if (val is string){
-                                                       if (!ValidateGuid ((string) val))
-                                                               return null;
-                                               }
-                                               
-                                       } else if (MarshalAsAttr)
-                                               this.UnmanagedType =
-                                               (System.Runtime.InteropServices.UnmanagedType) val;
+                               if (i == 0 && Type == TypeManager.attribute_usage_type && (int)val == 0) {
+                                       Report.Error (591, Location, "Invalid value for argument to 'System.AttributeUsage' attribute");
+                                       return null;
                                }
                        }
 
@@ -417,17 +394,18 @@ namespace Mono.CSharp {
                        ArrayList prop_infos  = null;
                        ArrayList field_values = null;
                        ArrayList prop_values = null;
+                       Hashtable seen_names = null;
 
-                       if (named_args.Count > 0) {
+                       if (named_arg_count > 0) {
                                field_infos = new ArrayList ();
                                prop_infos  = new ArrayList ();
                                field_values = new ArrayList ();
                                prop_values = new ArrayList ();
-                       }
 
-                       Hashtable seen_names = new Hashtable();
+                               seen_names = new Hashtable();
+                       }
                        
-                       for (i = 0; i < named_args.Count; i++) {
+                       for (i = 0; i < named_arg_count; i++) {
                                DictionaryEntry de = (DictionaryEntry) named_args [i];
                                string member_name = (string) de.Key;
                                Argument a  = (Argument) de.Value;
@@ -454,13 +432,13 @@ namespace Mono.CSharp {
                                                Location);
 
                                        if (member != null) {
-                                               Report.Error (122, Location, "'{0}' is inaccessible due to its protection level", GetFullMemberName (member_name));
+                                               Expression.ErrorIsInaccesible (Location, member.GetSignatureForError ());
                                                return null;
                                        }
                                }
 
                                if (member == null){
-                                       Report.Error (117, Location, "Attribute `{0}' does not contain a definition for `{1}'",
+                                       Report.Error (117, Location, "`{0}' does not contain a definition for `{1}'",
                                                      Type, member_name);
                                        return null;
                                }
@@ -481,17 +459,16 @@ namespace Mono.CSharp {
                                                return null;
                                        }
 
+                                       if (!IsValidArgumentType (pi.PropertyType)) {
+                                               Report.SymbolRelatedToPreviousError (pi);
+                                               Error_InvalidNamedAgrumentType (member_name);
+                                               return null;
+                                       }
+
                                        object value;
                                        if (!GetAttributeArgumentExpression (e, Location, pi.PropertyType, out value))
                                                return null;
 
-                                       if (UsageAttribute != null) {
-                                               if (member_name == "AllowMultiple")
-                                                       UsageAttribute.AllowMultiple = (bool) value;
-                                               if (member_name == "Inherited")
-                                                       UsageAttribute.Inherited = (bool) value;
-                                       }
-
                                        prop_values.Add (value);
                                        prop_infos.Add (pi);
                                        
@@ -504,6 +481,12 @@ namespace Mono.CSharp {
                                                return null;
                                        }
 
+                                       if (!IsValidArgumentType (fi.FieldType)) {
+                                               Report.SymbolRelatedToPreviousError (fi);
+                                               Error_InvalidNamedAgrumentType (member_name);
+                                               return null;
+                                       }
+
                                        object value;
                                        if (!GetAttributeArgumentExpression (e, Location, fi.FieldType, out value))
                                                return null;
@@ -518,11 +501,6 @@ namespace Mono.CSharp {
                                BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
                                 Location);
 
-                       if (mg == null) {
-                               Error_AttributeConstructorMismatch ();
-                               return null;
-                       }
-
                        MethodBase constructor = Invocation.OverloadResolve (
                                ec, (MethodGroupExpr) mg, pos_args, false, Location);
 
@@ -530,6 +508,25 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+
+                       // 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);
+                               }
+                       }
+// TODO: reenable
+//                     if (Type == TypeManager.methodimpl_attr_type &&
+//                             pos_values.Length == 1 && ((Argument)pos_args [0]).Type == TypeManager.short_type &&
+//                             !System.Enum.IsDefined (TypeManager.method_impl_options, pos_values [0])) {
+//                                     Error_AttributeEmitError ("Incorrect argument value.");
+//                     }
+
                        //
                        // Now we perform some checks on the positional args as they
                        // cannot be null for a constructor which expects a parameter
@@ -559,7 +556,7 @@ namespace Mono.CSharp {
                                }
 
                                object value = pos_values [j];
-                               if (value != null && a.Type != value.GetType () && a.Type.IsPrimitive) {
+                               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) {
@@ -589,44 +586,20 @@ namespace Mono.CSharp {
                                pos_values = new_pos_values;
                        }
 
-                       try {
-                               if (named_args.Count > 0) {
-                                       prop_info_arr = new PropertyInfo [prop_infos.Count];
-                                       field_info_arr = new FieldInfo [field_infos.Count];
-                                       field_values_arr = new object [field_values.Count];
-                                       prop_values_arr = new object [prop_values.Count];
-
-                                       field_infos.CopyTo  (field_info_arr, 0);
-                                       field_values.CopyTo (field_values_arr, 0);
+                       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];
 
-                                       prop_values.CopyTo  (prop_values_arr, 0);
-                                       prop_infos.CopyTo   (prop_info_arr, 0);
+                               field_infos.CopyTo  (field_info_arr, 0);
+                               field_values.CopyTo (field_values_arr, 0);
 
-                                       cb = new CustomAttributeBuilder (
-                                               (ConstructorInfo) constructor, pos_values,
-                                               prop_info_arr, prop_values_arr,
-                                               field_info_arr, field_values_arr);
-                               }
-                               else
-                                       cb = new CustomAttributeBuilder (
-                                               (ConstructorInfo) constructor, pos_values);
-                       } catch (Exception e) {
-                               //
-                               // Sample:
-                               // using System.ComponentModel;
-                               // [DefaultValue (CollectionChangeAction.Add)]
-                               // class X { static void Main () {} }
-                               //
-                               Error_AttributeArgumentNotValid (Location);
-                               return null;
-                       }
-                       
-                       if (!usage_attr) {
-                               UsageAttribute = DefaultUsageAttribute;
+                               prop_values.CopyTo  (prop_values_arr, 0);
+                               prop_infos.CopyTo   (prop_info_arr, 0);
                        }
 
-                       resolve_error = false;
-                       return cb;
+                       return (ConstructorInfo) constructor;
                }
 
                /// <summary>
@@ -635,58 +608,61 @@ namespace Mono.CSharp {
                public string GetValidTargets ()
                {
                        StringBuilder sb = new StringBuilder ();
-                       AttributeTargets targets = UsageAttribute.ValidOn;
+                       AttributeTargets targets = GetAttributeUsage (null).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>
-               public AttributeUsageAttribute GetAttributeUsage (EmitContext ec)
+               AttributeUsageAttribute GetAttributeUsage (EmitContext ec)
                {
                        AttributeUsageAttribute ua = usage_attr_cache [Type] as AttributeUsageAttribute;
                        if (ua != null)
@@ -701,11 +677,41 @@ namespace Mono.CSharp {
                                return ua;
                        }
 
-                       ua = attr_class.ResolveAttributeUsage (ec);
+                       Attribute a = attr_class.OptAttributes == null
+                               ? null
+                               : attr_class.OptAttributes.Search (TypeManager.attribute_usage_type, attr_class.EmitContext);
+
+                       ua = a == null
+                               ? DefaultUsageAttribute 
+                               : a.GetAttributeUsageAttribute (attr_class.EmitContext);
+
                        usage_attr_cache.Add (Type, ua);
                        return ua;
                }
 
+               AttributeUsageAttribute GetAttributeUsageAttribute (EmitContext ec)
+               {
+                       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 DefaultUsageAttribute;
+
+                       AttributeUsageAttribute usage_attribute = new AttributeUsageAttribute ((AttributeTargets)pos_values [0]);
+
+                       object field = GetPropertyValue ("AllowMultiple");
+                       if (field != null)
+                               usage_attribute.AllowMultiple = (bool)field;
+
+                       field = GetPropertyValue ("Inherited");
+                       if (field != null)
+                               usage_attribute.Inherited = (bool)field;
+
+                       return usage_attribute;
+               }
+
                /// <summary>
                /// Returns custom name of indexer
                /// </summary>
@@ -716,6 +722,9 @@ namespace Mono.CSharp {
                                // But because a lot of attribute class code must be rewritten will be better to wait...
                                Resolve (ec);
 
+                       if (resolve_error)
+                               return null;
+
                        return pos_values [0] as string;
                }
 
@@ -729,8 +738,7 @@ namespace Mono.CSharp {
                                // But because a lot of attribute class code must be rewritten will be better to wait...
                                Resolve (ec);
 
-                       // Some error occurred
-                       if (pos_values [0] == null)
+                       if (resolve_error)
                                return null;
 
                        return (string)pos_values [0];
@@ -746,11 +754,10 @@ namespace Mono.CSharp {
                                // But because a lot of attribute class code must be rewritten will be better to wait...
                                Resolve (ec);
 
-                       // Some error occurred
-                       if (pos_values == null)
+                       if (resolve_error)
                                return null;
 
-                       if (pos_values.Length == 0)
+                       if (pos_values == null || pos_values.Length == 0)
                                return new ObsoleteAttribute ();
 
                        if (pos_values.Length == 1)
@@ -771,8 +778,7 @@ namespace Mono.CSharp {
                                // But because a lot of attribute class code must be rewritten will be better to wait...
                                Resolve (ec);
 
-                       // Some error occurred
-                       if (pos_values [0] == null)
+                       if (resolve_error)
                                return false;
 
                        return (bool)pos_values [0];
@@ -813,14 +819,34 @@ 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) {
@@ -830,15 +856,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]) :
@@ -850,13 +875,7 @@ namespace Mono.CSharp {
                        }
 
                        IPermission perm;
-                       try {
-                               perm = sa.CreatePermission ();
-                       }
-                       catch (Exception e) {
-                               Error_AttributeEmitError (String.Format ("{0} was thrown during attribute processing: {1}", e.GetType (), e.Message));
-                               return;
-                       }
+                       perm = sa.CreatePermission ();
                        SecurityAction action = GetSecurityActionValue ();
 
                        // IS is correct because for corlib we are using an instance from old corlib
@@ -882,7 +901,7 @@ namespace Mono.CSharp {
                                        ps = new PermissionSet (PermissionState.None);
 
                                permissions.Add (action, ps);
-                       } else if (!ps.IsUnrestricted () && sa.Unrestricted) {
+                       } else if (!ps.IsUnrestricted () && (sa is PermissionSetAttribute) && sa.Unrestricted) {
                                ps = ps.Union (new PermissionSet (PermissionState.Unrestricted));
                                permissions [action] = ps;
                        }
@@ -897,13 +916,21 @@ namespace Mono.CSharp {
                                return value;                           
                }
 
-               public object GetPositionalValue (int i)
+               object GetPropertyValue (string name)
                {
-                       return (pos_values == null) ? null : pos_values[i];
+                       if (prop_info_arr == null)
+                               return null;
+
+                       for (int i = 0; i < prop_info_arr.Length; ++i) {
+                               if (prop_info_arr [i].Name == name)
+                                       return prop_values_arr [i];
+                       }
+
+                       return null;
                }
 
                object GetFieldValue (string name)
-                {
+               {
                        int i;
                        if (field_info_arr == null)
                                return null;
@@ -916,8 +943,19 @@ 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;
+                       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) {
                                Error_AttributeEmitError ("SizeParamIndex field is not valid for the specified unmanaged type");
@@ -925,12 +963,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:
+                       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;
@@ -942,13 +980,31 @@ namespace Mono.CSharp {
                                args [2] = GetFieldValue ("MarshalType");
                                args [3] = Guid.Empty;
                                return (UnmanagedMarshal) define_custom.Invoke (null, args);
+                       }
+                       case UnmanagedType.LPArray: {
+                               object size_const = GetFieldValue ("SizeConst");
+                               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);
+                                       if (define_array == null) {
+                                               Report.RuntimeMissingSupport (Location, "set marshal info");
+                                               return null;
+                                       }
                                
-                       case UnmanagedType.LPArray:                             
-                               return UnmanagedMarshal.DefineLPArray (array_sub_type);
-                       
+                                       object [] args = new object [3];
+                                       args [0] = array_sub_type;
+                                       args [1] = size_const == null ? -1 : size_const;
+                                       args [2] = size_param_index == null ? -1 : size_param_index;
+                                       return (UnmanagedMarshal) define_array.Invoke (null, args);
+                               }
+                               else
+                                       return UnmanagedMarshal.DefineLPArray (array_sub_type);
+                       }
                        case UnmanagedType.SafeArray:
                                return UnmanagedMarshal.DefineSafeArray (array_sub_type);
-                       
+
                        case UnmanagedType.ByValArray:
                                FieldMember fm = attr as FieldMember;
                                if (fm == null) {
@@ -956,18 +1012,33 @@ namespace Mono.CSharp {
                                        return null;
                                }
                                return UnmanagedMarshal.DefineByValArray ((int) GetFieldValue ("SizeConst"));
-                       
+
                        case UnmanagedType.ByValTStr:
                                return UnmanagedMarshal.DefineByValTStr ((int) GetFieldValue ("SizeConst"));
-                       
+
                        default:
                                return UnmanagedMarshal.DefineUnmanagedMarshal (UnmanagedType);
                        }
                }
 
-               public bool IsInternalCall
+               public CharSet GetCharSetValue ()
+               {
+                       return (CharSet)System.Enum.Parse (typeof (CharSet), pos_values [0].ToString ());
+               }
+
+               public MethodImplOptions GetMethodImplOptions ()
+               {
+                       if (pos_values [0].GetType () != typeof (MethodImplOptions))
+                               return (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values [0]);
+                       return (MethodImplOptions)pos_values [0];
+               }
+
+               public LayoutKind GetLayoutKindValue ()
                {
-                       get { return ImplOptions == MethodImplOptions.InternalCall; }
+                       if (!RootContext.StdLib || pos_values [0].GetType () != typeof (LayoutKind))
+                               return (LayoutKind)System.Enum.ToObject (typeof (LayoutKind), pos_values [0]);
+
+                       return (LayoutKind)pos_values [0];
                }
 
                /// <summary>
@@ -981,11 +1052,18 @@ namespace Mono.CSharp {
 
                        AttributeUsageAttribute usage_attr = GetAttributeUsage (ec);
                        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, "Attribute `{0}' is not valid on this declaration type. It is valid on `{1}' declarations only",
+                                       GetSignatureForError (), GetValidTargets ());
                                return;
                        }
 
-                       ias.ApplyAttributeBuilder (this, cb);
+                       try {
+                               ias.ApplyAttributeBuilder (this, cb);
+                       }
+                       catch (Exception e) {
+                               Error_AttributeEmitError (e.Message);
+                               return;
+                       }
 
                        if (!usage_attr.AllowMultiple) {
                                ArrayList emitted_targets = (ArrayList)emitted_attr [Type];
@@ -993,7 +1071,7 @@ namespace Mono.CSharp {
                                        emitted_targets = new ArrayList ();
                                        emitted_attr.Add (Type, emitted_targets);
                                } else if (emitted_targets.Contains (Target)) {
-                                       Report.Error (579, Location, "Duplicate '" + Name + "' attribute");
+                                       Report.Error (579, Location, "Duplicate `{0}' attribute", GetSignatureForError ());
                                        return;
                                }
                                emitted_targets.Add (Target);
@@ -1039,147 +1117,114 @@ namespace Mono.CSharp {
                                }
                        }
                }
-
-               public object GetValue (EmitContext ec, Constant c, Type target)
-               {
-                       if (Convert.ImplicitConversionExists (ec, c, target))
-                               return c.GetValue ();
-
-                       Convert.Error_CannotImplicitConversion (Location, c.Type, target);
-                       return null;
-               }
                
                public MethodBuilder DefinePInvokeMethod (EmitContext ec, TypeBuilder builder, string name,
                                                          MethodAttributes flags, Type ret_type, Type [] param_types)
                {
-                       //
-                       // We extract from the attribute the information we need 
-                       //
-
-                       if (Arguments == null) {
-                               Console.WriteLine ("Internal error : this is not supposed to happen !");
-                               return null;
-                       }
+                       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);
 
-                       ResolveType (ec);
-                       if (Type == null)
+                       if (resolve_error)
                                return null;
                        
-                       ArrayList named_args = new ArrayList ();
-                       
-                       ArrayList pos_args = (ArrayList) Arguments [0];
-                       if (Arguments.Count > 1)
-                               named_args = (ArrayList) Arguments [1];
-                       
+                       string dll_name = (string)pos_values [0];
 
-                       string dll_name = null;
-                       
-                       Argument tmp = (Argument) pos_args [0];
-
-                       if (!tmp.Resolve (ec, Location))
-                               return null;
-                       
-                       if (tmp.Expr is Constant)
-                               dll_name = (string) ((Constant) tmp.Expr).GetValue ();
-                       else { 
-                               Error_AttributeArgumentNotValid (Location);
-                               return null;
-                       }
-                       if (dll_name == null || dll_name == ""){
-                               Error_AttributeArgumentNotValid (": DllImport requires a non-empty string", Location);
-                               return null;
-                       }
-                       
-                       // Now we process the named arguments
+                       // Default settings
                        CallingConvention cc = CallingConvention.Winapi;
-                       CharSet charset = CharSet.Ansi;
+                       CharSet charset = CodeGen.Module.DefaultCharSet;
                        bool preserve_sig = true;
-#if FIXME
+                       string entry_point = name;
+                       bool best_fit_mapping = false;
+                       bool throw_on_unmappable = false;
                        bool exact_spelling = false;
-#endif
-                       bool set_last_err = false;
-                       string entry_point = null;
-
-                       for (int i = 0; i < named_args.Count; i++) {
-
-                               DictionaryEntry de = (DictionaryEntry) named_args [i];
-
-                               string member_name = (string) de.Key;
-                               Argument a  = (Argument) de.Value;
-
-                               if (!a.Resolve (ec, Location))
-                                       return null;
-
-                               Expression member = Expression.MemberLookup (
-                                       ec, Type, member_name, 
-                                       MemberTypes.Field | MemberTypes.Property,
-                                       BindingFlags.Public | BindingFlags.Instance,
-                                       Location);
-
-                               if (member == null || !(member is FieldExpr)) {
-                                       Error_InvalidNamedArgument (member_name);
-                                       return null;
+                       bool set_last_error = false;
+
+                       bool best_fit_mapping_set = false;
+                       bool throw_on_unmappable_set = false;
+                       bool exact_spelling_set = false;
+                       bool set_last_error_set = false;
+
+                       MethodInfo set_best_fit = null;
+                       MethodInfo set_throw_on = null;
+                       MethodInfo set_exact_spelling = null;
+                       MethodInfo set_set_last_error = null;
+
+                       if (field_info_arr != null) {
+
+                               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":
+                                                       exact_spelling = (bool) field_values_arr [i];
+                                                       exact_spelling_set = true;
+                                                       break;
+                                               case "PreserveSig":
+                                                       preserve_sig = (bool) field_values_arr [i];
+                                                       break;
+                                               case "SetLastError":
+                                                       set_last_error = (bool) field_values_arr [i];
+                                                       set_last_error_set = true;
+                                                       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 ());
+                                       }
                                }
+                       }
 
-                               if (member is FieldExpr) {
-                                       FieldExpr fe = (FieldExpr) member;
-                                       FieldInfo fi = fe.FieldInfo;
-
-                                       if (fi.IsInitOnly) {
-                                               Error_InvalidNamedArgument (member_name);
-                                               return null;
-                                       }
+                       if (throw_on_unmappable_set || best_fit_mapping_set || exact_spelling_set || set_last_error_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);
+                               set_exact_spelling = typeof (MethodBuilder).GetMethod ("set_ExactSpelling", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+                               set_set_last_error = typeof (MethodBuilder).GetMethod ("set_SetLastError", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
 
-                                       if (a.Expr is Constant) {
-                                               Constant c = (Constant) a.Expr;
-
-                                               try {
-                                                       if (member_name == "CallingConvention"){
-                                                               object val = GetValue (ec, c, typeof (CallingConvention));
-                                                               if (val == null)
-                                                                       return null;
-                                                               cc = (CallingConvention) val;
-                                                       } else if (member_name == "CharSet"){
-                                                               charset = (CharSet) c.GetValue ();
-                                                       } else if (member_name == "EntryPoint")
-                                                               entry_point = (string) c.GetValue ();
-                                                       else if (member_name == "SetLastError")
-                                                               set_last_err = (bool) c.GetValue ();
-#if FIXME
-                                                       else if (member_name == "ExactSpelling")
-                                                               exact_spelling = (bool) c.GetValue ();
-#endif
-                                                       else if (member_name == "PreserveSig")
-                                                               preserve_sig = (bool) c.GetValue ();
-                                               } catch (InvalidCastException){
-                                                       Error_InvalidNamedArgument (member_name);
-                                                       Error_AttributeArgumentNotValid (Location);
-                                               }
-                                       } else { 
-                                               Error_AttributeArgumentNotValid (Location);
-                                               return null;
-                                       }
-                                       
+                               if ((set_best_fit == null) || (set_throw_on == null) || (set_exact_spelling == null) || (set_set_last_error == null)) {
+                                       Report.Error (-1, Location,
+                                                                 "The ThrowOnUnmappableChar, BestFitMapping, SetLastError, and ExactSpelling attributes can only be emitted when running on the mono runtime.");
+                                       return null;
                                }
                        }
 
-                       if (entry_point == null)
-                               entry_point = name;
-                       if (set_last_err)
-                               charset = (CharSet)((int)charset | 0x40);
-                       
-                       MethodBuilder mb = builder.DefinePInvokeMethod (
-                               name, dll_name, entry_point, flags | MethodAttributes.HideBySig,
-                               CallingConventions.Standard,
-                               ret_type,
-                               param_types,
-                               cc,
-                               charset);
-
-                       if (preserve_sig)
-                               mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);
+                       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);
+                               if (exact_spelling_set)
+                                       set_exact_spelling.Invoke  (mb, 0, null, new object [] { exact_spelling }, null);
+                               if (set_last_error_set)
+                                       set_set_last_error.Invoke  (mb, 0, null, new object [] { set_last_error }, null);
                        
-                       return mb;
+                               return mb;
+                       }
+                       catch (ArgumentException e) {
+                               Error_AttributeEmitError (e.Message);
+                               return null;
+                       }
                }
 
                private Expression GetValue () 
@@ -1222,8 +1267,8 @@ namespace Mono.CSharp {
                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)
+                                       Expression left_expr, string identifier, ArrayList args, Location loc, bool nameEscaped):
+                       base (target, left_expr, identifier, args, loc, nameEscaped)
                {
                        ns = container.NamespaceEntry;
                }
@@ -1248,20 +1293,38 @@ namespace Mono.CSharp {
                        RootContext.Tree.Types.NamespaceEntry = null;
                }
 
-               public override Type ResolveType (EmitContext ec)
+               protected override FullNamedExpression ResolveAsTypeStep (Expression expr, EmitContext ec, bool silent)
                {
-                       Enter ();
-                       Type retval = base.ResolveType (ec);
-                       Leave ();
-                       return retval;
+                       try {
+                               Enter ();
+                               return base.ResolveAsTypeStep (expr, ec, silent);
+                       }
+                       finally {
+                               Leave ();
+                       }
                }
 
-               public override CustomAttributeBuilder Resolve (EmitContext ec)
+
+               protected override FullNamedExpression ResolveAsTypeTerminal (Expression expr, EmitContext ec, bool silent)
                {
-                       Enter ();
-                       CustomAttributeBuilder retval = base.Resolve (ec);
-                       Leave ();
-                       return retval;
+                       try {
+                               Enter ();
+                               return base.ResolveAsTypeTerminal (expr, ec, silent);
+                       }
+                       finally {
+                               Leave ();
+                       }
+               }
+
+               protected override ConstructorInfo ResolveArguments (EmitContext ec)
+               {
+                       try {
+                               Enter ();
+                               return base.ResolveArguments (ec);
+                       }
+                       finally {
+                               Leave ();
+                       }
                }
        }
 
@@ -1314,7 +1377,7 @@ namespace Mono.CSharp {
                                        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 ());
+                               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;
                        }
                        return true;
@@ -1349,8 +1412,7 @@ namespace Mono.CSharp {
 
                public void Emit (EmitContext ec, Attributable ias)
                {
-                       if (!CheckTargets (ias))
-                               return;
+                       CheckTargets (ias);
 
                        ListDictionary ld = new ListDictionary ();
 
@@ -1373,7 +1435,10 @@ namespace Mono.CSharp {
                static PtrHashtable analyzed_types_obsolete = new PtrHashtable ();
                static PtrHashtable analyzed_member_obsolete = new PtrHashtable ();
                static PtrHashtable analyzed_method_excluded = new PtrHashtable ();
+
+#if NET_2_0
                static PtrHashtable fixed_buffer_cache = new PtrHashtable ();
+#endif
 
                static object TRUE = new object ();
                static object FALSE = new object ();
@@ -1382,24 +1447,41 @@ namespace Mono.CSharp {
                {
                }
 
+               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;
@@ -1418,12 +1500,12 @@ namespace Mono.CSharp {
                                }
 
                                if (aBaseType != bBaseType)
-                                       continue;
+                                       return Result.Ok;
 
                                if (is_either_ref_or_out)
-                                       return false;
+                                       result = Result.RefOutArrayError;
                        }
-                       return true;
+                       return result;
                }
 
                /// <summary>
@@ -1436,7 +1518,7 @@ namespace Mono.CSharp {
 
                        foreach (Parameter arg in fixedParameters) {
                                if (!AttributeTester.IsClsCompliant (arg.ParameterType)) {
-                                       Report.Error (3001, loc, "Argument type '{0}' is not CLS-compliant", arg.GetSignatureForError ());
+                                       Report.Error (3001, loc, "Argument type `{0}' is not CLS-compliant", arg.GetSignatureForError ());
                                        return false;
                                }
                        }
@@ -1519,41 +1601,17 @@ namespace Mono.CSharp {
                        }
                }
 
-               /// <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))
-                                       continue;
-
-                               locase_table.Add (((string)de.Key).ToLower (System.Globalization.CultureInfo.InvariantCulture), t);
-                       }
-
-                       foreach (DictionaryEntry de in RootContext.Tree.Decls) {
-                               DeclSpace decl = (DeclSpace)de.Value;
-                               if (!decl.IsClsCompliaceRequired (decl))
+                       foreach (Assembly a in TypeManager.GetAssemblies ()) {
+                               Type t = a.GetType (name, false, true);
+                               if (t == null)
                                        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) 
@@ -1624,9 +1682,14 @@ namespace Mono.CSharp {
                        if (mb.DeclaringType is TypeBuilder)
                                return null;
 
-                       PropertyInfo pi = PropertyExpr.AccessorTable [mb] as PropertyInfo;
-                       if (pi != null)
-                               return GetMemberObsoleteAttribute (pi);
+                       if (mb.IsSpecialName) {
+                               PropertyInfo pi = PropertyExpr.AccessorTable [mb] as PropertyInfo;
+                               if (pi != null) {
+                                       // FIXME: This is buggy as properties from this assembly are included as well
+                                       return null;
+                                       //return GetMemberObsoleteAttribute (pi);
+                               }
+                       }
 
                        return GetMemberObsoleteAttribute (mb);
                }
@@ -1654,16 +1717,16 @@ 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, loc, "`{0}' is obsolete", member);
                                return;
                        }
                        if (RootContext.WarningLevel >= 2)
-                               Report.Warning (618, loc, "'{0}' is obsolete: '{1}'", member, oa.Message);
+                               Report.Warning (618, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
                }
 
                public static bool IsConditionalMethodExcluded (MethodBase mb)
@@ -1687,5 +1750,30 @@ namespace Mono.CSharp {
                        analyzed_method_excluded.Add (mb, TRUE);
                        return true;
                }
+
+               /// <summary>
+               /// Analyzes class whether it has attribute which has ConditionalAttribute
+               /// and its condition is not defined.
+               /// </summary>
+               public static bool IsAttributeExcluded (Type type)
+               {
+                       if (!type.IsClass)
+                               return false;
+
+                       Class class_decl = TypeManager.LookupDeclSpace (type) as Class;
+
+                       // TODO: add caching
+                       // TODO: merge all Type bases attribute caching to one cache to save memory
+                       if (class_decl == null) {
+                               object[] attributes = type.GetCustomAttributes (TypeManager.conditional_attribute_type, false);
+                               foreach (ConditionalAttribute ca in attributes) {
+                                       if (RootContext.AllDefines.Contains (ca.ConditionString))
+                                               return false;
+                               }
+                               return attributes.Length > 0;
+                       }
+
+                       return class_decl.IsExcluded ();
+               }
        }
 }