2007-10-17 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / mcs / attribute.cs
index 8cb2499e6f9652ced3090aa46ab599d0e71dda65..612f299403fd70fa8d4ed4409697e9760ef51b64 100644 (file)
@@ -36,7 +36,8 @@ namespace Mono.CSharp {
 
                public Attributable (Attributes attrs)
                {
-                       OptAttributes = attrs;
+                       if (attrs != null)
+                               OptAttributes = attrs;
                }
 
                public Attributes OptAttributes 
@@ -84,7 +85,7 @@ namespace Mono.CSharp {
                public readonly string Identifier;
 
                readonly ArrayList PosArguments;
-               readonly ArrayList NamedArguments;
+               ArrayList NamedArguments;
 
                public readonly Location Location;
 
@@ -92,7 +93,9 @@ namespace Mono.CSharp {
 
                bool resolve_error;
                readonly bool nameEscaped;
-               Attributable owner;
+
+               // It can contain more onwers when the attribute is applied to multiple fiels.
+               protected Attributable[] owners;
 
                static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
                static Assembly orig_sec_assembly;
@@ -105,10 +108,9 @@ namespace Mono.CSharp {
                object [] prop_values_arr;
                object [] pos_values;
 
-               static PtrHashtable usage_attr_cache = new PtrHashtable ();
-
+               static PtrHashtable usage_attr_cache;
                // Cache for parameter-less attributes
-               static PtrHashtable att_cache = new PtrHashtable ();
+               static PtrHashtable att_cache;
                
                public Attribute (string target, Expression left_expr, string identifier, object[] args, Location loc, bool nameEscaped)
                {
@@ -124,9 +126,33 @@ namespace Mono.CSharp {
                        this.nameEscaped = nameEscaped;
                }
 
-               public void AttachTo (Attributable owner)
+               static Attribute ()
+               {
+                       Reset ();
+               }
+
+               public static void Reset ()
                {
-                       this.owner = owner;
+                       usage_attr_cache = new PtrHashtable ();
+                       att_cache = new PtrHashtable ();
+               }
+
+               public virtual void AttachTo (Attributable owner)
+               {
+                       if (this.owners == null) {
+                               this.owners = new Attributable[1] { owner };
+                               return;
+                       }
+
+                       // When the same attribute is attached to multiple fiels
+                       // we use this extra_owners as a list of owners. The attribute
+                       // then can be removed because will be emitted when first owner
+                       // is served
+                       Attributable[] new_array = new Attributable [this.owners.Length + 1];
+                       owners.CopyTo (new_array, 0);
+                       new_array [owners.Length] = owner;
+                       this.owners = new_array;
+                       owner.OptAttributes = null;
                }
 
                void Error_InvalidNamedArgument (string name)
@@ -148,7 +174,23 @@ namespace Mono.CSharp {
                        Report.Error (182, loc,
                                      "An attribute argument must be a constant expression, typeof " +
                                      "expression or array creation expression");
-               }               
+               }
+               
+               static void Error_TypeParameterInAttribute (Location loc)
+               {
+                       Report.Error (
+                               -202, loc, "Can not use a type parameter in an attribute");
+               }
+
+               public void Error_MissingGuidAttribute ()
+               {
+                       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
@@ -165,6 +207,12 @@ namespace Mono.CSharp {
                        Error_AttributeEmitError ("it is attached to invalid parent");
                }
 
+               Attributable Owner {
+                       get {
+                               return owners [0];
+                       }
+               }
+
                protected virtual TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec, bool silent)
                {
                        return expr.ResolveAsTypeTerminal (ec, silent);
@@ -172,7 +220,7 @@ namespace Mono.CSharp {
 
                Type ResolvePossibleAttributeType (string name, bool silent, ref bool is_attr)
                {
-                       IResolveContext rc = owner.ResolveContext;
+                       IResolveContext rc = Owner.ResolveContext;
 
                        TypeExpr te;
                        if (LeftExpr == null) {
@@ -260,6 +308,29 @@ namespace Mono.CSharp {
                                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)
@@ -291,15 +362,24 @@ 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);
+                               Location, null, typeof (Attribute), owner.ResolveContext.DeclContainer.ModFlags, false);
+                       ec.IsAnonymousMethodAllowed = false;
 
                        ConstructorInfo ctor = ResolveConstructor (ec);
-                       if (ctor == null)
+                       if (ctor == null) {
+                               if (Type is TypeBuilder && 
+                                   TypeManager.LookupDeclSpace (Type).MemberCache == null)
+                                       // The attribute type has been DefineType'd, but not Defined.  Let's not treat it as an error.
+                                       // It'll be resolved again when the attached-to entity is emitted.
+                                       resolve_error = false;
                                return null;
+                       }
 
-                       CustomAttributeBuilder cb;
+                       ApplyModuleCharSet ();
 
+                       CustomAttributeBuilder cb;
                        try {
                                if (NamedArguments == null) {
                                        cb = new CustomAttributeBuilder (ctor, pos_values);
@@ -339,25 +419,29 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       Expression mg = Expression.MemberLookup (ec.ContainerType,
+                       MethodGroupExpr mg = Expression.MemberLookup (ec.ContainerType,
                                Type, ".ctor", MemberTypes.Constructor,
                                BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                               Location);
+                               Location) as MethodGroupExpr;
 
-                       MethodBase constructor = Invocation.OverloadResolve (
-                               ec, (MethodGroupExpr) mg, PosArguments, false, Location);
+                       if (mg == null)
+                               return null;
 
-                       if (constructor == null)
+                       mg = mg.OverloadResolve (ec, PosArguments, false, Location);
+                       if (mg == null)
                                return null;
+                       
+                       ConstructorInfo constructor = (ConstructorInfo)mg;
 
+                       // TODO: move to OverloadResolve
                        ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (constructor);
-                       if (oa != null && !owner.ResolveContext.IsInObsoleteScope) {
+                       if (oa != null && !Owner.ResolveContext.IsInObsoleteScope) {
                                AttributeTester.Report_ObsoleteMessage (oa, mg.GetSignatureForError (), mg.Location);
                        }
 
                        if (PosArguments == null) {
                                pos_values = EmptyObject;
-                               return (ConstructorInfo)constructor;
+                               return constructor;
                        }
 
                        ParameterData pd = TypeManager.GetParameterData (constructor);
@@ -381,15 +465,9 @@ namespace Mono.CSharp {
                        for (int j = 0; j < pos_arg_count; ++j) {
                                Argument a = (Argument) PosArguments [j];
 
-                               if (!a.Expr.GetAttributableValue (out pos_values [j]))
+                               if (!a.Expr.GetAttributableValue (a.Type, out pos_values [j]))
                                        return null;
                                
-                               if (TypeManager.IsPrimitiveType (a.Type) && a.Type != pos_values [j].GetType ()) {
-                                       bool fail;
-                                       // This can happen only for constants in same range
-                                       pos_values [j] = TypeManager.ChangeType (pos_values [j], a.Type, out fail);
-                               }
-
                                if (j < last_real_param)
                                        continue;
                                
@@ -425,10 +503,18 @@ namespace Mono.CSharp {
                        }
 
                        if (Type == TypeManager.attribute_usage_type && (int)pos_values [0] == 0) {
-                               Report.Error (591, Location, "Invalid value for argument to 'System.AttributeUsage' attribute");
+                               Report.Error (591, Location, "Invalid value for argument to `System.AttributeUsage' attribute");
                                return null;
                        }
 
+                       if (Type == TypeManager.indexer_name_type || Type == TypeManager.conditional_attribute_type) {
+                               if (!Tokenizer.IsValidIdentifier ((string)pos_values [0])) {
+                                       Report.Error (633, ((Argument)PosArguments[0]).Expr.Location,
+                                               "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
+                                       return null;
+                               }
+                       }
+
                        if (Type == TypeManager.methodimpl_attr_type && pos_values.Length == 1 &&
                                pd.ParameterType (0) == TypeManager.short_type &&
                                !System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0].ToString ())) {
@@ -475,14 +561,14 @@ namespace Mono.CSharp {
                                                Location);
 
                                        if (member != null) {
+                                               Report.SymbolRelatedToPreviousError (member.Type);
                                                Expression.ErrorIsInaccesible (Location, member.GetSignatureForError ());
                                                return false;
                                        }
                                }
 
                                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;
                                }
                                
@@ -491,6 +577,11 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
+                               if (a.Expr is TypeParameterExpr){
+                                       Error_TypeParameterInAttribute (Location);
+                                       return false;
+                               }
+
                                ObsoleteAttribute obsolete_attr;
 
                                if (member is PropertyExpr) {
@@ -508,12 +599,8 @@ namespace Mono.CSharp {
                                                return false;
                                        }
 
-                                       Expression e = Convert.ImplicitConversionRequired (ec, a.Expr, pi.PropertyType, a.Expr.Location);
-                                       if (e == null)
-                                               return false;
-
                                        object value;
-                                       if (!e.GetAttributableValue (out value))
+                                       if (!a.Expr.GetAttributableValue (pi.PropertyType, out value))
                                                return false;
 
                                        PropertyBase pb = TypeManager.GetProperty (pi);
@@ -539,12 +626,8 @@ namespace Mono.CSharp {
                                                return false;
                                        }
 
-                                       Expression e = Convert.ImplicitConversionRequired (ec, a.Expr, fi.FieldType, a.Expr.Location);
-                                       if (e == null)
-                                               return false;
-
                                        object value;
-                                       if (!e.GetAttributableValue (out value))
+                                       if (!a.Expr.GetAttributableValue (fi.FieldType, out value))
                                                return false;
 
                                        FieldBase fb = TypeManager.GetField (fi);
@@ -557,7 +640,7 @@ namespace Mono.CSharp {
                                        field_infos.Add (fi);
                                }
 
-                               if (obsolete_attr != null && !owner.ResolveContext.IsInObsoleteScope)
+                               if (obsolete_attr != null && !Owner.ResolveContext.IsInObsoleteScope)
                                        AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location);
                        }
 
@@ -581,7 +664,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, ");
@@ -633,32 +716,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;
                }
 
@@ -770,9 +858,9 @@ namespace Mono.CSharp {
 
                public bool CheckTarget ()
                {
-                       string[] valid_targets = owner.ValidAttributeTargets;
+                       string[] valid_targets = Owner.ValidAttributeTargets;
                        if (ExplicitTarget == null || ExplicitTarget == valid_targets [0]) {
-                               Target = owner.AttributeTargets;
+                               Target = Owner.AttributeTargets;
                                return true;
                        }
 
@@ -804,21 +892,29 @@ namespace Mono.CSharp {
                /// </summary>
                public bool CheckSecurityActionValidity (bool for_assembly)
                {
-                       SecurityAction action  = GetSecurityActionValue ();
+                       SecurityAction action = GetSecurityActionValue ();
 
-                       if ((action == SecurityAction.RequestMinimum || action == SecurityAction.RequestOptional ||
-                            action == SecurityAction.RequestRefuse) && for_assembly)
-                               return true;
-                       
-                       if (!for_assembly) {
-                               if (action < SecurityAction.Demand || action > SecurityAction.InheritanceDemand) {
-                                       Error_AttributeEmitError ("SecurityAction is out of range");
-                                       return false;
-                               }
-                               
-                               if ((action != SecurityAction.RequestMinimum && action != SecurityAction.RequestOptional &&
-                                    action != SecurityAction.RequestRefuse) && !for_assembly)
+                       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;
+
+                       case SecurityAction.RequestMinimum:
+                       case SecurityAction.RequestOptional:
+                       case SecurityAction.RequestRefuse:
+                               if (for_assembly)
                                        return true;
+                               break;
+
+                       default:
+                               Error_AttributeEmitError ("SecurityAction is out of range");
+                               return false;
                        }
 
                        Error_AttributeEmitError (String.Concat ("SecurityAction `", action, "' is not valid for this declaration"));
@@ -1024,7 +1120,7 @@ namespace Mono.CSharp {
                                return UnmanagedMarshal.DefineSafeArray (array_sub_type);
 
                        case UnmanagedType.ByValArray:
-                               FieldMember fm = attr as FieldMember;
+                               FieldBase fm = attr as FieldBase;
                                if (fm == null) {
                                        Error_AttributeEmitError ("Specified unmanaged type is only valid on fields");
                                        return null;
@@ -1044,11 +1140,19 @@ namespace Mono.CSharp {
                        return (CharSet)System.Enum.Parse (typeof (CharSet), pos_values [0].ToString ());
                }
 
-               public MethodImplOptions GetMethodImplOptions ()
-               {
-                       if (pos_values [0].GetType () != typeof (MethodImplOptions))
-                               return (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values [0]);
-                       return (MethodImplOptions)pos_values [0];
+               public 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 ()
@@ -1059,6 +1163,11 @@ namespace Mono.CSharp {
                        return (LayoutKind)pos_values [0];
                }
 
+               public object GetParameterDefaultValue ()
+               {
+                       return pos_values [0];
+               }
+
                public override bool Equals (object obj)
                {
                        Attribute a = obj as Attribute;
@@ -1082,7 +1191,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",
@@ -1091,7 +1200,8 @@ namespace Mono.CSharp {
                        }
 
                        try {
-                               owner.ApplyAttributeBuilder (this, cb);
+                               foreach (Attributable owner in owners)
+                                       owner.ApplyAttributeBuilder (this, cb);
                        }
                        catch (Exception e) {
                                Error_AttributeEmitError (e.Message);
@@ -1115,7 +1225,7 @@ namespace Mono.CSharp {
                                return;
 
                        // Here we are testing attribute arguments for array usage (error 3016)
-                       if (owner.IsClsComplianceRequired ()) {
+                       if (Owner.IsClsComplianceRequired ()) {
                                if (PosArguments != null) {
                                        foreach (Argument arg in PosArguments) { 
                                                // Type is undefined (was error 246)
@@ -1146,121 +1256,6 @@ namespace Mono.CSharp {
                                }
                        }
                }
-               
-               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 () 
                {
@@ -1273,18 +1268,26 @@ 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;
                }
+
+               public Type GetArgumentType ()
+               {
+                       TypeOf e = GetValue () as TypeOf;
+                       if (e == null)
+                               return null;
+                       return e.TypeArgument;
+               }
        }
        
 
@@ -1301,26 +1304,40 @@ 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 ()
                {
-                       // RootContext.Tree.Types has a single NamespaceEntry which gets overwritten
+                       // RootContext.ToplevelTypes has a single NamespaceEntry which gets overwritten
                        // each time a new file is parsed.  However, we need to use the NamespaceEntry
                        // in effect where the attribute was used.  Since code elsewhere cannot assume
                        // that the NamespaceEntry is right, just overwrite it.
                        //
-                       // Precondition: RootContext.Tree.Types == null
+                       // Precondition: RootContext.ToplevelTypes == null
 
-                       if (RootContext.Tree.Types.NamespaceEntry != null)
+                       if (RootContext.ToplevelTypes.NamespaceEntry != null)
                                throw new InternalErrorException (Location + " non-null NamespaceEntry");
 
-                       RootContext.Tree.Types.NamespaceEntry = ns;
+                       RootContext.ToplevelTypes.NamespaceEntry = ns;
                }
 
                void Leave ()
                {
-                       RootContext.Tree.Types.NamespaceEntry = null;
+                       RootContext.ToplevelTypes.NamespaceEntry = null;
                }
 
                protected override TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec, bool silent)
@@ -1441,7 +1458,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 ());
                        }
                }
 
@@ -1456,22 +1474,38 @@ namespace Mono.CSharp {
        /// </summary>
        sealed class AttributeTester
        {
-               static PtrHashtable analyzed_types = new PtrHashtable ();
-               static PtrHashtable analyzed_types_obsolete = new PtrHashtable ();
-               static PtrHashtable analyzed_member_obsolete = new PtrHashtable ();
-               static PtrHashtable analyzed_method_excluded = new PtrHashtable ();
+               static PtrHashtable analyzed_types;
+               static PtrHashtable analyzed_types_obsolete;
+               static PtrHashtable analyzed_member_obsolete;
+               static PtrHashtable analyzed_method_excluded;
 
 #if NET_2_0
-               static PtrHashtable fixed_buffer_cache = new PtrHashtable ();
+               static PtrHashtable fixed_buffer_cache;
 #endif
 
                static object TRUE = new object ();
                static object FALSE = new object ();
 
+               static AttributeTester ()
+               {
+                       Reset ();
+               }
+
                private AttributeTester ()
                {
                }
 
+               public static void Reset ()
+               {
+                       analyzed_types = new PtrHashtable ();
+                       analyzed_types_obsolete = new PtrHashtable ();
+                       analyzed_member_obsolete = new PtrHashtable ();
+                       analyzed_method_excluded = new PtrHashtable ();
+#if NET_2_0
+                       fixed_buffer_cache = new PtrHashtable ();
+#endif
+               }
+
                public enum Result {
                        Ok,
                        RefOutArrayError,
@@ -1551,8 +1585,10 @@ namespace Mono.CSharp {
                        }
 
                        bool result;
-                       if (type.IsArray || type.IsByRef)       {
+                       if (type.IsArray || type.IsByRef) {
                                result = IsClsCompliant (TypeManager.GetElementType (type));
+                       } else if (TypeManager.IsNullableType (type)) {
+                               result = IsClsCompliant (TypeManager.GetTypeArguments (type) [0]);
                        } else {
                                result = AnalyzeTypeCompliance (type);
                        }
@@ -1565,15 +1601,22 @@ namespace Mono.CSharp {
                /// </summary>
                public static IFixedBuffer GetFixedBuffer (FieldInfo fi)
                {
+                       // Fixed buffer helper type is generated as value type
+                       if (!fi.FieldType.IsValueType)
+                               return null;
+
                        FieldBase fb = TypeManager.GetField (fi);
                        if (fb != null) {
                                return fb as IFixedBuffer;
                        }
+                       
+                       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 (!fi.IsDefined (TypeManager.fixed_buffer_attr_type, false)) {
                                        fixed_buffer_cache.Add (fi, FALSE);
                                        return null;
                                }
@@ -1589,7 +1632,7 @@ namespace Mono.CSharp {
                        return (IFixedBuffer)o;
 #else
                        return null;
-#endif
+#endif         
                }
 
                public static void VerifyModulesClsCompliance ()
@@ -1633,11 +1676,15 @@ namespace Mono.CSharp {
 
                static bool AnalyzeTypeCompliance (Type type)
                {
+                       type = TypeManager.DropGenericTypeArguments (type);
                        DeclSpace ds = TypeManager.LookupDeclSpace (type);
                        if (ds != null) {
                                return ds.IsClsComplianceRequired ();
                        }
 
+                       if (TypeManager.IsGenericParameter (type))
+                               return true;
+
                        object[] CompliantAttribute = type.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
                        if (CompliantAttribute.Length == 0) 
                                return IsClsCompliant (type.Assembly);
@@ -1645,6 +1692,13 @@ namespace Mono.CSharp {
                        return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;
                }
 
+               // Registers the core type as we assume that they will never be obsolete which
+               // makes things easier for bootstrap and faster (we don't need to query Obsolete attribute).
+               public static void RegisterNonObsoleteType (Type type)
+               {
+                       analyzed_types_obsolete [type] = FALSE;
+               }
+
                /// <summary>
                /// Returns instance of ObsoleteAttribute when type is obsolete
                /// </summary>
@@ -1658,9 +1712,11 @@ namespace Mono.CSharp {
                                return (ObsoleteAttribute)type_obsolete;
 
                        ObsoleteAttribute result = null;
-                       if (type.IsByRef || type.IsArray || type.IsPointer) {
+                       if (TypeManager.HasElementType (type)) {
                                result = GetObsoleteAttribute (TypeManager.GetElementType (type));
-                       } else {
+                       } else if (TypeManager.IsGenericParameter (type) || TypeManager.IsGenericType (type))
+                               return null;
+                       else {
                                DeclSpace type_ds = TypeManager.LookupDeclSpace (type);
 
                                // Type is external, we can get attribute directly
@@ -1669,9 +1725,7 @@ namespace Mono.CSharp {
                                        if (attribute.Length == 1)
                                                result = (ObsoleteAttribute)attribute [0];
                                } else {
-                                       // Is null during corlib bootstrap
-                                       if (TypeManager.obsolete_attribute_type != null)
-                                               result = type_ds.GetObsoleteAttribute ();
+                                       result = type_ds.GetObsoleteAttribute ();
                                }
                        }
 
@@ -1693,14 +1747,13 @@ namespace Mono.CSharp {
                        if (mb.DeclaringType is TypeBuilder)
                                return null;
 
-                       if (mb.IsSpecialName) {
-                               PropertyInfo pi = PropertyExpr.AccessorTable [mb] as PropertyInfo;
-                               if (pi != null) {
-                                       // FIXME: This is buggy as properties from this assembly are included as well
-                                       return null;
-                                       //return GetMemberObsoleteAttribute (pi);
-                               }
-                       }
+                       MemberInfo mi = TypeManager.GetPropertyFromAccessor (mb);
+                       if (mi != null)
+                               return GetMemberObsoleteAttribute (mi);
+
+                       mi = TypeManager.GetEventFromAccessor (mb);
+                       if (mi != null)
+                               return GetMemberObsoleteAttribute (mi);
 
                        return GetMemberObsoleteAttribute (mb);
                }
@@ -1717,6 +1770,9 @@ namespace Mono.CSharp {
                        if (type_obsolete != null)
                                return (ObsoleteAttribute)type_obsolete;
 
+                       if ((mi.DeclaringType is TypeBuilder) || TypeManager.IsGenericType (mi.DeclaringType))
+                               return null;
+
                        ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false)
                                as ObsoleteAttribute;
                        analyzed_member_obsolete.Add (mi, oa == null ? FALSE : oa);
@@ -1742,10 +1798,15 @@ namespace Mono.CSharp {
 
                public static bool IsConditionalMethodExcluded (MethodBase mb)
                {
+                       mb = TypeManager.DropGenericMethodArguments (mb);
+                       // TODO: Has to be fixed for partial methods
+                       if ((mb is MethodBuilder) || (mb is ConstructorBuilder))
+                               return false;
+
                        object excluded = analyzed_method_excluded [mb];
                        if (excluded != null)
                                return excluded == TRUE ? true : false;
-                       
+
                        ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true)
                                as ConditionalAttribute[];
                        if (attrs.Length == 0) {