* ImportTest.cs (Add1): Fix test on windows.
[mono.git] / mcs / mcs / attribute.cs
index cb37b36ac690f98671dd4340b1efa4437221807b..caaad5513bbc523c2d85925cb0c82a09cd5471b4 100644 (file)
@@ -12,8 +12,7 @@
 
 using System;
 using System.Diagnostics;
-using System.Collections;
-using System.Collections.Specialized;
+using System.Collections.Generic;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Runtime.InteropServices;
@@ -29,43 +28,43 @@ namespace Mono.CSharp {
        ///   Base class for objects that can have Attributes applied to them.
        /// </summary>
        public abstract class Attributable {
-               /// <summary>
-               ///   Attributes for this type
-               /// </summary>
+               //
+               // Holds all attributes attached to this element
+               //
                protected Attributes attributes;
 
-               public Attributable (Attributes attrs)
+               public void AddAttributes (Attributes attrs, IMemberContext context)
                {
-                       if (attrs != null)
-                               OptAttributes = attrs;
+                       if (attrs == null)
+                               return;
+
+                       if (attributes == null)
+                               attributes = attrs;
+                       else
+                               throw new NotImplementedException ();
+
+                       attributes.AttachTo (this, context);
                }
 
-               public Attributes OptAttributes 
-               {
+               public Attributes OptAttributes {
                        get {
                                return attributes;
                        }
                        set {
                                attributes = value;
-
-                               if (attributes != null) {
-                                       attributes.AttachTo (this);
-                               }
                        }
                }
 
                /// <summary>
                /// Use member-specific procedure to apply attribute @a in @cb to the entity being built in @builder
                /// </summary>
-               public abstract void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb);
+               public abstract void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa);
 
                /// <summary>
                /// Returns one AttributeTarget for this element.
                /// </summary>
                public abstract AttributeTargets AttributeTargets { get; }
 
-               public abstract IResolveContext ResolveContext { get; }
-
                public abstract bool IsClsComplianceRequired ();
 
                /// <summary>
@@ -79,20 +78,24 @@ namespace Mono.CSharp {
        {
                public readonly string ExplicitTarget;
                public AttributeTargets Target;
+               readonly ATypeNameExpression expression;
 
-               // TODO: remove this member
-               public readonly string    Name;
-               public readonly Expression LeftExpr;
-               public readonly string Identifier;
-
-               ArrayList PosArguments;
-               ArrayList NamedArguments;
+               Arguments PosArguments;
+               Arguments NamedArguments;
 
                bool resolve_error;
                readonly bool nameEscaped;
 
-               // It can contain more onwers when the attribute is applied to multiple fiels.
-               protected Attributable[] owners;
+               //
+               // An attribute can be attached to multiple targets (e.g. multiple fields)
+               //
+               protected Attributable[] targets;
+
+               //
+               // A member context for the attribute, it's much easier to hold it here
+               // than trying to pull it during resolve
+               //
+               IMemberContext context;
 
                static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
                static Assembly orig_sec_assembly;
@@ -105,18 +108,16 @@ namespace Mono.CSharp {
                object [] prop_values_arr;
                object [] pos_values;
 
-               static PtrHashtable usage_attr_cache;
+               static Dictionary<Type, AttributeUsageAttribute> usage_attr_cache;
                // Cache for parameter-less attributes
-               static PtrHashtable att_cache;
-               
-               public Attribute (string target, Expression left_expr, string identifier, object[] args, Location loc, bool nameEscaped)
+               static Dictionary<Type, CustomAttributeBuilder> att_cache;
+
+               public Attribute (string target, ATypeNameExpression expr, Arguments[] args, Location loc, bool nameEscaped)
                {
-                       LeftExpr = left_expr;
-                       Identifier = identifier;
-                       Name = LeftExpr == null ? identifier : LeftExpr + "." + identifier;
+                       this.expression = expr;
                        if (args != null) {
-                               PosArguments = (ArrayList)args [0];
-                               NamedArguments = (ArrayList)args [1];                           
+                               PosArguments = args [0];
+                               NamedArguments = args [1];                              
                        }
                        this.loc = loc;
                        ExplicitTarget = target;
@@ -125,7 +126,7 @@ namespace Mono.CSharp {
 
                public Attribute Clone ()
                {
-                       Attribute a = new Attribute (ExplicitTarget, LeftExpr, Identifier, null, loc, nameEscaped);
+                       Attribute a = new Attribute (ExplicitTarget, expression, null, loc, nameEscaped);
                        a.PosArguments = PosArguments;
                        a.NamedArguments = NamedArguments;
                        return a;
@@ -138,55 +139,58 @@ namespace Mono.CSharp {
 
                public static void Reset ()
                {
-                       usage_attr_cache = new PtrHashtable ();
-                       att_cache = new PtrHashtable ();
+                       usage_attr_cache = new Dictionary<Type, AttributeUsageAttribute> (ReferenceEquality<Type>.Default);
+                       att_cache = new Dictionary<Type, CustomAttributeBuilder> (ReferenceEquality<Type>.Default);
                }
 
-               public virtual void AttachTo (Attributable owner)
+               //
+               // When the same attribute is attached to multiple fiels
+               // we use @target field as a list of targets. The attribute
+               // has to be resolved only once but emitted for each target.
+               //
+               public virtual void AttachTo (Attributable target, IMemberContext context)
                {
-                       if (this.owners == null) {
-                               this.owners = new Attributable[1] { owner };
+                       if (this.targets == null) {
+                               this.targets = new Attributable[] { target };
+                               this.context = context;
                                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;
+                       // Resize target array
+                       Attributable[] new_array = new Attributable [this.targets.Length + 1];
+                       targets.CopyTo (new_array, 0);
+                       new_array [targets.Length] = target;
+                       this.targets = new_array;
+
+                       // No need to update context, different targets cannot have
+                       // different contexts, it's enough to remove same attributes
+                       // from secondary members.
+
+                       target.OptAttributes = null;
                }
 
-               void Error_InvalidNamedArgument (string name)
+               static void Error_InvalidNamedArgument (ResolveContext rc, NamedArgument name)
                {
-                       Report.Error (617, Location, "`{0}' is not a valid named attribute argument. Named attribute arguments " +
+                       rc.Report.Error (617, name.Location, "`{0}' is not a valid named attribute argument. Named attribute arguments " +
                                      "must be fields which are not readonly, static, const or read-write properties which are " +
                                      "public and not static",
-                             name);
+                             name.Name);
                }
 
-               void Error_InvalidNamedAgrumentType (string name)
+               static void Error_InvalidNamedArgumentType (ResolveContext rc, NamedArgument name)
                {
-                       Report.Error (655, Location, "`{0}' is not a valid named attribute argument because it is not a valid " +
-                                     "attribute parameter type", name);
+                       rc.Report.Error (655, name.Location,
+                               "`{0}' is not a valid named attribute argument because it is not a valid attribute parameter type",
+                               name.Name);
                }
 
-               public static void Error_AttributeArgumentNotValid (Location loc)
+               public static void Error_AttributeArgumentNotValid (ResolveContext rc, Location loc)
                {
-                       Report.Error (182, loc,
+                       rc.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");
@@ -197,6 +201,11 @@ namespace Mono.CSharp {
                        Report.Error (1112, Location, "Do not use `{0}' directly. Use parameter modifier `this' instead", GetSignatureForError ());
                }
 
+               public void Error_MisusedDynamicAttribute ()
+               {
+                       Report.Error (1970, loc, "Do not use `{0}' directly. Use `dynamic' keyword 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.
@@ -214,33 +223,25 @@ namespace Mono.CSharp {
 
                Attributable Owner {
                        get {
-                               return owners [0];
+                               return targets [0];
                        }
                }
 
-               protected virtual TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec, bool silent)
+               protected virtual TypeExpr ResolveAsTypeTerminal (Expression expr, IMemberContext ec)
                {
-                       return expr.ResolveAsTypeTerminal (ec, silent);
+                       return expr.ResolveAsTypeTerminal (ec, false);
                }
 
-               Type ResolvePossibleAttributeType (string name, bool silent, ref bool is_attr)
+               Type ResolvePossibleAttributeType (ATypeNameExpression expr, ref bool is_attr)
                {
-                       IResolveContext rc = Owner.ResolveContext;
-
-                       TypeExpr te;
-                       if (LeftExpr == null) {
-                               te = ResolveAsTypeTerminal (new SimpleName (name, Location), rc, silent);
-                       } else {
-                               te = ResolveAsTypeTerminal (new MemberAccess (LeftExpr, name), rc, silent);
-                       }
-
+                       TypeExpr te = ResolveAsTypeTerminal (expr, context);
                        if (te == null)
                                return null;
 
                        Type t = te.Type;
                        if (TypeManager.IsSubclassOf (t, TypeManager.attribute_type)) {
                                is_attr = true;
-                       } else if (!silent) {
+                       } else {
                                Report.SymbolRelatedToPreviousError (t);
                                Report.Error (616, Location, "`{0}': is not an attribute class", TypeManager.CSharpName (t));
                        }
@@ -252,16 +253,34 @@ namespace Mono.CSharp {
                /// </summary>
                void ResolveAttributeType ()
                {
-                       bool t1_is_attr = false;
-                       Type t1 = ResolvePossibleAttributeType (Identifier, true, ref t1_is_attr);
+                       SessionReportPrinter resolve_printer = new SessionReportPrinter ();
+                       ReportPrinter prev_recorder = context.Compiler.Report.SetPrinter (resolve_printer);
 
+                       bool t1_is_attr = false;
                        bool t2_is_attr = false;
-                       Type t2 = nameEscaped ? null :
-                               ResolvePossibleAttributeType (Identifier + "Attribute", true, ref t2_is_attr);
+                       Type t1, t2;
+                       ATypeNameExpression expanded = null;
+
+                       try {
+                               t1 = ResolvePossibleAttributeType (expression, ref t1_is_attr);
+
+                               if (nameEscaped) {
+                                       t2 = null;
+                               } else {
+                                       expanded = (ATypeNameExpression) expression.Clone (null);
+                                       expanded.Name += "Attribute";
+
+                                       t2 = ResolvePossibleAttributeType (expanded, ref t2_is_attr);
+                               }
+
+                               resolve_printer.EndSession ();
+                       } finally {
+                               context.Compiler.Report.SetPrinter (prev_recorder);
+                       }
 
                        if (t1_is_attr && t2_is_attr) {
-                               Report.Error (1614, Location, "`{0}' is ambiguous between `{0}' and `{0}Attribute'. " +
-                                             "Use either `@{0}' or `{0}Attribute'", GetSignatureForError ());
+                               Report.Error (1614, Location, "`{0}' is ambiguous between `{1}' and `{2}'. Use either `@{0}' or `{0}Attribute'",
+                                       GetSignatureForError (), expression.GetSignatureForError (), expanded.GetSignatureForError ());
                                resolve_error = true;
                                return;
                        }
@@ -276,13 +295,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (t1 == null && t2 == null)
-                               ResolvePossibleAttributeType (Identifier, false, ref t1_is_attr);
-                       if (t1 != null)
-                               ResolvePossibleAttributeType (Identifier, false, ref t1_is_attr);
-                       if (t2 != null)
-                               ResolvePossibleAttributeType (Identifier + "Attribute", false, ref t2_is_attr);
-
+                       resolve_printer.Merge (prev_recorder);
                        resolve_error = true;
                }
 
@@ -298,13 +311,13 @@ namespace Mono.CSharp {
                        if (Type != null)
                                return TypeManager.CSharpName (Type);
 
-                       return LeftExpr == null ? Identifier : LeftExpr.GetSignatureForError () + "." + Identifier;
+                       return expression.GetSignatureForError ();
                }
 
                public bool HasSecurityAttribute {
                        get {
-                               return TypeManager.security_attr_type != null &&
-                               TypeManager.IsSubclassOf (type, TypeManager.security_attr_type);
+                               PredefinedAttribute pa = PredefinedAttributes.Get.Security;
+                               return pa.IsDefined && TypeManager.IsSubclassOf (type, pa.Type);
                        }
                }
 
@@ -325,29 +338,37 @@ namespace Mono.CSharp {
                                t == TypeManager.type_type;
                }
 
-               [Conditional ("GMCS_SOURCE")]
-               void ApplyModuleCharSet ()
+               // TODO: Don't use this ambiguous value
+               public string Name {
+                       get { return expression.Name; }
+               }
+
+               void ApplyModuleCharSet (ResolveContext rc)
                {
-                       if (Type != TypeManager.dllimport_type)
+                       if (Type != PredefinedAttributes.Get.DllImport)
                                return;
 
-                       if (!CodeGen.Module.HasDefaultCharSet)
+                       if (!RootContext.ToplevelTypes.HasDefaultCharSet)
                                return;
 
                        const string CharSetEnumMember = "CharSet";
                        if (NamedArguments == null) {
-                               NamedArguments = new ArrayList (1);
+                               NamedArguments = new Arguments (1);
                        } else {
-                               foreach (DictionaryEntry de in NamedArguments) {
-                                       if ((string)de.Key == CharSetEnumMember)
+                               foreach (NamedArgument a in NamedArguments) {
+                                       if (a.Name == CharSetEnumMember)
                                                return;
                                }
                        }
                        
-                       NamedArguments.Add (new DictionaryEntry (CharSetEnumMember,
-                               new Argument (Constant.CreateConstant (typeof (CharSet), CodeGen.Module.DefaultCharSet, Location))));
+                       NamedArguments.Add (new NamedArgument (CharSetEnumMember, loc,
+                               Constant.CreateConstant (rc, typeof (CharSet), RootContext.ToplevelTypes.DefaultCharSet, Location)));
                }
 
+               public Report Report {
+                       get { return context.Compiler.Report; }
+               }
+
                public CustomAttributeBuilder Resolve ()
                {
                        if (resolve_error)
@@ -368,27 +389,19 @@ namespace Mono.CSharp {
 
                        ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (Type);
                        if (obsolete_attr != null) {
-                               AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location);
+                               AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location, Report);
                        }
 
+                       CustomAttributeBuilder cb;
                        if (PosArguments == null && NamedArguments == null) {
-                               object o = att_cache [Type];
-                               if (o != null) {
+                               if (att_cache.TryGetValue (Type, out cb)) {
                                        resolve_error = false;
-                                       return (CustomAttributeBuilder)o;
+                                       return cb;
                                }
                        }
 
-                       Attributable owner = Owner;
-                       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);
+                       ResolveContext rc = new ResolveContext (context, ResolveContext.Options.ConstantScope);
+                       var ctor = ResolveConstructor (rc);
                        if (ctor == null) {
                                if (Type is TypeBuilder && 
                                    TypeManager.LookupDeclSpace (Type).MemberCache == null)
@@ -398,16 +411,16 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       ApplyModuleCharSet ();
+                       ApplyModuleCharSet (rc);
 
-                       CustomAttributeBuilder cb;
                        try {
+                               var ctor_meta = (ConstructorInfo) ctor.MetaInfo;
                                // SRE does not allow private ctor but we want to report all source code errors
-                               if (ctor.IsPrivate)
+                               if (ctor.MetaInfo.IsPrivate)
                                        return null;
 
                                if (NamedArguments == null) {
-                                       cb = new CustomAttributeBuilder (ctor, pos_values);
+                                       cb = new CustomAttributeBuilder (ctor_meta, pos_values);
 
                                        if (pos_values.Length == 0)
                                                att_cache.Add (Type, cb);
@@ -416,11 +429,11 @@ namespace Mono.CSharp {
                                        return cb;
                                }
 
-                               if (!ResolveNamedArguments (ec)) {
+                               if (!ResolveNamedArguments (rc)) {
                                        return null;
                                }
 
-                               cb = new CustomAttributeBuilder (ctor, pos_values,
+                               cb = new CustomAttributeBuilder (ctor_meta, pos_values,
                                                prop_info_arr, prop_values_arr,
                                                field_info_arr, field_values_arr);
 
@@ -428,62 +441,47 @@ namespace Mono.CSharp {
                                return cb;
                        }
                        catch (Exception) {
-                               Error_AttributeArgumentNotValid (Location);
+                               Error_AttributeArgumentNotValid (rc, Location);
                                return null;
                        }
                }
 
-               protected virtual ConstructorInfo ResolveConstructor (EmitContext ec)
+               protected virtual MethodSpec ResolveConstructor (ResolveContext ec)
                {
                        if (PosArguments != null) {
-                               for (int i = 0; i < PosArguments.Count; i++) {
-                                       Argument a = (Argument) PosArguments [i];
-
-                                       if (!a.Resolve (ec, Location))
-                                               return null;
+                               bool dynamic;
+                               PosArguments.Resolve (ec, out dynamic);
+                               if (dynamic) {
+                                       Error_AttributeArgumentNotValid (ec, loc);
+                                       return null;
                                }
                        }
-                       
-                       MethodGroupExpr mg = MemberLookupFinal (ec, ec.ContainerType,
-                               Type, ".ctor", MemberTypes.Constructor,
+
+                       MethodGroupExpr mg = MemberLookupFinal (ec, ec.CurrentType,
+                               Type, ConstructorInfo.ConstructorName, MemberTypes.Constructor,
                                BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
                                Location) as MethodGroupExpr;
 
                        if (mg == null)
-                               return null;
+                               throw new NotImplementedException ();
 
                        mg = mg.OverloadResolve (ec, ref 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) {
-                               AttributeTester.Report_ObsoleteMessage (oa, mg.GetSignatureForError (), mg.Location);
-                       }
-
+                       var constructor = (MethodSpec) mg;
                        if (PosArguments == null) {
                                pos_values = EmptyObject;
                                return constructor;
                        }
 
-                       AParametersCollection pd = TypeManager.GetParameterData (constructor);
-
-                       int pos_arg_count = PosArguments.Count;
-                       pos_values = new object [pos_arg_count];
-                       for (int j = 0; j < pos_arg_count; ++j) {
-                               Argument a = (Argument) PosArguments [j];
-
-                               if (!a.Expr.GetAttributableValue (ec, a.Type, out pos_values [j]))
-                                       return null;
-                       }
+                       if (!PosArguments.GetAttributableValue (ec, out pos_values))
+                               return null;
 
                        // Here we do the checks which should be done by corlib or by runtime.
                        // However Zoltan doesn't like it and every Mono compiler has to do it again.
-                       
-                       if (Type == TypeManager.guid_attr_type) {
+                       PredefinedAttributes pa = PredefinedAttributes.Get;
+                       if (Type == pa.Guid) {
                                try {
                                        new Guid ((string)pos_values [0]);
                                }
@@ -493,22 +491,22 @@ 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");
+                       if (Type == pa.AttributeUsage && (int)pos_values [0] == 0) {
+                               ec.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 (Type == pa.IndexerName || Type == pa.Conditional) {
                                string v = pos_values [0] as string;
                                if (!Tokenizer.IsValidIdentifier (v) || Tokenizer.IsKeyword (v)) {
-                                       Report.Error (633, ((Argument)PosArguments[0]).Expr.Location,
+                                       ec.Report.Error (633, 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.Types [0] == TypeManager.short_type &&
+                       if (Type == pa.MethodImpl && pos_values.Length == 1 &&
+                               constructor.Parameters.Types [0] == TypeManager.short_type &&
                                !System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0].ToString ())) {
                                Error_AttributeEmitError ("Incorrect argument value.");
                                return null;
@@ -517,60 +515,53 @@ namespace Mono.CSharp {
                        return constructor;
                }
 
-               protected virtual bool ResolveNamedArguments (EmitContext ec)
+               protected virtual bool ResolveNamedArguments (ResolveContext ec)
                {
                        int named_arg_count = NamedArguments.Count;
 
-                       ArrayList field_infos = new ArrayList (named_arg_count);
-                       ArrayList prop_infos  = new ArrayList (named_arg_count);
-                       ArrayList field_values = new ArrayList (named_arg_count);
-                       ArrayList prop_values = new ArrayList (named_arg_count);
+                       var field_infos = new List<FieldInfo> (named_arg_count);
+                       var prop_infos  = new List<PropertyInfo> (named_arg_count);
+                       var field_values = new List<object> (named_arg_count);
+                       var prop_values = new List<object> (named_arg_count);
 
-                       ArrayList seen_names = new ArrayList(named_arg_count);
+                       var seen_names = new List<string> (named_arg_count);
                        
-                       foreach (DictionaryEntry de in NamedArguments) {
-                               string member_name = (string) de.Key;
-
-                               if (seen_names.Contains(member_name)) {
-                                       Report.Error(643, Location, "'{0}' duplicate named attribute argument", member_name);
-                                       return false;
-                               }                               
-                               seen_names.Add(member_name);
+                       foreach (NamedArgument a in NamedArguments) {
+                               string name = a.Name;
+                               if (seen_names.Contains (name)) {
+                                       ec.Report.Error (643, a.Location, "Duplicate named attribute `{0}' argument", name);
+                                       continue;
+                               }                       
+       
+                               seen_names.Add (name);
 
-                               Argument a = (Argument) de.Value;
-                               if (!a.Resolve (ec, Location))
-                                       return false;
+                               a.Resolve (ec);
 
-                               Expression member = Expression.MemberLookup (
-                                       ec.ContainerType, Type, member_name,
-                                       MemberTypes.Field | MemberTypes.Property,
-                                       BindingFlags.Public | BindingFlags.Instance,
+                               Expression member = Expression.MemberLookup (ec.Compiler,
+                                       ec.CurrentType, Type, name,
+                                       MemberTypes.All,
+                                       BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static,
                                        Location);
 
                                if (member == null) {
-                                       member = Expression.MemberLookup (ec.ContainerType, Type, member_name,
-                                               MemberTypes.Field | MemberTypes.Property, BindingFlags.NonPublic | BindingFlags.Instance,
+                                       member = Expression.MemberLookup (ec.Compiler, ec.CurrentType, Type, name,
+                                               MemberTypes.All, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
                                                Location);
 
                                        if (member != null) {
-                                               Report.SymbolRelatedToPreviousError (member.Type);
-                                               Expression.ErrorIsInaccesible (Location, member.GetSignatureForError ());
+                                               ec.Report.SymbolRelatedToPreviousError (member.Type);
+                                               Expression.ErrorIsInaccesible (Location, member.GetSignatureForError (), ec.Report);
                                                return false;
                                        }
                                }
 
                                if (member == null){
-                                       Expression.Error_TypeDoesNotContainDefinition (Location, Type, member_name);
+                                       Expression.Error_TypeDoesNotContainDefinition (ec, Location, Type, name);
                                        return false;
                                }
                                
                                if (!(member is PropertyExpr || member is FieldExpr)) {
-                                       Error_InvalidNamedArgument (member_name);
-                                       return false;
-                               }
-
-                               if (a.Expr is TypeParameterExpr){
-                                       Error_TypeParameterInAttribute (Location);
+                                       Error_InvalidNamedArgument (ec, a);
                                        return false;
                                }
 
@@ -579,15 +570,15 @@ namespace Mono.CSharp {
                                if (member is PropertyExpr) {
                                        PropertyInfo pi = ((PropertyExpr) member).PropertyInfo;
 
-                                       if (!pi.CanWrite || !pi.CanRead) {
-                                               Report.SymbolRelatedToPreviousError (pi);
-                                               Error_InvalidNamedArgument (member_name);
+                                       if (!pi.CanWrite || !pi.CanRead || pi.GetGetMethod ().IsStatic) {
+                                               ec.Report.SymbolRelatedToPreviousError (pi);
+                                               Error_InvalidNamedArgument (ec, a);
                                                return false;
                                        }
 
                                        if (!IsValidArgumentType (member.Type)) {
-                                               Report.SymbolRelatedToPreviousError (pi);
-                                               Error_InvalidNamedAgrumentType (member_name);
+                                               ec.Report.SymbolRelatedToPreviousError (pi);
+                                               Error_InvalidNamedArgumentType (ec, a);
                                                return false;
                                        }
 
@@ -605,16 +596,16 @@ namespace Mono.CSharp {
                                        prop_infos.Add (pi);
                                        
                                } else {
-                                       FieldInfo fi = ((FieldExpr) member).FieldInfo;
+                                       var fi = ((FieldExpr) member).Spec;
 
-                                       if (fi.IsInitOnly) {
-                                               Error_InvalidNamedArgument (member_name);
+                                       if (fi.IsReadOnly || fi.IsStatic) {
+                                               Error_InvalidNamedArgument (ec, a);
                                                return false;
                                        }
 
                                        if (!IsValidArgumentType (member.Type)) {
-                                               Report.SymbolRelatedToPreviousError (fi);
-                                               Error_InvalidNamedAgrumentType (member_name);
+                                               ec.Report.SymbolRelatedToPreviousError (fi.MetaInfo);
+                                               Error_InvalidNamedArgumentType (ec, a);
                                                return false;
                                        }
 
@@ -622,18 +613,18 @@ namespace Mono.CSharp {
                                        if (!a.Expr.GetAttributableValue (ec, member.Type, out value))
                                                return false;
 
-                                       FieldBase fb = TypeManager.GetField (fi);
+                                       FieldBase fb = TypeManager.GetField (fi.MetaInfo);
                                        if (fb != null)
                                                obsolete_attr = fb.GetObsoleteAttribute ();
                                        else
-                                               obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (fi);
+                                               obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (fi.MetaInfo);
 
-                                       field_values.Add (value);                                       
-                                       field_infos.Add (fi);
+                                       field_values.Add (value);
+                                       field_infos.Add (fi.MetaInfo);
                                }
 
-                               if (obsolete_attr != null && !Owner.ResolveContext.IsInObsoleteScope)
-                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location);
+                               if (obsolete_attr != null && !context.IsObsolete)
+                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location, Report);
                        }
 
                        prop_info_arr = new PropertyInfo [prop_infos.Count];
@@ -700,10 +691,9 @@ namespace Mono.CSharp {
                        if ((targets & AttributeTargets.ReturnValue) != 0)
                                sb.Append ("return, ");
 
-#if NET_2_0
                        if ((targets & AttributeTargets.GenericParameter) != 0)
                                sb.Append ("type parameter, ");
-#endif                 
+
                        return sb.Remove (sb.Length - 2, 2).ToString ();
                }
 
@@ -712,14 +702,18 @@ namespace Mono.CSharp {
                /// </summary>
                static AttributeUsageAttribute GetAttributeUsage (Type type)
                {
-                       AttributeUsageAttribute ua = usage_attr_cache [type] as AttributeUsageAttribute;
-                       if (ua != null)
+                       AttributeUsageAttribute ua;
+                       if (usage_attr_cache.TryGetValue (type, out ua))
                                return ua;
 
                        Class attr_class = TypeManager.LookupClass (type);
+                       PredefinedAttribute pa = PredefinedAttributes.Get.AttributeUsage;
 
                        if (attr_class == null) {
-                               object[] usage_attr = type.GetCustomAttributes (TypeManager.attribute_usage_type, true);
+                               if (!pa.IsDefined)
+                                       return new AttributeUsageAttribute (0);
+
+                               object[] usage_attr = type.GetCustomAttributes (pa.Type, true);
                                ua = (AttributeUsageAttribute)usage_attr [0];
                                usage_attr_cache.Add (type, ua);
                                return ua;
@@ -727,7 +721,7 @@ namespace Mono.CSharp {
 
                        Attribute a = null;
                        if (attr_class.OptAttributes != null)
-                               a = attr_class.OptAttributes.Search (TypeManager.attribute_usage_type);
+                               a = attr_class.OptAttributes.Search (pa);
 
                        if (a == null) {
                                if (attr_class.TypeBuilder.BaseType != TypeManager.attribute_type)
@@ -857,13 +851,13 @@ namespace Mono.CSharp {
                        }
 
                        // TODO: we can skip the first item
-                       if (((IList) valid_targets).Contains (ExplicitTarget)) {
+                       if (Array.Exists (valid_targets, i => i == 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);
                        }
@@ -922,7 +916,7 @@ namespace Mono.CSharp {
                /// Creates instance of SecurityAttribute class and add result of CreatePermission method to permission table.
                /// </summary>
                /// <returns></returns>
-               public void ExtractSecurityPermissionSet (ListDictionary permissions)
+               public void ExtractSecurityPermissionSet (Dictionary<SecurityAction, PermissionSet> permissions)
                {
                        Type orig_assembly_type = null;
 
@@ -973,7 +967,7 @@ namespace Mono.CSharp {
                                                // TODO: pi can be null
                                                PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name);
 
-                                               object old_instance = pi.PropertyType.IsEnum ?
+                                               object old_instance = TypeManager.IsEnumType (pi.PropertyType) ?
                                                        System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) :
                                                        prop_values_arr [i];
 
@@ -989,20 +983,20 @@ 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;
                                }
                        }
 
-                       PermissionSet ps = (PermissionSet)permissions [action];
-                       if (ps == null) {
+                       PermissionSet ps;
+                       if (!permissions.TryGetValue (action, out ps)) {
                                if (sa is PermissionSetAttribute)
                                        ps = new PermissionSet (sa.Unrestricted ? PermissionState.Unrestricted : PermissionState.None);
                                else
@@ -1034,7 +1028,7 @@ namespace Mono.CSharp {
                // 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
+#if false
                public UnmanagedMarshal GetMarshal (Attributable attr)
                {
                        UnmanagedType UnmanagedType;
@@ -1152,7 +1146,7 @@ namespace Mono.CSharp {
 
                public bool IsInternalMethodImplAttribute {
                        get {
-                               if (Type != TypeManager.methodimpl_attr_type)
+                               if (Type != PredefinedAttributes.Get.MethodImpl)
                                        return false;
 
                                MethodImplOptions options;
@@ -1189,13 +1183,13 @@ namespace Mono.CSharp {
 
                public override int GetHashCode ()
                {
-                       return base.GetHashCode ();
+                       return type.GetHashCode () ^ Target.GetHashCode ();
                }
 
                /// <summary>
                /// Emit attribute for Attributable symbol
                /// </summary>
-               public void Emit (ListDictionary allEmitted)
+               public void Emit (Dictionary<Attribute, List<Attribute>> allEmitted)
                {
                        CustomAttributeBuilder cb = Resolve ();
                        if (cb == null)
@@ -1209,20 +1203,21 @@ namespace Mono.CSharp {
                                return;
                        }
 
+                       var predefined = PredefinedAttributes.Get;
+
                        try {
-                               foreach (Attributable owner in owners)
-                                       owner.ApplyAttributeBuilder (this, cb);
-                       }
-                       catch (Exception e) {
+                               foreach (Attributable target in targets)
+                                       target.ApplyAttributeBuilder (this, cb, predefined);
+                       } catch (Exception e) {
                                Error_AttributeEmitError (e.Message);
                                return;
                        }
 
                        if (!usage_attr.AllowMultiple && allEmitted != null) {
-                               if (allEmitted.Contains (this)) {
-                                       ArrayList a = allEmitted [this] as ArrayList;
+                               if (allEmitted.ContainsKey (this)) {
+                                       var a = allEmitted [this];
                                        if (a == null) {
-                                               a = new ArrayList (2);
+                                               a = new List<Attribute> (2);
                                                allEmitted [this] = a;
                                        }
                                        a.Add (this);
@@ -1236,34 +1231,13 @@ namespace Mono.CSharp {
 
                        // Here we are testing attribute arguments for array usage (error 3016)
                        if (Owner.IsClsComplianceRequired ()) {
-                               if (PosArguments != null) {
-                                       foreach (Argument arg in PosArguments) { 
-                                               // Type is undefined (was error 246)
-                                               if (arg.Type == null)
-                                                       return;
-
-                                               if (arg.Type.IsArray) {
-                                                       Report.Warning (3016, 1, Location, "Arrays as attribute arguments are not CLS-compliant");
-                                                       return;
-                                               }
-                                       }
-                               }
+                               if (PosArguments != null)
+                                       PosArguments.CheckArrayAsAttribute (context.Compiler);
                        
                                if (NamedArguments == null)
                                        return;
-                       
-                               foreach (DictionaryEntry de in NamedArguments) {
-                                       Argument arg  = (Argument) de.Value;
 
-                                       // Type is undefined (was error 246)
-                                       if (arg.Type == null)
-                                               return;
-
-                                       if (arg.Type.IsArray) {
-                                               Report.Warning (3016, 1, Location, "Arrays as attribute arguments are not CLS-compliant");
-                                               return;
-                                       }
-                               }
+                               NamedArguments.CheckArrayAsAttribute (context.Compiler);
                        }
                }
 
@@ -1272,7 +1246,7 @@ namespace Mono.CSharp {
                        if (PosArguments == null || PosArguments.Count < 1)
                                return null;
 
-                       return ((Argument) PosArguments [0]).Expr;
+                       return PosArguments [0].Expr;
                }
 
                public string GetString () 
@@ -1299,12 +1273,12 @@ namespace Mono.CSharp {
                        return e.TypeArgument;
                }
 
-               public override Expression CreateExpressionTree (EmitContext ec)
+               public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        throw new NotSupportedException ("ET");
                }
 
-               public override Expression DoResolve (EmitContext ec)
+               protected override Expression DoResolve (ResolveContext ec)
                {
                        throw new NotImplementedException ();
                }
@@ -1324,24 +1298,25 @@ namespace Mono.CSharp {
        {
                public readonly NamespaceEntry ns;
 
-               public GlobalAttribute (NamespaceEntry ns, string target, 
-                                       Expression left_expr, string identifier, object[] args, Location loc, bool nameEscaped):
-                       base (target, left_expr, identifier, args, loc, nameEscaped)
+               public GlobalAttribute (NamespaceEntry ns, string target, ATypeNameExpression expression,
+                                       Arguments[] args, Location loc, bool nameEscaped):
+                       base (target, expression, args, loc, nameEscaped)
                {
                        this.ns = ns;
-                       this.owners = new Attributable[1];
                }
                
-               public override void AttachTo (Attributable owner)
+               public override void AttachTo (Attributable target, IMemberContext context)
                {
                        if (ExplicitTarget == "assembly") {
-                               owners [0] = CodeGen.Assembly;
+                               base.AttachTo (CodeGen.Assembly, context);
                                return;
                        }
+
                        if (ExplicitTarget == "module") {
-                               owners [0] = CodeGen.Module;
+                               base.AttachTo (RootContext.ToplevelTypes, context);
                                return;
                        }
+
                        throw new NotImplementedException ("Unknown global explicit target " + ExplicitTarget);
                }
 
@@ -1370,18 +1345,18 @@ namespace Mono.CSharp {
                        RootContext.ToplevelTypes.NamespaceEntry = null;
                }
 
-               protected override TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec, bool silent)
+               protected override TypeExpr ResolveAsTypeTerminal (Expression expr, IMemberContext ec)
                {
                        try {
                                Enter ();
-                               return base.ResolveAsTypeTerminal (expr, ec, silent);
+                               return base.ResolveAsTypeTerminal (expr, ec);
                        }
                        finally {
                                Leave ();
                        }
                }
 
-               protected override ConstructorInfo ResolveConstructor (EmitContext ec)
+               protected override MethodSpec ResolveConstructor (ResolveContext ec)
                {
                        try {
                                Enter ();
@@ -1392,7 +1367,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected override bool ResolveNamedArguments (EmitContext ec)
+               protected override bool ResolveNamedArguments (ResolveContext ec)
                {
                        try {
                                Enter ();
@@ -1405,33 +1380,33 @@ namespace Mono.CSharp {
        }
 
        public class Attributes {
-               public readonly ArrayList Attrs;
+               public readonly List<Attribute> Attrs;
 
                public Attributes (Attribute a)
                {
-                       Attrs = new ArrayList ();
+                       Attrs = new List<Attribute> ();
                        Attrs.Add (a);
                }
 
-               public Attributes (ArrayList attrs)
+               public Attributes (List<Attribute> attrs)
                {
                        Attrs = attrs;
                }
 
-               public void AddAttributes (ArrayList attrs)
+               public void AddAttributes (List<Attribute> attrs)
                {
                        Attrs.AddRange (attrs);
                }
 
-               public void AttachTo (Attributable attributable)
+               public void AttachTo (Attributable attributable, IMemberContext context)
                {
                        foreach (Attribute a in Attrs)
-                               a.AttachTo (attributable);
+                               a.AttachTo (attributable, context);
                }
 
                public Attributes Clone ()
                {
-                       ArrayList al = new ArrayList (Attrs.Count);
+                       var al = new List<Attribute> (Attrs.Count);
                        foreach (Attribute a in Attrs)
                                al.Add (a.Clone ());
 
@@ -1450,7 +1425,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public Attribute Search (Type t)
+               public Attribute Search (PredefinedAttribute t)
                {
                        foreach (Attribute a in Attrs) {
                                if (a.ResolveType () == t)
@@ -1462,26 +1437,26 @@ namespace Mono.CSharp {
                /// <summary>
                /// Returns all attributes of type 't'. Use it when attribute is AllowMultiple = true
                /// </summary>
-               public Attribute[] SearchMulti (Type t)
+               public Attribute[] SearchMulti (PredefinedAttribute t)
                {
-                       ArrayList ar = null;
+                       List<Attribute> ar = null;
 
                        foreach (Attribute a in Attrs) {
                                if (a.ResolveType () == t) {
                                        if (ar == null)
-                                               ar = new ArrayList ();
+                                               ar = new List<Attribute> (Attrs.Count);
                                        ar.Add (a);
                                }
                        }
 
-                       return ar == null ? null : ar.ToArray (typeof (Attribute)) as Attribute[];
+                       return ar == null ? null : ar.ToArray ();
                }
 
                public void Emit ()
                {
                        CheckTargets ();
 
-                       ListDictionary ld = Attrs.Count > 1 ? new ListDictionary () : null;
+                       Dictionary<Attribute, List<Attribute>> ld = Attrs.Count > 1 ? new Dictionary<Attribute, List<Attribute>> () : null;
 
                        foreach (Attribute a in Attrs)
                                a.Emit (ld);
@@ -1489,20 +1464,21 @@ namespace Mono.CSharp {
                        if (ld == null || ld.Count == 0)
                                return;
 
-                       foreach (DictionaryEntry d in ld) {
+                       foreach (var d in ld) {
                                if (d.Value == null)
                                        continue;
 
-                               foreach (Attribute collision in (ArrayList)d.Value)
-                                       Report.SymbolRelatedToPreviousError (collision.Location, "");
+                               Attribute a = d.Key;
+
+                               foreach (Attribute collision in d.Value)
+                                       a.Report.SymbolRelatedToPreviousError (collision.Location, "");
 
-                               Attribute a = (Attribute)d.Key;
-                               Report.Error (579, a.Location, "The attribute `{0}' cannot be applied multiple times",
+                               a.Report.Error (579, a.Location, "The attribute `{0}' cannot be applied multiple times",
                                        a.GetSignatureForError ());
                        }
                }
 
-               public bool Contains (Type t)
+               public bool Contains (PredefinedAttribute t)
                {
                        return Search (t) != null;
                }
@@ -1513,14 +1489,11 @@ namespace Mono.CSharp {
        /// </summary>
        sealed class AttributeTester
        {
-               static PtrHashtable analyzed_types;
-               static PtrHashtable analyzed_types_obsolete;
-               static PtrHashtable analyzed_member_obsolete;
-               static PtrHashtable analyzed_method_excluded;
-               static PtrHashtable fixed_buffer_cache;
-
-               static object TRUE = new object ();
-               static object FALSE = new object ();
+               static Dictionary<Type, bool> analyzed_types;
+               static Dictionary<Type, ObsoleteAttribute> analyzed_types_obsolete;
+               static Dictionary<MemberInfo, ObsoleteAttribute> analyzed_member_obsolete;
+               static Dictionary<MethodBase, bool> analyzed_method_excluded;
+//             static Dictionary<FieldInfo, IFixedBuffer> fixed_buffer_cache;
 
                static AttributeTester ()
                {
@@ -1533,11 +1506,11 @@ namespace Mono.CSharp {
 
                public static void Reset ()
                {
-                       analyzed_types = new PtrHashtable ();
-                       analyzed_types_obsolete = new PtrHashtable ();
-                       analyzed_member_obsolete = new PtrHashtable ();
-                       analyzed_method_excluded = new PtrHashtable ();
-                       fixed_buffer_cache = new PtrHashtable ();
+                       analyzed_types = new Dictionary<Type, bool> (ReferenceEquality<Type>.Default);
+                       analyzed_types_obsolete = new Dictionary<Type, ObsoleteAttribute> (ReferenceEquality<Type>.Default);
+                       analyzed_member_obsolete = new Dictionary<MemberInfo, ObsoleteAttribute> (ReferenceEquality<MemberInfo>.Default);
+                       analyzed_method_excluded = new Dictionary<MethodBase, bool> (ReferenceEquality<MethodBase>.Default);
+//                     fixed_buffer_cache = new Dictionary<FieldInfo, IFixedBuffer> (ReferenceEquality<FieldInfo>.Default);
                }
 
                public enum Result {
@@ -1566,8 +1539,8 @@ namespace Mono.CSharp {
                                Type bType = types_b [i];
 
                                if (aType.IsArray && bType.IsArray) {
-                                       Type a_el_type = aType.GetElementType ();
-                                       Type b_el_type = bType.GetElementType ();
+                                       Type a_el_type = TypeManager.GetElementType (aType);
+                                       Type b_el_type = TypeManager.GetElementType (bType);
                                        if (aType.GetArrayRank () != bType.GetArrayRank () && a_el_type == b_el_type) {
                                                result = Result.RefOutArrayError;
                                                continue;
@@ -1582,7 +1555,8 @@ namespace Mono.CSharp {
                                if (aType != bType)
                                        return Result.Ok;
 
-                               if (pa.FixedParameters [i].ModFlags != pb.FixedParameters [i].ModFlags)
+                               const Parameter.Modifier out_ref_mod = (Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
+                               if ((pa.FixedParameters[i].ModFlags & out_ref_mod) != (pb.FixedParameters[i].ModFlags & out_ref_mod))
                                        result = Result.RefOutArrayError;
                        }
                        return result;
@@ -1596,68 +1570,29 @@ namespace Mono.CSharp {
                        if (type == null)
                                return true;
 
-                       object type_compliance = analyzed_types[type];
-                       if (type_compliance != null)
-                               return type_compliance == TRUE;
+                       bool result;
+                       if (analyzed_types.TryGetValue (type, out result))
+                               return result;
 
                        if (type.IsPointer) {
-                               analyzed_types.Add (type, FALSE);
+                               analyzed_types.Add (type, false);
                                return false;
                        }
 
-                       bool result;
                        if (type.IsArray) {
                                result = IsClsCompliant (TypeManager.GetElementType (type));
                        } else if (TypeManager.IsNullableType (type)) {
-                               result = IsClsCompliant (TypeManager.GetTypeArguments (type) [0]);
+                               result = IsClsCompliant (TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (type) [0]));
                        } else {
                                result = AnalyzeTypeCompliance (type);
                        }
-                       analyzed_types.Add (type, result ? TRUE : FALSE);
+                       analyzed_types.Add (type, result);
                        return result;
                }        
-        
-               /// <summary>
-               /// Returns IFixedBuffer implementation if field is fixed buffer else null.
-               /// </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;
-
-                       object o = fixed_buffer_cache [fi];
-                       if (o == 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;
-                               }
-                               
-                               IFixedBuffer iff = new FixedFieldExternal (fi);
-                               fixed_buffer_cache.Add (fi, iff);
-                               return iff;
-                       }
-
-                       if (o == FALSE)
-                               return null;
-
-                       return (IFixedBuffer)o;
-               }
 
-               public static void VerifyModulesClsCompliance ()
+               public static void VerifyModulesClsCompliance (CompilerContext ctx)
                {
-                       Module[] modules = RootNamespace.Global.Modules;
+                       Module[] modules = GlobalRootNamespace.Instance.Modules;
                        if (modules == null)
                                return;
 
@@ -1665,7 +1600,7 @@ namespace Mono.CSharp {
                        for (int i = 1; i < modules.Length; ++i) {
                                Module module = modules [i];
                                if (!GetClsCompliantAttributeValue (module, null)) {
-                                       Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute " +
+                                       ctx.Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute " +
                                                      "to match the assembly", module.Name);
                                        return;
                                }
@@ -1674,7 +1609,7 @@ namespace Mono.CSharp {
 
                public static Type GetImportedIgnoreCaseClsType (string name)
                {
-                       foreach (Assembly a in RootNamespace.Global.Assemblies) {
+                       foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
                                Type t = a.GetType (name, false, true);
                                if (t == null)
                                        continue;
@@ -1687,10 +1622,11 @@ namespace Mono.CSharp {
 
                static bool GetClsCompliantAttributeValue (ICustomAttributeProvider attribute_provider, Assembly a) 
                {
-                       if (TypeManager.cls_compliant_attribute_type == null)
+                       PredefinedAttribute pa = PredefinedAttributes.Get.CLSCompliant;
+                       if (!pa.IsDefined)
                                return false;
 
-                       object[] cls_attr = attribute_provider.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
+                       object[] cls_attr = attribute_provider.GetCustomAttributes (pa.Type, false);
                        if (cls_attr.Length == 0) {
                                if (a == null)
                                        return false;
@@ -1720,27 +1656,26 @@ namespace Mono.CSharp {
                /// </summary>
                public static ObsoleteAttribute GetObsoleteAttribute (Type type)
                {
-                       object type_obsolete = analyzed_types_obsolete [type];
-                       if (type_obsolete == FALSE)
-                               return null;
+                       ObsoleteAttribute result;
+                       if (analyzed_types_obsolete.TryGetValue (type, out result))
+                               return result;
 
-                       if (type_obsolete != null)
-                               return (ObsoleteAttribute)type_obsolete;
-
-                       ObsoleteAttribute result = null;
                        if (TypeManager.HasElementType (type)) {
                                result = GetObsoleteAttribute (TypeManager.GetElementType (type));
-                       } else if (TypeManager.IsGenericParameter (type) || TypeManager.IsGenericType (type))
-                               return null;
-                       else {
+                       } else if (TypeManager.IsGenericParameter (type))
+                               result = null;  // TODO: throw new NotSupportedException ()
+                       else if (TypeManager.IsGenericType (type) && !TypeManager.IsGenericTypeDefinition (type)) {
+                               return GetObsoleteAttribute (TypeManager.DropGenericTypeArguments (type));
+                       } else {
                                DeclSpace type_ds = TypeManager.LookupDeclSpace (type);
 
                                // Type is external, we can get attribute directly
                                if (type_ds == null) {
-                                       if (TypeManager.obsolete_attribute_type != null) {
-                                               object [] attribute = type.GetCustomAttributes (TypeManager.obsolete_attribute_type, false);
+                                       PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete;
+                                       if (pa.IsDefined) {
+                                               object[] attribute = type.GetCustomAttributes (pa.Type, false);
                                                if (attribute.Length == 1)
-                                                       result = (ObsoleteAttribute) attribute [0];
+                                                       result = (ObsoleteAttribute) attribute[0];
                                        }
                                } else {
                                        result = type_ds.GetObsoleteAttribute ();
@@ -1748,7 +1683,7 @@ namespace Mono.CSharp {
                        }
 
                        // Cannot use .Add because of corlib bootstrap
-                       analyzed_types_obsolete [type] = result == null ? FALSE : result;
+                       analyzed_types_obsolete [type] = result;
                        return result;
                }
 
@@ -1781,29 +1716,26 @@ namespace Mono.CSharp {
                /// </summary>
                public static ObsoleteAttribute GetMemberObsoleteAttribute (MemberInfo mi)
                {
-                       object type_obsolete = analyzed_member_obsolete [mi];
-                       if (type_obsolete == FALSE)
-                               return null;
-
-                       if (type_obsolete != null)
-                               return (ObsoleteAttribute)type_obsolete;
+                       ObsoleteAttribute oa;
+                       if (analyzed_member_obsolete.TryGetValue (mi, out oa))
+                               return oa;
 
                        if ((mi.DeclaringType is TypeBuilder) || TypeManager.IsGenericType (mi.DeclaringType))
                                return null;
 
-                       if (TypeManager.obsolete_attribute_type == null)
+                       PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete;
+                       if (!pa.IsDefined)
                                return null;
 
-                       ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false)
-                               as ObsoleteAttribute;
-                       analyzed_member_obsolete.Add (mi, oa == null ? FALSE : oa);
+                       oa = System.Attribute.GetCustomAttribute (mi, pa.Type, false) as ObsoleteAttribute;
+                       analyzed_member_obsolete.Add (mi, oa);
                        return oa;
                }
 
                /// <summary>
                /// Common method for Obsolete error/warning reporting.
                /// </summary>
-               public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc)
+               public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc, Report Report)
                {
                        if (oa.IsError) {
                                Report.Error (619, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
@@ -1819,28 +1751,29 @@ namespace Mono.CSharp {
 
                public static bool IsConditionalMethodExcluded (MethodBase mb, Location loc)
                {
-                       object excluded = analyzed_method_excluded [mb];
-                       if (excluded != null)
-                               return excluded == TRUE ? true : false;
+                       bool excluded;
+                       if (analyzed_method_excluded.TryGetValue (mb, out excluded))
+                               return excluded;
 
-                       if (TypeManager.conditional_attribute_type == null)
+                       PredefinedAttribute pa = PredefinedAttributes.Get.Conditional;
+                       if (!pa.IsDefined)
                                return false;
 
-                       ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true)
+                       ConditionalAttribute[] attrs = mb.GetCustomAttributes (pa.Type, true)
                                as ConditionalAttribute[];
                        if (attrs.Length == 0) {
-                               analyzed_method_excluded.Add (mb, FALSE);
+                               analyzed_method_excluded.Add (mb, false);
                                return false;
                        }
 
                        foreach (ConditionalAttribute a in attrs) {
                                if (loc.CompilationUnit.IsConditionalDefined (a.ConditionString)) {
-                                       analyzed_method_excluded.Add (mb, FALSE);
+                                       analyzed_method_excluded.Add (mb, false);
                                        return false;
                                }
                        }
 
-                       analyzed_method_excluded.Add (mb, TRUE);
+                       analyzed_method_excluded.Add (mb, true);
                        return true;
                }
 
@@ -1857,8 +1790,9 @@ namespace Mono.CSharp {
 
                        // TODO: add caching
                        // TODO: merge all Type bases attribute caching to one cache to save memory
-                       if (class_decl == null && TypeManager.conditional_attribute_type != null) {
-                               object[] attributes = type.GetCustomAttributes (TypeManager.conditional_attribute_type, false);
+                       PredefinedAttribute pa = PredefinedAttributes.Get.Conditional;
+                       if (class_decl == null && pa.IsDefined) {
+                               object[] attributes = type.GetCustomAttributes (pa.Type, false);
                                foreach (ConditionalAttribute ca in attributes) {
                                        if (loc.CompilationUnit.IsConditionalDefined (ca.ConditionString))
                                                return false;
@@ -1872,24 +1806,286 @@ namespace Mono.CSharp {
                public static Type GetCoClassAttribute (Type type)
                {
                        TypeContainer tc = TypeManager.LookupInterface (type);
+                       PredefinedAttribute pa = PredefinedAttributes.Get.CoClass;
                        if (tc == null) {
-                               if (TypeManager.coclass_attr_type == null)
+                               if (!pa.IsDefined)
                                        return null;
 
-                               object[] o = type.GetCustomAttributes (TypeManager.coclass_attr_type, false);
+                               object[] o = type.GetCustomAttributes (pa.Type, false);
                                if (o.Length < 1)
                                        return null;
                                return ((System.Runtime.InteropServices.CoClassAttribute)o[0]).CoClass;
                        }
 
-                       if (tc.OptAttributes == null || TypeManager.coclass_attr_type == null)
+                       if (tc.OptAttributes == null)
                                return null;
 
-                       Attribute a = tc.OptAttributes.Search (TypeManager.coclass_attr_type);
+                       Attribute a = tc.OptAttributes.Search (pa);
                        if (a == null)
                                return null;
 
                        return a.GetCoClassAttributeValue ();
                }
        }
+
+       public class PredefinedAttributes
+       {
+               // Core types
+               public readonly PredefinedAttribute ParamArray;
+               public readonly PredefinedAttribute Out;
+
+               // Optional types
+               public readonly PredefinedAttribute Obsolete;
+               public readonly PredefinedAttribute DllImport;
+               public readonly PredefinedAttribute MethodImpl;
+               public readonly PredefinedAttribute MarshalAs;
+               public readonly PredefinedAttribute In;
+               public readonly PredefinedAttribute IndexerName;
+               public readonly PredefinedAttribute Conditional;
+               public readonly PredefinedAttribute CLSCompliant;
+               public readonly PredefinedAttribute Security;
+               public readonly PredefinedAttribute Required;
+               public readonly PredefinedAttribute Guid;
+               public readonly PredefinedAttribute AssemblyCulture;
+               public readonly PredefinedAttribute AssemblyVersion;
+               public readonly PredefinedAttribute ComImport;
+               public readonly PredefinedAttribute CoClass;
+               public readonly PredefinedAttribute AttributeUsage;
+               public readonly PredefinedAttribute DefaultParameterValue;
+               public readonly PredefinedAttribute OptionalParameter;
+
+               // New in .NET 2.0
+               public readonly PredefinedAttribute DefaultCharset;
+               public readonly PredefinedAttribute TypeForwarder;
+               public readonly PredefinedAttribute FixedBuffer;
+               public readonly PredefinedAttribute CompilerGenerated;
+               public readonly PredefinedAttribute InternalsVisibleTo;
+               public readonly PredefinedAttribute RuntimeCompatibility;
+               public readonly PredefinedAttribute DebuggerHidden;
+               public readonly PredefinedAttribute UnsafeValueType;
+
+               // New in .NET 3.5
+               public readonly PredefinedAttribute Extension;
+
+               // New in .NET 4.0
+               public readonly PredefinedAttribute Dynamic;
+               public readonly PredefinedAttribute DynamicTransform;   // DynamicAttribute with transform arguments
+
+               //
+               // Optional types which are used as types and for member lookup
+               //
+               public readonly PredefinedAttribute DefaultMember;
+               public readonly PredefinedAttribute DecimalConstant;
+               public readonly PredefinedAttribute StructLayout;
+               public readonly PredefinedAttribute FieldOffset;
+
+               public static PredefinedAttributes Get = new PredefinedAttributes ();
+
+               private PredefinedAttributes ()
+               {
+                       ParamArray = new PredefinedAttribute ("System", "ParamArrayAttribute");
+                       Out = new PredefinedAttribute ("System.Runtime.InteropServices", "OutAttribute");
+
+                       Obsolete = new PredefinedAttribute ("System", "ObsoleteAttribute");
+                       DllImport = new PredefinedAttribute ("System.Runtime.InteropServices", "DllImportAttribute");
+                       MethodImpl = new PredefinedAttribute ("System.Runtime.CompilerServices", "MethodImplAttribute");
+                       MarshalAs = new PredefinedAttribute ("System.Runtime.InteropServices", "MarshalAsAttribute");
+                       In = new PredefinedAttribute ("System.Runtime.InteropServices", "InAttribute");
+                       IndexerName = new PredefinedAttribute ("System.Runtime.CompilerServices", "IndexerNameAttribute");
+                       Conditional = new PredefinedAttribute ("System.Diagnostics", "ConditionalAttribute");
+                       CLSCompliant = new PredefinedAttribute ("System", "CLSCompliantAttribute");
+                       Security = new PredefinedAttribute ("System.Security.Permissions", "SecurityAttribute");
+                       Required = new PredefinedAttribute ("System.Runtime.CompilerServices", "RequiredAttributeAttribute");
+                       Guid = new PredefinedAttribute ("System.Runtime.InteropServices", "GuidAttribute");
+                       AssemblyCulture = new PredefinedAttribute ("System.Reflection", "AssemblyCultureAttribute");
+                       AssemblyVersion = new PredefinedAttribute ("System.Reflection", "AssemblyVersionAttribute");
+                       ComImport = new PredefinedAttribute ("System.Runtime.InteropServices", "ComImportAttribute");
+                       CoClass = new PredefinedAttribute ("System.Runtime.InteropServices", "CoClassAttribute");
+                       AttributeUsage = new PredefinedAttribute ("System", "AttributeUsageAttribute");
+                       DefaultParameterValue = new PredefinedAttribute ("System.Runtime.InteropServices", "DefaultParameterValueAttribute");
+                       OptionalParameter = new PredefinedAttribute ("System.Runtime.InteropServices", "OptionalAttribute");
+
+                       DefaultCharset = new PredefinedAttribute ("System.Runtime.InteropServices", "DefaultCharSetAttribute");
+                       TypeForwarder = new PredefinedAttribute ("System.Runtime.CompilerServices", "TypeForwardedToAttribute");
+                       FixedBuffer = new PredefinedAttribute ("System.Runtime.CompilerServices", "FixedBufferAttribute");
+                       CompilerGenerated = new PredefinedAttribute ("System.Runtime.CompilerServices", "CompilerGeneratedAttribute");
+                       InternalsVisibleTo = new PredefinedAttribute ("System.Runtime.CompilerServices", "InternalsVisibleToAttribute");
+                       RuntimeCompatibility = new PredefinedAttribute ("System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute");
+                       DebuggerHidden = new PredefinedAttribute ("System.Diagnostics", "DebuggerHiddenAttribute");
+                       UnsafeValueType = new PredefinedAttribute ("System.Runtime.CompilerServices", "UnsafeValueTypeAttribute");
+
+                       Extension = new PredefinedAttribute ("System.Runtime.CompilerServices", "ExtensionAttribute");
+
+                       Dynamic = new PredefinedAttribute ("System.Runtime.CompilerServices", "DynamicAttribute");
+                       DynamicTransform = new PredefinedAttribute ("System.Runtime.CompilerServices", "DynamicAttribute");
+
+                       DefaultMember = new PredefinedAttribute ("System.Reflection", "DefaultMemberAttribute");
+                       DecimalConstant = new PredefinedAttribute ("System.Runtime.CompilerServices", "DecimalConstantAttribute");
+                       StructLayout = new PredefinedAttribute ("System.Runtime.InteropServices", "StructLayoutAttribute");
+                       FieldOffset = new PredefinedAttribute ("System.Runtime.InteropServices", "FieldOffsetAttribute");
+               }
+
+               public void Initialize (CompilerContext ctx)
+               {
+                       foreach (FieldInfo fi in GetType ().GetFields (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) {
+                               ((PredefinedAttribute) fi.GetValue (this)).Initialize (ctx, true);
+                       }
+               }
+
+               public static void Reset ()
+               {
+                       Get = new PredefinedAttributes ();
+               }
+       }
+
+       public class PredefinedAttribute
+       {
+               Type type;
+               CustomAttributeBuilder cab;
+               ConstructorInfo ctor;
+               readonly string ns, name;
+               CompilerContext compiler;
+
+               static readonly Type NotFound = typeof (PredefinedAttribute);
+
+               public PredefinedAttribute (string ns, string name)
+               {
+                       this.ns = ns;
+                       this.name = name;
+               }
+
+               public static bool operator == (Type type, PredefinedAttribute pa)
+               {
+                       return type == pa.type;
+               }
+
+               public static bool operator != (Type type, PredefinedAttribute pa)
+               {
+                       return type != pa.type;
+               }
+
+               public ConstructorInfo Constructor {
+                       get { return ctor; }
+               }
+
+               public override int GetHashCode ()
+               {
+                       return base.GetHashCode ();
+               }
+
+               public string GetSignatureForError ()
+               {
+                       return ns + "." + name;
+               }
+
+               public override bool Equals (object obj)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void EmitAttribute (ConstructorBuilder builder)
+               {
+                       if (ResolveBuilder ())
+                               builder.SetCustomAttribute (cab);
+               }
+
+               public void EmitAttribute (MethodBuilder builder)
+               {
+                       if (ResolveBuilder ())
+                               builder.SetCustomAttribute (cab);
+               }
+
+               public void EmitAttribute (PropertyBuilder builder)
+               {
+                       if (ResolveBuilder ())
+                               builder.SetCustomAttribute (cab);
+               }
+
+               public void EmitAttribute (FieldBuilder builder)
+               {
+                       if (ResolveBuilder ())
+                               builder.SetCustomAttribute (cab);
+               }
+
+               public void EmitAttribute (TypeBuilder builder)
+               {
+                       if (ResolveBuilder ())
+                               builder.SetCustomAttribute (cab);
+               }
+
+               public void EmitAttribute (AssemblyBuilder builder)
+               {
+                       if (ResolveBuilder ())
+                               builder.SetCustomAttribute (cab);
+               }
+
+               public void EmitAttribute (ParameterBuilder builder)
+               {
+                       if (ResolveBuilder ())
+                               builder.SetCustomAttribute (cab);
+               }
+
+               public bool IsDefined {
+                       get { return type != null && type != NotFound; }
+               }
+
+               public void Initialize (CompilerContext ctx, bool canFail)
+               {
+                       this.compiler = ctx;
+                       Resolve (canFail);
+               }
+
+               public bool Resolve (bool canFail)
+               {
+                       if (type != null) {
+                               if (IsDefined)
+                                       return true;
+                               if (canFail)
+                                       return false;
+                       }
+
+                       type = TypeManager.CoreLookupType (compiler, ns, name, MemberKind.Class, !canFail);
+                       if (type == null) {
+                               type = NotFound;
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               bool ResolveBuilder ()
+               {
+                       if (cab != null)
+                               return true;
+
+                       //
+                       // Handle all parameter-less attributes as optional
+                       //
+                       if (!Resolve (true))
+                               return false;
+
+                       ConstructorInfo ci = TypeManager.GetPredefinedConstructor (type, Location.Null, Type.EmptyTypes);
+                       if (ci == null)
+                               return false;
+
+                       cab = new CustomAttributeBuilder (ci, new object[0]);
+                       return true;
+               }
+
+               public bool ResolveConstructor (Location loc, params Type[] argType)
+               {
+                       if (ctor != null)
+                               throw new InternalErrorException ("Predefined ctor redefined");
+
+                       if (!Resolve (false))
+                               return false;
+
+                       ctor = TypeManager.GetPredefinedConstructor (type, loc, argType);
+                       return ctor != null;
+               }
+
+               public Type Type {
+                       get { return type; }
+               }
+       }
 }