2008-11-05 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / mcs / attribute.cs
index bf1759c70ea3a4cb582c648ef0dbb6662bf28fb4..f95ca55df2f1461b6ef21f65bcdbfb09b9904c2a 100644 (file)
@@ -4,10 +4,10 @@
 // Author: Ravi Pratap (ravi@ximian.com)
 //         Marek Safar (marek.safar@seznam.cz)
 //
-// Licensed under the terms of the GNU GPL
-//
-// (C) 2001 Ximian, Inc (http://www.ximian.com)
+// Dual licensed under the terms of the MIT X11 or GNU GPL
 //
+// Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+// Copyright 2003-2008 Novell, Inc.
 //
 
 using System;
@@ -75,7 +75,8 @@ namespace Mono.CSharp {
                public abstract string[] ValidAttributeTargets { get; }
        };
 
-       public class Attribute {
+       public class Attribute : Expression
+       {
                public readonly string ExplicitTarget;
                public AttributeTargets Target;
 
@@ -84,18 +85,14 @@ namespace Mono.CSharp {
                public readonly Expression LeftExpr;
                public readonly string Identifier;
 
-               readonly ArrayList PosArguments;
-               readonly ArrayList NamedArguments;
-
-               public readonly Location Location;
-
-               public Type Type;
+               ArrayList PosArguments;
+               ArrayList NamedArguments;
 
                bool resolve_error;
                readonly bool nameEscaped;
 
                // It can contain more onwers when the attribute is applied to multiple fiels.
-               Attributable[] owners;
+               protected Attributable[] owners;
 
                static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
                static Assembly orig_sec_assembly;
@@ -121,11 +118,19 @@ namespace Mono.CSharp {
                                PosArguments = (ArrayList)args [0];
                                NamedArguments = (ArrayList)args [1];                           
                        }
-                       Location = loc;
+                       this.loc = loc;
                        ExplicitTarget = target;
                        this.nameEscaped = nameEscaped;
                }
 
+               public Attribute Clone ()
+               {
+                       Attribute a = new Attribute (ExplicitTarget, LeftExpr, Identifier, null, loc, nameEscaped);
+                       a.PosArguments = PosArguments;
+                       a.NamedArguments = NamedArguments;
+                       return a;
+               }
+
                static Attribute ()
                {
                        Reset ();
@@ -137,7 +142,7 @@ namespace Mono.CSharp {
                        att_cache = new PtrHashtable ();
                }
 
-               public void AttachTo (Attributable owner)
+               public virtual void AttachTo (Attributable owner)
                {
                        if (this.owners == null) {
                                this.owners = new Attributable[1] { owner };
@@ -187,6 +192,11 @@ namespace Mono.CSharp {
                        Report.Error (596, Location, "The Guid attribute must be specified with the ComImport attribute");
                }
 
+               public void Error_MisusedExtensionAttribute ()
+               {
+                       Report.Error (1112, Location, "Do not use `{0}' directly. Use parameter modifier `this' instead", GetSignatureForError ());
+               }
+
                /// <summary>
                /// This is rather hack. We report many emit attribute error with same error to be compatible with
                /// csc. But because csc has to report them this way because error came from ilasm we needn't.
@@ -283,7 +293,7 @@ namespace Mono.CSharp {
                        return Type;
                }
 
-               public string GetSignatureForError ()
+               public override string GetSignatureForError ()
                {
                        if (Type != null)
                                return TypeManager.CSharpName (Type);
@@ -291,18 +301,53 @@ namespace Mono.CSharp {
                        return LeftExpr == null ? Identifier : LeftExpr.GetSignatureForError () + "." + Identifier;
                }
 
-               bool IsValidArgumentType (Type t)
+               public bool HasSecurityAttribute {
+                       get {
+                               return TypeManager.security_attr_type != null &&
+                               TypeManager.IsSubclassOf (type, TypeManager.security_attr_type);
+                       }
+               }
+
+               public bool IsValidSecurityAttribute ()
+               {
+                       return HasSecurityAttribute && IsSecurityActionValid (false);
+               }
+
+               static bool IsValidArgumentType (Type t)
                {
                        if (t.IsArray)
-                               t = t.GetElementType ();
+                               t = TypeManager.GetElementType (t);
 
-                       return TypeManager.IsPrimitiveType (t) ||
+                       return t == TypeManager.string_type ||
+                               TypeManager.IsPrimitiveType (t) ||
                                TypeManager.IsEnumType (t) ||
-                               t == TypeManager.string_type ||
                                t == TypeManager.object_type ||
                                t == TypeManager.type_type;
                }
 
+               [Conditional ("GMCS_SOURCE")]
+               void ApplyModuleCharSet ()
+               {
+                       if (Type != TypeManager.dllimport_type)
+                               return;
+
+                       if (!CodeGen.Module.HasDefaultCharSet)
+                               return;
+
+                       const string CharSetEnumMember = "CharSet";
+                       if (NamedArguments == null) {
+                               NamedArguments = new ArrayList (1);
+                       } else {
+                               foreach (DictionaryEntry de in NamedArguments) {
+                                       if ((string)de.Key == CharSetEnumMember)
+                                               return;
+                               }
+                       }
+                       
+                       NamedArguments.Add (new DictionaryEntry (CharSetEnumMember,
+                               new Argument (Constant.CreateConstant (typeof (CharSet), CodeGen.Module.DefaultCharSet, Location))));
+               }
+
                public CustomAttributeBuilder Resolve ()
                {
                        if (resolve_error)
@@ -335,8 +380,12 @@ namespace Mono.CSharp {
                        }
 
                        Attributable owner = Owner;
-                       EmitContext ec = new EmitContext (owner.ResolveContext, owner.ResolveContext.DeclContainer, owner.ResolveContext.DeclContainer,
-                               Location, null, null, owner.ResolveContext.DeclContainer.ModFlags, false);
+                       DeclSpace ds = owner.ResolveContext as DeclSpace;
+                       if (ds == null)
+                               ds = owner.ResolveContext.DeclContainer;
+                       
+                       EmitContext ec = new EmitContext (owner.ResolveContext, ds, owner.ResolveContext.DeclContainer,
+                               Location, null, typeof (Attribute), owner.ResolveContext.DeclContainer.ModFlags, false);
                        ec.IsAnonymousMethodAllowed = false;
 
                        ConstructorInfo ctor = ResolveConstructor (ec);
@@ -349,9 +398,14 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       CustomAttributeBuilder cb;
+                       ApplyModuleCharSet ();
 
+                       CustomAttributeBuilder cb;
                        try {
+                               // SRE does not allow private ctor but we want to report all source code errors
+                               if (ctor.IsPrivate)
+                                       return null;
+
                                if (NamedArguments == null) {
                                        cb = new CustomAttributeBuilder (ctor, pos_values);
 
@@ -389,74 +443,34 @@ namespace Mono.CSharp {
                                                return null;
                                }
                        }
-
-                       Expression mg = Expression.MemberLookup (ec.ContainerType,
+                       
+                       MethodGroupExpr mg = MemberLookupFinal (ec, ec.ContainerType,
                                Type, ".ctor", MemberTypes.Constructor,
                                BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                               Location);
+                               Location) as MethodGroupExpr;
 
                        if (mg == null)
                                return null;
 
-                       MethodBase constructor = Invocation.OverloadResolve (
-                               ec, (MethodGroupExpr) mg, PosArguments, false, Location);
-
-                       if (constructor == null)
+                       mg = mg.OverloadResolve (ec, ref PosArguments, false, Location);
+                       if (mg == null)
                                return null;
-
-                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (constructor);
-                       if (oa != null && !Owner.ResolveContext.IsInObsoleteScope) {
-                               AttributeTester.Report_ObsoleteMessage (oa, mg.GetSignatureForError (), mg.Location);
-                       }
-
+                       
+                       ConstructorInfo constructor = (ConstructorInfo)mg;
                        if (PosArguments == null) {
                                pos_values = EmptyObject;
-                               return (ConstructorInfo)constructor;
+                               return constructor;
                        }
 
-                       ParameterData pd = TypeManager.GetParameterData (constructor);
+                       AParametersCollection pd = TypeManager.GetParameterData (constructor);
 
                        int pos_arg_count = PosArguments.Count;
-                       int last_real_param = pd.Count;
-
                        pos_values = new object [pos_arg_count];
-
-                       if (pd.HasParams) {
-                               // When the params is not filled we need to put one
-                               if (last_real_param > pos_arg_count) {
-                                       object [] new_pos_values = new object [pos_arg_count + 1];
-                                       pos_values.CopyTo (new_pos_values, 0);
-                                       new_pos_values [pos_arg_count] = new object [] {} ;
-                                       pos_values = new_pos_values;
-                               }
-                               last_real_param--;
-                       }
-
                        for (int j = 0; j < pos_arg_count; ++j) {
                                Argument a = (Argument) PosArguments [j];
 
-                               if (!a.Expr.GetAttributableValue (a.Type, out pos_values [j]))
+                               if (!a.Expr.GetAttributableValue (ec, a.Type, out pos_values [j]))
                                        return null;
-                               
-                               if (j < last_real_param)
-                                       continue;
-                               
-                               if (j == last_real_param) {
-                                       object [] array = new object [pos_arg_count - last_real_param];
-                                       array [0] = pos_values [j];
-                                       pos_values [j] = array;
-                                       continue;
-                               }
-
-                               object [] params_array = (object []) pos_values [last_real_param];
-                               params_array [j - last_real_param] = pos_values [j];
-                       }
-
-                       // Adjust the size of the pos_values if it had params
-                       if (last_real_param != pos_arg_count) {
-                               object [] new_pos_values = new object [last_real_param + 1];
-                               Array.Copy (pos_values, new_pos_values, last_real_param + 1);
-                               pos_values = new_pos_values;
                        }
 
                        // Here we do the checks which should be done by corlib or by runtime.
@@ -478,7 +492,8 @@ namespace Mono.CSharp {
                        }
 
                        if (Type == TypeManager.indexer_name_type || Type == TypeManager.conditional_attribute_type) {
-                               if (!Tokenizer.IsValidIdentifier ((string)pos_values [0])) {
+                               string v = pos_values [0] as string;
+                               if (!Tokenizer.IsValidIdentifier (v) || Tokenizer.IsKeyword (v)) {
                                        Report.Error (633, ((Argument)PosArguments[0]).Expr.Location,
                                                "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
                                        return null;
@@ -486,13 +501,13 @@ namespace Mono.CSharp {
                        }
 
                        if (Type == TypeManager.methodimpl_attr_type && pos_values.Length == 1 &&
-                               pd.ParameterType (0) == TypeManager.short_type &&
+                               pd.Types [0] == TypeManager.short_type &&
                                !System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0].ToString ())) {
                                Error_AttributeEmitError ("Incorrect argument value.");
                                return null;
                        }
 
-                       return (ConstructorInfo)constructor;
+                       return constructor;
                }
 
                protected virtual bool ResolveNamedArguments (EmitContext ec)
@@ -510,7 +525,7 @@ namespace Mono.CSharp {
                                string member_name = (string) de.Key;
 
                                if (seen_names.Contains(member_name)) {
-                                       Report.Error(643, Location, "'" + member_name + "' duplicate named attribute argument");
+                                       Report.Error(643, Location, "'{0}' duplicate named attribute argument", member_name);
                                        return false;
                                }                               
                                seen_names.Add(member_name);
@@ -538,8 +553,7 @@ namespace Mono.CSharp {
                                }
 
                                if (member == null){
-                                       Report.Error (117, Location, "`{0}' does not contain a definition for `{1}'",
-                                                     TypeManager.CSharpName (Type), member_name);
+                                       Expression.Error_TypeDoesNotContainDefinition (Location, Type, member_name);
                                        return false;
                                }
                                
@@ -564,14 +578,14 @@ namespace Mono.CSharp {
                                                return false;
                                        }
 
-                                       if (!IsValidArgumentType (pi.PropertyType)) {
+                                       if (!IsValidArgumentType (member.Type)) {
                                                Report.SymbolRelatedToPreviousError (pi);
                                                Error_InvalidNamedAgrumentType (member_name);
                                                return false;
                                        }
 
                                        object value;
-                                       if (!a.Expr.GetAttributableValue (pi.PropertyType, out value))
+                                       if (!a.Expr.GetAttributableValue (ec, member.Type, out value))
                                                return false;
 
                                        PropertyBase pb = TypeManager.GetProperty (pi);
@@ -591,14 +605,14 @@ namespace Mono.CSharp {
                                                return false;
                                        }
 
-                                       if (!IsValidArgumentType (fi.FieldType)) {
+                                       if (!IsValidArgumentType (member.Type)) {
                                                Report.SymbolRelatedToPreviousError (fi);
                                                Error_InvalidNamedAgrumentType (member_name);
                                                return false;
                                        }
 
                                        object value;
-                                       if (!a.Expr.GetAttributableValue (fi.FieldType, out value))
+                                       if (!a.Expr.GetAttributableValue (ec, member.Type, out value))
                                                return false;
 
                                        FieldBase fb = TypeManager.GetField (fi);
@@ -635,7 +649,7 @@ namespace Mono.CSharp {
                public string GetValidTargets ()
                {
                        StringBuilder sb = new StringBuilder ();
-                       AttributeTargets targets = GetAttributeUsage ().ValidOn;
+                       AttributeTargets targets = GetAttributeUsage (Type).ValidOn;
 
                        if ((targets & AttributeTargets.Assembly) != 0)
                                sb.Append ("assembly, ");
@@ -687,32 +701,37 @@ namespace Mono.CSharp {
                }
 
                /// <summary>
-               /// Returns AttributeUsage attribute for this type
+               /// Returns AttributeUsage attribute based on types hierarchy
                /// </summary>
-               AttributeUsageAttribute GetAttributeUsage ()
+               static AttributeUsageAttribute GetAttributeUsage (Type type)
                {
-                       AttributeUsageAttribute ua = usage_attr_cache [Type] as AttributeUsageAttribute;
+                       AttributeUsageAttribute ua = usage_attr_cache [type] as AttributeUsageAttribute;
                        if (ua != null)
                                return ua;
 
-                       Class attr_class = TypeManager.LookupClass (Type);
+                       Class attr_class = TypeManager.LookupClass (type);
 
                        if (attr_class == null) {
-                               object[] usage_attr = Type.GetCustomAttributes (TypeManager.attribute_usage_type, true);
+                               object[] usage_attr = type.GetCustomAttributes (TypeManager.attribute_usage_type, true);
                                ua = (AttributeUsageAttribute)usage_attr [0];
-                               usage_attr_cache.Add (Type, ua);
+                               usage_attr_cache.Add (type, ua);
                                return ua;
                        }
 
-                       Attribute a = attr_class.OptAttributes == null
-                               ? null
-                               : attr_class.OptAttributes.Search (TypeManager.attribute_usage_type);
+                       Attribute a = null;
+                       if (attr_class.OptAttributes != null)
+                               a = attr_class.OptAttributes.Search (TypeManager.attribute_usage_type);
 
-                       ua = a == null
-                               ? DefaultUsageAttribute 
-                               : a.GetAttributeUsageAttribute ();
+                       if (a == null) {
+                               if (attr_class.TypeBuilder.BaseType != TypeManager.attribute_type)
+                                       ua = GetAttributeUsage (attr_class.TypeBuilder.BaseType);
+                               else
+                                       ua = DefaultUsageAttribute;
+                       } else {
+                               ua = a.GetAttributeUsageAttribute ();
+                       }
 
-                       usage_attr_cache.Add (Type, ua);
+                       usage_attr_cache.Add (type, ua);
                        return ua;
                }
 
@@ -833,11 +852,11 @@ namespace Mono.CSharp {
                        // TODO: we can skip the first item
                        if (((IList) valid_targets).Contains (ExplicitTarget)) {
                                switch (ExplicitTarget) {
-                                       case "return": Target = AttributeTargets.ReturnValue; return true;
-                                       case "param": Target = AttributeTargets.Parameter; return true;
-                                       case "field": Target = AttributeTargets.Field; return true;
-                                       case "method": Target = AttributeTargets.Method; return true;
-                                       case "property": Target = AttributeTargets.Property; return true;
+                               case "return": Target = AttributeTargets.ReturnValue; return true;
+                               case "param": Target = AttributeTargets.Parameter; return true;
+                               case "field": Target = AttributeTargets.Field; return true;
+                               case "method": Target = AttributeTargets.Method; return true;
+                               case "property": Target = AttributeTargets.Property; return true;
                                }
                                throw new InternalErrorException ("Unknown explicit target: " + ExplicitTarget);
                        }
@@ -856,7 +875,7 @@ namespace Mono.CSharp {
                /// <summary>
                /// Tests permitted SecurityAction for assembly or other types
                /// </summary>
-               public bool CheckSecurityActionValidity (bool for_assembly)
+               protected virtual bool IsSecurityActionValid (bool for_assembly)
                {
                        SecurityAction action = GetSecurityActionValue ();
 
@@ -943,7 +962,9 @@ namespace Mono.CSharp {
                                if (prop_info_arr != null) {
                                        for (int i = 0; i < prop_info_arr.Length; ++i) {
                                                PropertyInfo emited_pi = prop_info_arr [i];
-                                               PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name, emited_pi.PropertyType);
+                                               // FIXME: We are missing return type filter
+                                               // TODO: pi can be null
+                                               PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name);
 
                                                object old_instance = pi.PropertyType.IsEnum ?
                                                        System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) :
@@ -961,15 +982,15 @@ namespace Mono.CSharp {
                        // IS is correct because for corlib we are using an instance from old corlib
                        if (!(perm is System.Security.CodeAccessPermission)) {
                                switch (action) {
-                                       case SecurityAction.Demand:
-                                               action = (SecurityAction)13;
-                                               break;
-                                       case SecurityAction.LinkDemand:
-                                               action = (SecurityAction)14;
-                                               break;
-                                       case SecurityAction.InheritanceDemand:
-                                               action = (SecurityAction)15;
-                                               break;
+                               case SecurityAction.Demand:
+                                       action = (SecurityAction)13;
+                                       break;
+                               case SecurityAction.LinkDemand:
+                                       action = (SecurityAction)14;
+                                       break;
+                               case SecurityAction.InheritanceDemand:
+                                       action = (SecurityAction)15;
+                                       break;
                                }
                        }
 
@@ -988,14 +1009,6 @@ namespace Mono.CSharp {
                        ps.AddPermission (perm);
                }
 
-               static object GetValue (object value)
-               {
-                       if (value is EnumConstant)
-                               return ((EnumConstant) value).GetValue ();
-                       else
-                               return value;                           
-               }
-
                public object GetPropertyValue (string name)
                {
                        if (prop_info_arr == null)
@@ -1009,25 +1022,12 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               object GetFieldValue (string name)
-               {
-                       int i;
-                       if (field_info_arr == null)
-                               return null;
-                       i = 0;
-                       foreach (FieldInfo fi in field_info_arr) {
-                               if (fi.Name == name)
-                                       return GetValue (field_values_arr [i]);
-                               i++;
-                       }
-                       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.
                //
+#if !NET_2_0
                public UnmanagedMarshal GetMarshal (Attributable attr)
                {
                        UnmanagedType UnmanagedType;
@@ -1101,16 +1101,61 @@ namespace Mono.CSharp {
                        }
                }
 
+               object GetFieldValue (string name)
+               {
+                       int i;
+                       if (field_info_arr == null)
+                               return null;
+                       i = 0;
+                       foreach (FieldInfo fi in field_info_arr) {
+                               if (fi.Name == name)
+                                       return GetValue (field_values_arr [i]);
+                               i++;
+                       }
+                       return null;
+               }
+
+               static object GetValue (object value)
+               {
+                       if (value is EnumConstant)
+                               return ((EnumConstant) value).GetValue ();
+                       else
+                               return value;                           
+               }
+               
+#endif
+
                public CharSet GetCharSetValue ()
                {
                        return (CharSet)System.Enum.Parse (typeof (CharSet), pos_values [0].ToString ());
                }
 
-               public MethodImplOptions GetMethodImplOptions ()
+               public bool HasField (string fieldName)
                {
-                       if (pos_values [0].GetType () != typeof (MethodImplOptions))
-                               return (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values [0]);
-                       return (MethodImplOptions)pos_values [0];
+                       if (field_info_arr == null)
+                               return false;
+
+                       foreach (FieldInfo fi in field_info_arr) {
+                               if (fi.Name == fieldName)
+                                       return true;
+                       }
+
+                       return false;
+               }
+
+               public bool IsInternalMethodImplAttribute {
+                       get {
+                               if (Type != TypeManager.methodimpl_attr_type)
+                                       return false;
+
+                               MethodImplOptions options;
+                               if (pos_values[0].GetType () != typeof (MethodImplOptions))
+                                       options = (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values[0]);
+                               else
+                                       options = (MethodImplOptions)pos_values[0];
+
+                               return (options & MethodImplOptions.InternalCall) != 0;
+                       }
                }
 
                public LayoutKind GetLayoutKindValue ()
@@ -1149,7 +1194,7 @@ namespace Mono.CSharp {
                        if (cb == null)
                                return;
 
-                       AttributeUsageAttribute usage_attr = GetAttributeUsage ();
+                       AttributeUsageAttribute usage_attr = GetAttributeUsage (Type);
                        if ((usage_attr.ValidOn & Target) == 0) {
                                Report.Error (592, Location, "The attribute `{0}' is not valid on this declaration type. " +
                                              "It is valid on `{1}' declarations only",
@@ -1191,7 +1236,7 @@ namespace Mono.CSharp {
                                                        return;
 
                                                if (arg.Type.IsArray) {
-                                                       Report.Error (3016, Location, "Arrays as attribute arguments are not CLS-compliant");
+                                                       Report.Warning (3016, 1, Location, "Arrays as attribute arguments are not CLS-compliant");
                                                        return;
                                                }
                                        }
@@ -1208,127 +1253,12 @@ namespace Mono.CSharp {
                                                return;
 
                                        if (arg.Type.IsArray) {
-                                               Report.Error (3016, Location, "Arrays as attribute arguments are not CLS-compliant");
+                                               Report.Warning (3016, 1, Location, "Arrays as attribute arguments are not CLS-compliant");
                                                return;
                                        }
                                }
                        }
                }
-               
-               public MethodBuilder DefinePInvokeMethod (TypeBuilder builder, string name,
-                                                         MethodAttributes flags, Type ret_type, Type [] param_types)
-               {
-                       if (pos_values == null)
-                               // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
-                               // But because a lot of attribute class code must be rewritten will be better to wait...
-                               Resolve ();
-
-                       if (resolve_error)
-                               return null;
-                       
-                       string dll_name = (string)pos_values [0];
-
-                       // Default settings
-                       CallingConvention cc = CallingConvention.Winapi;
-                       CharSet charset = CodeGen.Module.DefaultCharSet;
-                       bool preserve_sig = true;
-                       string entry_point = name;
-                       bool best_fit_mapping = false;
-                       bool throw_on_unmappable = false;
-                       bool 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) {
-                               
-                               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 (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) ||
-                                   (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;
-                               }
-                       }
-
-                       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;
-                       }
-                       catch (ArgumentException e) {
-                               Error_AttributeEmitError (e.Message);
-                               return null;
-                       }
-               }
 
                private Expression GetValue () 
                {
@@ -1341,16 +1271,16 @@ namespace Mono.CSharp {
                public string GetString () 
                {
                        Expression e = GetValue ();
-                       if (e is StringLiteral)
-                               return (e as StringLiteral).Value;
+                       if (e is StringConstant)
+                               return ((StringConstant)e).Value;
                        return null;
                }
 
                public bool GetBoolean () 
                {
                        Expression e = GetValue ();
-                       if (e is BoolLiteral)
-                               return (e as BoolLiteral).Value;
+                       if (e is BoolConstant)
+                               return ((BoolConstant)e).Value;
                        return false;
                }
 
@@ -1361,6 +1291,21 @@ namespace Mono.CSharp {
                                return null;
                        return e.TypeArgument;
                }
+
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       throw new NotSupportedException ("ET");
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotImplementedException ();
+               }
        }
        
 
@@ -1377,6 +1322,20 @@ namespace Mono.CSharp {
                        base (target, left_expr, identifier, args, loc, nameEscaped)
                {
                        this.ns = ns;
+                       this.owners = new Attributable[1];
+               }
+               
+               public override void AttachTo (Attributable owner)
+               {
+                       if (ExplicitTarget == "assembly") {
+                               owners [0] = CodeGen.Assembly;
+                               return;
+                       }
+                       if (ExplicitTarget == "module") {
+                               owners [0] = CodeGen.Module;
+                               return;
+                       }
+                       throw new NotImplementedException ("Unknown global explicit target " + ExplicitTarget);
                }
 
                void Enter ()
@@ -1394,6 +1353,11 @@ namespace Mono.CSharp {
                        RootContext.ToplevelTypes.NamespaceEntry = ns;
                }
 
+               protected override bool IsSecurityActionValid (bool for_assembly)
+               {
+                       return base.IsSecurityActionValid (true);
+               }
+
                void Leave ()
                {
                        RootContext.ToplevelTypes.NamespaceEntry = null;
@@ -1458,6 +1422,15 @@ namespace Mono.CSharp {
                                a.AttachTo (attributable);
                }
 
+               public Attributes Clone ()
+               {
+                       ArrayList al = new ArrayList (Attrs.Count);
+                       foreach (Attribute a in Attrs)
+                               al.Add (a.Clone ());
+
+                       return new Attributes (al);
+               }
+
                /// <summary>
                /// Checks whether attribute target is valid for the current element
                /// </summary>
@@ -1517,7 +1490,8 @@ namespace Mono.CSharp {
                                        Report.SymbolRelatedToPreviousError (collision.Location, "");
 
                                Attribute a = (Attribute)d.Key;
-                               Report.Error (579, a.Location, "The attribute `{0}' cannot be applied multiple times", a.GetSignatureForError ());
+                               Report.Error (579, a.Location, "The attribute `{0}' cannot be applied multiple times",
+                                       a.GetSignatureForError ());
                        }
                }
 
@@ -1536,10 +1510,7 @@ namespace Mono.CSharp {
                static PtrHashtable analyzed_types_obsolete;
                static PtrHashtable analyzed_member_obsolete;
                static PtrHashtable analyzed_method_excluded;
-
-#if NET_2_0
                static PtrHashtable fixed_buffer_cache;
-#endif
 
                static object TRUE = new object ();
                static object FALSE = new object ();
@@ -1559,9 +1530,7 @@ namespace Mono.CSharp {
                        analyzed_types_obsolete = new PtrHashtable ();
                        analyzed_member_obsolete = new PtrHashtable ();
                        analyzed_method_excluded = new PtrHashtable ();
-#if NET_2_0
                        fixed_buffer_cache = new PtrHashtable ();
-#endif
                }
 
                public enum Result {
@@ -1574,8 +1543,10 @@ namespace Mono.CSharp {
                /// 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 Result AreOverloadedMethodParamsClsCompliant (Type[] types_a, Type[] types_b) 
+               public static Result AreOverloadedMethodParamsClsCompliant (AParametersCollection pa, AParametersCollection pb) 
                {
+                       Type [] types_a = pa.Types;
+                       Type [] types_b = pb.Types;
                        if (types_a == null || types_b == null)
                                return Result.Ok;
 
@@ -1601,25 +1572,10 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               Type aBaseType = aType;
-                               bool is_either_ref_or_out = false;
-
-                               if (aType.IsByRef || aType.IsPointer) {
-                                       aBaseType = aType.GetElementType ();
-                                       is_either_ref_or_out = true;
-                               }
-
-                               Type bBaseType = bType;
-                               if (bType.IsByRef || bType.IsPointer) 
-                               {
-                                       bBaseType = bType.GetElementType ();
-                                       is_either_ref_or_out = !is_either_ref_or_out;
-                               }
-
-                               if (aBaseType != bBaseType)
+                               if (aType != bType)
                                        return Result.Ok;
 
-                               if (is_either_ref_or_out)
+                               if (pa.FixedParameters [i].ModFlags != pb.FixedParameters [i].ModFlags)
                                        result = Result.RefOutArrayError;
                        }
                        return result;
@@ -1638,13 +1594,15 @@ namespace Mono.CSharp {
                                return type_compliance == TRUE;
 
                        if (type.IsPointer) {
-                               analyzed_types.Add (type, null);
+                               analyzed_types.Add (type, FALSE);
                                return false;
                        }
 
                        bool result;
-                       if (type.IsArray || type.IsByRef)       {
+                       if (type.IsArray) {
                                result = IsClsCompliant (TypeManager.GetElementType (type));
+                       } else if (TypeManager.IsNullableType (type)) {
+                               result = IsClsCompliant (TypeManager.GetTypeArguments (type) [0]);
                        } else {
                                result = AnalyzeTypeCompliance (type);
                        }
@@ -1665,11 +1623,16 @@ namespace Mono.CSharp {
                        if (fb != null) {
                                return fb as IFixedBuffer;
                        }
+                       
+                       if (TypeManager.GetConstant (fi) != null)
+                               return null;
 
-#if NET_2_0
                        object o = fixed_buffer_cache [fi];
                        if (o == null) {
-                               if (System.Attribute.GetCustomAttribute (fi, TypeManager.fixed_buffer_attr_type) == null) {
+                               if (TypeManager.fixed_buffer_attr_type == null)
+                                       return null;
+
+                               if (!fi.IsDefined (TypeManager.fixed_buffer_attr_type, false)) {
                                        fixed_buffer_cache.Add (fi, FALSE);
                                        return null;
                                }
@@ -1683,9 +1646,6 @@ namespace Mono.CSharp {
                                return null;
 
                        return (IFixedBuffer)o;
-#else
-                       return null;
-#endif         
                }
 
                public static void VerifyModulesClsCompliance ()
@@ -1697,7 +1657,7 @@ namespace Mono.CSharp {
                        // The first module is generated assembly
                        for (int i = 1; i < modules.Length; ++i) {
                                Module module = modules [i];
-                               if (!IsClsCompliant (module)) {
+                               if (!GetClsCompliantAttributeValue (module, null)) {
                                        Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute " +
                                                      "to match the assembly", module.Name);
                                        return;
@@ -1718,13 +1678,20 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               static bool IsClsCompliant (ICustomAttributeProvider attribute_provider
+               static bool GetClsCompliantAttributeValue (ICustomAttributeProvider attribute_provider, Assembly a
                {
-                       object[] CompliantAttribute = attribute_provider.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
-                       if (CompliantAttribute.Length == 0)
+                       if (TypeManager.cls_compliant_attribute_type == null)
                                return false;
 
-                       return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;
+                       object[] cls_attr = attribute_provider.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
+                       if (cls_attr.Length == 0) {
+                               if (a == null)
+                                       return false;
+
+                               return GetClsCompliantAttributeValue (a, null);
+                       }
+                       
+                       return ((CLSCompliantAttribute)cls_attr [0]).IsCompliant;
                }
 
                static bool AnalyzeTypeCompliance (Type type)
@@ -1738,18 +1705,7 @@ namespace Mono.CSharp {
                        if (TypeManager.IsGenericParameter (type))
                                return true;
 
-                       object[] CompliantAttribute = type.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
-                       if (CompliantAttribute.Length == 0) 
-                               return IsClsCompliant (type.Assembly);
-
-                       return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;
-               }
-
-               // Registers the core type as we assume that they will never be obsolete which
-               // makes things easier for bootstrap and faster (we don't need to query Obsolete attribute).
-               public static void RegisterNonObsoleteType (Type type)
-               {
-                       analyzed_types_obsolete [type] = FALSE;
+                       return GetClsCompliantAttributeValue (type, type.Assembly);
                }
 
                /// <summary>
@@ -1774,9 +1730,11 @@ namespace Mono.CSharp {
 
                                // Type is external, we can get attribute directly
                                if (type_ds == null) {
-                                       object[] attribute = type.GetCustomAttributes (TypeManager.obsolete_attribute_type, false);
-                                       if (attribute.Length == 1)
-                                               result = (ObsoleteAttribute)attribute [0];
+                                       if (TypeManager.obsolete_attribute_type != null) {
+                                               object [] attribute = type.GetCustomAttributes (TypeManager.obsolete_attribute_type, false);
+                                               if (attribute.Length == 1)
+                                                       result = (ObsoleteAttribute) attribute [0];
+                                       }
                                } else {
                                        result = type_ds.GetObsoleteAttribute ();
                                }
@@ -1826,6 +1784,9 @@ namespace Mono.CSharp {
                        if ((mi.DeclaringType is TypeBuilder) || TypeManager.IsGenericType (mi.DeclaringType))
                                return null;
 
+                       if (TypeManager.obsolete_attribute_type == null)
+                               return null;
+
                        ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false)
                                as ObsoleteAttribute;
                        analyzed_member_obsolete.Add (mi, oa == null ? FALSE : oa);
@@ -1842,23 +1803,22 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (oa.Message == null) {
+                       if (oa.Message == null || oa.Message.Length == 0) {
                                Report.Warning (612, 1, loc, "`{0}' is obsolete", member);
                                return;
                        }
                        Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
                }
 
-               public static bool IsConditionalMethodExcluded (MethodBase mb)
+               public static bool IsConditionalMethodExcluded (MethodBase mb, Location loc)
                {
-                       mb = TypeManager.DropGenericMethodArguments (mb);
-                       if ((mb is MethodBuilder) || (mb is ConstructorBuilder))
-                               return false;
-
                        object excluded = analyzed_method_excluded [mb];
                        if (excluded != null)
                                return excluded == TRUE ? true : false;
 
+                       if (TypeManager.conditional_attribute_type == null)
+                               return false;
+
                        ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true)
                                as ConditionalAttribute[];
                        if (attrs.Length == 0) {
@@ -1867,11 +1827,12 @@ namespace Mono.CSharp {
                        }
 
                        foreach (ConditionalAttribute a in attrs) {
-                               if (RootContext.AllDefines.Contains (a.ConditionString)) {
+                               if (loc.CompilationUnit.IsConditionalDefined (a.ConditionString)) {
                                        analyzed_method_excluded.Add (mb, FALSE);
                                        return false;
                                }
                        }
+
                        analyzed_method_excluded.Add (mb, TRUE);
                        return true;
                }
@@ -1880,7 +1841,7 @@ namespace Mono.CSharp {
                /// Analyzes class whether it has attribute which has ConditionalAttribute
                /// and its condition is not defined.
                /// </summary>
-               public static bool IsAttributeExcluded (Type type)
+               public static bool IsAttributeExcluded (Type type, Location loc)
                {
                        if (!type.IsClass)
                                return false;
@@ -1889,10 +1850,10 @@ namespace Mono.CSharp {
 
                        // TODO: add caching
                        // TODO: merge all Type bases attribute caching to one cache to save memory
-                       if (class_decl == null) {
+                       if (class_decl == null && TypeManager.conditional_attribute_type != null) {
                                object[] attributes = type.GetCustomAttributes (TypeManager.conditional_attribute_type, false);
                                foreach (ConditionalAttribute ca in attributes) {
-                                       if (RootContext.AllDefines.Contains (ca.ConditionString))
+                                       if (loc.CompilationUnit.IsConditionalDefined (ca.ConditionString))
                                                return false;
                                }
                                return attributes.Length > 0;
@@ -1905,13 +1866,16 @@ namespace Mono.CSharp {
                {
                        TypeContainer tc = TypeManager.LookupInterface (type);
                        if (tc == null) {
+                               if (TypeManager.coclass_attr_type == null)
+                                       return null;
+
                                object[] o = type.GetCustomAttributes (TypeManager.coclass_attr_type, false);
                                if (o.Length < 1)
                                        return null;
                                return ((System.Runtime.InteropServices.CoClassAttribute)o[0]).CoClass;
                        }
 
-                       if (tc.OptAttributes == null)
+                       if (tc.OptAttributes == null || TypeManager.coclass_attr_type == null)
                                return null;
 
                        Attribute a = tc.OptAttributes.Search (TypeManager.coclass_attr_type);