Brush.jvm.cs: added brush transform field
[mono.git] / mcs / gmcs / attribute.cs
index 258730d96de6380b767f775f519a2efb5971a2c5..c853a331405a1f584ae757e8a7015ca1e3609bda 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 {
 
@@ -58,7 +59,7 @@ namespace Mono.CSharp {
                /// </summary>
                public abstract AttributeTargets AttributeTargets { get; }
 
-               public abstract bool IsClsCompliaceRequired (DeclSpace ds);
+               public abstract bool IsClsComplianceRequired (DeclSpace ds);
 
                /// <summary>
                /// Gets list of valid attribute targets for explicit target declaration.
@@ -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;
@@ -84,9 +86,8 @@ namespace Mono.CSharp {
                bool resolve_error;
 
                static AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
+               static Assembly orig_sec_assembly;
 
-               CustomAttributeBuilder cb;
-       
                // non-null if named args present after Resolve () is called
                PropertyInfo [] prop_info_arr;
                FieldInfo [] field_info_arr;
@@ -108,9 +109,13 @@ namespace Mono.CSharp {
 
                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)
@@ -137,7 +142,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 ()
@@ -145,97 +150,87 @@ 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);
+                       bool t1_is_attr = false;
+                       Type t1 = ResolvePossibleAttributeType (ec, Identifier, true, ref t1_is_attr);
+                       // FIXME: Shouldn't do this for quoted attributes: [@A]
+                       bool t2_is_attr = false;
+                       Type t2 = ResolvePossibleAttributeType (ec, Identifier + "Attribute", true, ref t2_is_attr);
 
-                       String err0616 = null;
-                       if (t1 != null && ! t1.IsSubclassOf (TypeManager.attribute_type)) {
-                               t1 = null;
-                               err0616 = "'{0}' 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 (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) {
+                               Type = t1;
+                               return;
                        }
 
-                       if (t1 != null && t2 != null) {
-                               Report.Error (1614, Location, "'{0}' is ambiguous; use either '@{0}' or '{0}Attribute'", Name);
-                               return null;
+                       if (t2_is_attr) {
+                               Type = t2;
+                               return;
                        }
+
+                       if (t1 == null && t2 == null)
+                               ResolvePossibleAttributeType (ec, Identifier, false, ref t1_is_attr);
                        if (t1 != null)
-                               return t1;
+                               ResolvePossibleAttributeType (ec, Identifier, false, ref t1_is_attr);
                        if (t2 != null)
-                               return t2;
-                       if (err0616 != null) {
-                               Report.Error (616, Location, err0616, Name);
-                               return null;
-                       }
-
-                       Report.Error (246, Location, 
-                                     "Could not find attribute '{0}' (are you missing a using directive or an assembly reference ?)",
-                                     Name);
-
+                               ResolvePossibleAttributeType (ec, Identifier + "Attribute", false, ref t2_is_attr);
                        resolve_error = true;
-                       return null;
                }
 
                public virtual Type ResolveType (EmitContext ec)
                {
                        if (Type == null && !resolve_error)
-                               Type = CheckAttributeType (ec);
+                               ResolveAttributeType (ec);
                        return Type;
                }
 
-               string GetFullMemberName (string member)
+               public string GetSignatureForError ()
                {
-                       return Type.FullName + '.' + member;
+                       return LeftExpr == null ? Identifier : LeftExpr.GetSignatureForError () + "." + Identifier;
                }
 
                //
@@ -281,25 +276,35 @@ namespace Mono.CSharp {
                        Error_AttributeArgumentNotValid (loc);
                        return false;
                }
-               
+
+               bool IsValidArgumentType (Type t)
+               {
+                       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 ();
 
-               public virtual CustomAttributeBuilder Resolve (EmitContext ec)
+               public CustomAttributeBuilder Resolve (EmitContext ec)
                {
                        if (resolve_error)
                                return null;
 
                        resolve_error = true;
 
-                       if (Type == null)
-                               Type = CheckAttributeType (ec);
-
-                       if (Type == null)
-                               return null;
+                       if (Type == null) {
+                               ResolveAttributeType (ec);
+                               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;
                        }
 
@@ -311,6 +316,37 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       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;
+                       }
+
+                       resolve_error = false;
+                       return cb;
+               }
+
+               protected virtual ConstructorInfo ResolveArguments (EmitContext ec)
+               {
                        // Now we extract the positional and named arguments
                        
                        ArrayList pos_args = null;
@@ -402,13 +438,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;
                                }
@@ -434,6 +470,12 @@ 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;
@@ -450,6 +492,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;
@@ -465,11 +513,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);
 
@@ -477,6 +520,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
@@ -506,7 +568,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) {
@@ -536,44 +598,20 @@ namespace Mono.CSharp {
                                pos_values = new_pos_values;
                        }
 
-                       try {
-                               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);
+                       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];
 
-                                       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);
+                               field_infos.CopyTo  (field_info_arr, 0);
+                               field_values.CopyTo (field_values_arr, 0);
 
-                                       if (pos_values.Length == 0)
-                                               att_cache.Add (Type, cb);
-                               }
-                       } catch (Exception) {
-                               //
-                               // Sample:
-                               // using System.ComponentModel;
-                               // [DefaultValue (CollectionChangeAction.Add)]
-                               // class X { static void Main () {} }
-                               //
-                               Error_AttributeArgumentNotValid (Location);
-                               return null;
+                               prop_values.CopyTo  (prop_values_arr, 0);
+                               prop_infos.CopyTo   (prop_info_arr, 0);
                        }
-                       
-                       resolve_error = false;
-                       return cb;
+
+                       return (ConstructorInfo) constructor;
                }
 
                /// <summary>
@@ -585,49 +623,50 @@ namespace Mono.CSharp {
                        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 ((targets & AttributeTargets.GenericParameter) != 0)
+                               sb.Append ("type parameter, ");
+                       return sb.Remove (sb.Length - 2, 2).ToString ();
                }
 
                /// <summary>
@@ -648,18 +687,14 @@ namespace Mono.CSharp {
                                return ua;
                        }
 
-                       if (attr_class.OptAttributes == null) {
-                               usage_attr_cache.Add (Type, DefaultUsageAttribute);
-                               return DefaultUsageAttribute;
-                       }
+                       Attribute a = attr_class.OptAttributes == null
+                               ? null
+                               : attr_class.OptAttributes.Search (TypeManager.attribute_usage_type, attr_class.EmitContext);
 
-                       Attribute a = attr_class.OptAttributes.Search (TypeManager.attribute_usage_type, ec);
-                       if (a == null) {
-                               usage_attr_cache.Add (Type, DefaultUsageAttribute);
-                               return DefaultUsageAttribute;
-                       }
+                       ua = a == null
+                               ? DefaultUsageAttribute 
+                               : a.GetAttributeUsageAttribute (attr_class.EmitContext);
 
-                       ua = a.GetAttributeUsageAttribute (ec);
                        usage_attr_cache.Add (Type, ua);
                        return ua;
                }
@@ -764,19 +799,29 @@ namespace Mono.CSharp {
                /// </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 X");
+                               return false;
                        }
 
                        Error_AttributeEmitError (String.Concat ("SecurityAction '", action, "' is not valid for this declaration"));
@@ -794,14 +839,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) {
@@ -811,15 +876,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]) :
@@ -967,6 +1031,11 @@ namespace Mono.CSharp {
                        }
                }
 
+               public CharSet GetCharSetValue ()
+               {
+                       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 ());
@@ -988,7 +1057,8 @@ 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;
                        }
 
@@ -997,7 +1067,6 @@ namespace Mono.CSharp {
                        }
                        catch (Exception e) {
                                Error_AttributeEmitError (e.Message);
-                               Console.WriteLine (e.ToString ());
                                return;
                        }
 
@@ -1007,7 +1076,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);
@@ -1017,7 +1086,7 @@ namespace Mono.CSharp {
                                return;
 
                        // Here we are testing attribute arguments for array usage (error 3016)
-                       if (ias.IsClsCompliaceRequired (ec.DeclSpace)) {
+                       if (ias.IsClsComplianceRequired (ec.DeclSpace)) {
                                if (Arguments == null)
                                        return;
 
@@ -1069,20 +1138,25 @@ namespace Mono.CSharp {
 
                        // Default settings
                        CallingConvention cc = CallingConvention.Winapi;
-                       CharSet charset = CharSet.Ansi;
+                       CharSet charset = CodeGen.Module.DefaultCharSet;
                        bool preserve_sig = true;
                        string entry_point = name;
                        bool best_fit_mapping = false;
                        bool throw_on_unmappable = false;
+                       bool exact_spelling = false;
+                       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) {
-                               int char_set_extra = 0;
 
                                for (int i = 0; i < field_info_arr.Length; i++) {
                                        switch (field_info_arr [i].Name) {
@@ -1100,13 +1174,15 @@ namespace Mono.CSharp {
                                                        entry_point = (string) field_values_arr [i];
                                                        break;
                                                case "ExactSpelling":
-                                                       char_set_extra |= 0x01;
+                                                       exact_spelling = (bool) field_values_arr [i];
+                                                       exact_spelling_set = true;
                                                        break;
                                                case "PreserveSig":
                                                        preserve_sig = (bool) field_values_arr [i];
                                                        break;
                                                case "SetLastError":
-                                                       char_set_extra |= 0x40;
+                                                       set_last_error = (bool) field_values_arr [i];
+                                                       set_last_error_set = true;
                                                        break;
                                                case "ThrowOnUnmappableChar":
                                                        throw_on_unmappable = (bool) field_values_arr [i];
@@ -1116,16 +1192,17 @@ namespace Mono.CSharp {
                                                        throw new InternalErrorException (field_info_arr [i].ToString ());
                                        }
                                }
-                               charset |= (CharSet)char_set_extra;
                        }
 
-                       if (throw_on_unmappable_set || best_fit_mapping_set) {
+                       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 ((set_best_fit == null) || (set_throw_on == 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 and BestFitMapping attributes can only be emitted when running on the mono runtime.");
+                                                                 "The ThrowOnUnmappableChar, BestFitMapping, SetLastError, and ExactSpelling attributes can only be emitted when running on the mono runtime.");
                                        return null;
                                }
                        }
@@ -1142,6 +1219,10 @@ namespace Mono.CSharp {
                                        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;
                        }
@@ -1217,20 +1298,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)
+               {
+                       try {
+                               Enter ();
+                               return base.ResolveAsTypeStep (expr, ec, silent);
+                       }
+                       finally {
+                               Leave ();
+                       }
+               }
+
+
+               protected override FullNamedExpression ResolveAsTypeTerminal (Expression expr, EmitContext ec, bool silent)
                {
-                       Enter ();
-                       Type retval = base.ResolveType (ec);
-                       Leave ();
-                       return retval;
+                       try {
+                               Enter ();
+                               return base.ResolveAsTypeTerminal (expr, ec, silent);
+                       }
+                       finally {
+                               Leave ();
+                       }
                }
 
-               public override CustomAttributeBuilder Resolve (EmitContext ec)
+               protected override ConstructorInfo ResolveArguments (EmitContext ec)
                {
-                       Enter ();
-                       CustomAttributeBuilder retval = base.Resolve (ec);
-                       Leave ();
-                       return retval;
+                       try {
+                               Enter ();
+                               return base.ResolveArguments (ec);
+                       }
+                       finally {
+                               Leave ();
+                       }
                }
        }
 
@@ -1283,7 +1382,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;
@@ -1351,24 +1450,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;
@@ -1387,12 +1503,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>
@@ -1405,7 +1521,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;
                                }
                        }
@@ -1504,7 +1620,7 @@ namespace Mono.CSharp {
                                if (!(de.Key is MemberName))
                                        throw new InternalErrorException ("");
                                DeclSpace decl = (DeclSpace) de.Value;
-                               if (!decl.IsClsCompliaceRequired (decl))
+                               if (!decl.IsClsComplianceRequired (decl))
                                        continue;
 
                                string lcase = decl.Name.ToLower (System.Globalization.CultureInfo.InvariantCulture);
@@ -1519,7 +1635,7 @@ namespace Mono.CSharp {
                                else
                                        Report.SymbolRelatedToPreviousError ((MemberCore)conflict);
 
-                               Report.Error (3005, decl.Location, "Identifier '{0}' differing only in case is not CLS-compliant", decl.GetSignatureForError ());
+                               Report.Error (3005, decl.Location, "Identifier `{0}' differing only in case is not CLS-compliant", decl.GetSignatureForError ());
                        }
                }
 
@@ -1534,13 +1650,14 @@ namespace Mono.CSharp {
 
                static bool AnalyzeTypeCompliance (Type type)
                {
+                       if (type.IsGenericInstance)
+                               type = type.GetGenericTypeDefinition ();
                        DeclSpace ds = TypeManager.LookupDeclSpace (type);
-                       if (ds != null) {
-                               return ds.IsClsCompliaceRequired (ds.Parent);
-                       }
+                       if (ds != null)
+                               return ds.IsClsComplianceRequired (ds.Parent);
 
-                       if (type.IsGenericParameter || type.IsGenericInstance)
-                               return false;
+                       if (type.IsGenericParameter)
+                               return true;
 
                        object[] CompliantAttribute = type.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
                        if (CompliantAttribute.Length == 0) 
@@ -1629,16 +1746,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)