2010-05-27 Marek Safar <marek.safar@gmail.com>
authorMarek Safar <marek.safar@gmail.com>
Tue, 27 Apr 2010 07:59:41 +0000 (07:59 -0000)
committerMarek Safar <marek.safar@gmail.com>
Tue, 27 Apr 2010 07:59:41 +0000 (07:59 -0000)
* *.cs: Major rewrite of compiler internals to better work with
unmodified System.Reflection.Emit. Some of the key changes are
- TypeSpec replaces reflection specific System.Type.
- All Type(TypeSpec) operations are now done in compiler therefore
no dependency on SRE to inflate generic members and types or to
query unclosed types.
- MemberCache is now the only and full hierarchical topology.
- Generic constraints are implemented properly.
- And as a bonus compilation is on average 30% faster.

svn path=/trunk/mcs/; revision=156161

46 files changed:
mcs/mcs/anonymous.cs
mcs/mcs/argument.cs
mcs/mcs/assign.cs
mcs/mcs/attribute.cs
mcs/mcs/cfold.cs
mcs/mcs/class.cs
mcs/mcs/codegen.cs
mcs/mcs/complete.cs
mcs/mcs/const.cs
mcs/mcs/constant.cs
mcs/mcs/context.cs
mcs/mcs/convert.cs
mcs/mcs/cs-parser.jay
mcs/mcs/decl.cs
mcs/mcs/delegate.cs
mcs/mcs/doc.cs
mcs/mcs/driver.cs
mcs/mcs/dynamic.cs
mcs/mcs/ecore.cs
mcs/mcs/enum.cs
mcs/mcs/eval.cs
mcs/mcs/expression.cs
mcs/mcs/field.cs
mcs/mcs/flowanalysis.cs
mcs/mcs/generic.cs
mcs/mcs/import.cs
mcs/mcs/iterators.cs
mcs/mcs/lambda.cs
mcs/mcs/linq.cs
mcs/mcs/literal.cs
mcs/mcs/membercache.cs
mcs/mcs/method.cs
mcs/mcs/modifiers.cs
mcs/mcs/namespace.cs
mcs/mcs/nullable.cs
mcs/mcs/parameter.cs
mcs/mcs/pending.cs
mcs/mcs/property.cs
mcs/mcs/report.cs
mcs/mcs/rootcontext.cs
mcs/mcs/roottypes.cs
mcs/mcs/statement.cs
mcs/mcs/support.cs
mcs/mcs/symbolwriter.cs
mcs/mcs/typemanager.cs
mcs/mcs/typespec.cs

index 4245c6f67efbe623169a9a689c494ff526bd074a..36a55cc761b4510cbe67e6cd4532c11d2885e049 100644 (file)
@@ -29,22 +29,9 @@ namespace Mono.CSharp {
                {
                }
 
-               protected CompilerGeneratedClass (DeclSpace parent, GenericMethod generic, MemberName name, Modifiers mod)
-                       : this (parent, name, mod)
-               {
-                       if (generic != null) {
-                               var list = new List<Constraints> ();
-                               foreach (TypeParameter tparam in generic.TypeParameters) {
-                                       if (tparam.Constraints != null)
-                                               list.Add (tparam.Constraints.Clone ());
-                               }
-                               SetParameterInfo (list);
-                       }
-               }
-
                protected void CheckMembersDefined ()
                {
-                       if (members_defined)
+                       if (HasMembersDefined)
                                throw new InternalErrorException ("Helper class already defined!");
                }
        }
@@ -82,8 +69,8 @@ namespace Mono.CSharp {
                                        return false;
 
                                AnonymousMethodStorey parent = ((AnonymousMethodStorey) Parent).GetGenericStorey ();
-                               if (parent != null)
-                                       member_type = parent.MutateType (MemberType);
+                               if (parent != null && parent.Mutator != null)
+                                       member_type = parent.Mutator.Mutate (MemberType);
 
                                return true;
                        }
@@ -113,11 +100,6 @@ namespace Mono.CSharp {
                        {
                                // Nothing to clone
                        }
-
-                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                       {
-                               // Nothing to mutate
-                       }
                }
 
                // Unique storey ID
@@ -140,12 +122,22 @@ namespace Mono.CSharp {
                // Local variable which holds this storey instance
                public LocalTemporary Instance;
 
+               TypeParameterMutator mutator;
+
                public AnonymousMethodStorey (Block block, TypeContainer parent, MemberBase host, GenericMethod generic, string name)
-                       : base (parent, generic, MakeMemberName (host, name, generic, block.StartLocation), Modifiers.PRIVATE | Modifiers.SEALED)
+                       : base (parent, MakeMemberName (host, name, generic, block.StartLocation), Modifiers.PRIVATE | Modifiers.SEALED)
                {
                        Parent = parent;
                        OriginalSourceBlock = block;
                        ID = unique_id++;
+
+                       if (generic != null) {
+                               var hoisted_tparams = generic.CurrentTypeParameters;
+                               type_params = new TypeParameter [hoisted_tparams.Length];
+                               for (int i = 0; i < type_params.Length; ++i) {
+                                       type_params[i] = hoisted_tparams[i].CreateHoistedCopy (spec);
+                               }
+                       }
                }
 
                static MemberName MakeMemberName (MemberBase host, string name, GenericMethod generic, Location loc)
@@ -168,9 +160,18 @@ namespace Mono.CSharp {
                        Field f = AddCompilerGeneratedField ("<>f__this", type_expr);
                        f.Define ();
                        hoisted_this = new HoistedThis (this, f);
+
+                       // Inflated type instance has to be updated manually
+                       if (Instance.Type != f.Parent.CurrentType) {
+                               var inflator = new TypeParameterInflator (Instance.Type, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
+                               Instance.Type.MemberCache.AddMember (f.Spec.InflateMember (inflator));
+
+                               inflator = new TypeParameterInflator (f.Parent.CurrentType, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
+                               f.Parent.CurrentType.MemberCache.AddMember (f.Spec.InflateMember (inflator));
+                       }
                }
 
-               public Field AddCapturedVariable (string name, Type type)
+               public Field AddCapturedVariable (string name, TypeSpec type)
                {
                        CheckMembersDefined ();
 
@@ -208,7 +209,7 @@ namespace Mono.CSharp {
                                children_references.Add (block);
                }
 
-               public void AddParentStoreyReference (AnonymousMethodStorey storey)
+               public void AddParentStoreyReference (EmitContext ec, AnonymousMethodStorey storey)
                {
                        CheckMembersDefined ();
 
@@ -217,7 +218,7 @@ namespace Mono.CSharp {
                        else if (used_parent_storeys.Exists (i => i.Storey == storey))
                                return;
 
-                       TypeExpr type_expr = new TypeExpression (storey.TypeBuilder, Location);
+                       TypeExpr type_expr = storey.CreateStoreyTypeExpression (ec);
                        Field f = AddCompilerGeneratedField ("<>f__ref$" + storey.ID, type_expr);
                        used_parent_storeys.Add (new StoreyFieldPair (storey, f));
                }
@@ -256,28 +257,13 @@ namespace Mono.CSharp {
                        hoisted_params.Add (expr);
                }
 
-               public void ChangeParentStorey (AnonymousMethodStorey parentStorey)
+               TypeExpr CreateStoreyTypeExpression (EmitContext ec)
                {
-                       Parent = parentStorey;
-                       type_params = null;
-               }
-
-               //
-               // Initializes all hoisted variables
-               //
-               public void EmitStoreyInstantiation (EmitContext ec)
-               {
-                       // There can be only one instance variable for each storey type
-                       if (Instance != null)
-                               throw new InternalErrorException ();
-
-                       SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
-
                        //
                        // Create an instance of storey type
                        //
-                       Expression storey_type_expr;
-                       if (is_generic) {
+                       TypeExpr storey_type_expr;
+                       if (CurrentTypeParameters != null) {
                                //
                                // Use current method type parameter (MVAR) for top level storey only. All
                                // nested storeys use class type parameter (VAR)
@@ -288,21 +274,73 @@ namespace Mono.CSharp {
 
                                TypeArguments targs = new TypeArguments ();
 
-                               if (tparams.Length < CountTypeParameters) {
-                                       TypeParameter[] parent_tparams = ec.MemberContext.CurrentTypeDefinition.TypeParameters;
-                                       for (int i = 0; i < parent_tparams.Length; ++i)
-                                               targs.Add (new TypeParameterExpr (parent_tparams[i], Location));
-                               }
-                               
+                               //
+                               // Use type parameter name instead of resolved type parameter
+                               // specification to resolve to correctly nested type parameters
+                               //
                                for (int i = 0; i < tparams.Length; ++i)
-                                       targs.Add (new TypeParameterExpr (tparams[i], Location));
+                                       targs.Add (new SimpleName (tparams [i].Name, Location)); //  new TypeParameterExpr (tparams[i], Location));
 
-                               storey_type_expr = new GenericTypeExpr (TypeBuilder, targs, Location);
+                               storey_type_expr = new GenericTypeExpr (Definition, targs, Location);
                        } else {
-                               storey_type_expr = new TypeExpression (TypeBuilder, Location);
+                               storey_type_expr = new TypeExpression (CurrentType, Location);
+                       }
+
+                       return storey_type_expr;
+               }
+
+               public void SetNestedStoryParent (AnonymousMethodStorey parentStorey)
+               {
+                       Parent = parentStorey;
+                       type_params = null;
+                       spec.IsGeneric = false;
+                       spec.DeclaringType = parentStorey.CurrentType;
+//                     MemberName.TypeArguments = null;
+               }
+
+               protected override bool DoResolveTypeParameters ()
+               {
+                       // Although any storey can have type parameters they are all clones of method type
+                       // parameters therefore have to mutate MVAR references in any of cloned constraints
+                       if (type_params != null) {
+                               for (int i = 0; i < type_params.Length; ++i) {
+                                       var spec = type_params[i].Type;
+                                       spec.BaseType = mutator.Mutate (spec.BaseType);
+                                       if (spec.Interfaces != null) {
+                                               var mutated = new TypeSpec[spec.Interfaces.Count];
+                                               for (int ii = 0; ii < mutated.Length; ++ii) {
+                                                       mutated [ii] = mutator.Mutate (spec.Interfaces[ii]);
+                                               }
+
+                                               spec.Interfaces = mutated;
+                                       }
+
+                                       if (spec.TypeArguments != null) {
+                                               spec.TypeArguments = mutator.Mutate (spec.TypeArguments);
+                                       }
+                               }
                        }
 
-                       ResolveContext rc = new ResolveContext (this);
+                       return true;
+               }
+
+               //
+               // Initializes all hoisted variables
+               //
+               public void EmitStoreyInstantiation (EmitContext ec)
+               {
+                       // There can be only one instance variable for each storey type
+                       if (Instance != null)
+                               throw new InternalErrorException ();
+
+                       SymbolWriter.OpenCompilerGeneratedBlock (ec);
+
+                       //
+                       // Create an instance of a storey
+                       //
+                       Expression storey_type_expr = CreateStoreyTypeExpression (ec);
+
+                       ResolveContext rc = new ResolveContext (ec.MemberContext);
                        Expression e = new New (storey_type_expr, null, Location).Resolve (rc);
                        e.Emit (ec);
 
@@ -312,7 +350,7 @@ namespace Mono.CSharp {
                        EmitHoistedFieldsInitialization (ec);
 
                        SymbolWriter.DefineScopeVariable (ID, Instance.Builder);
-                       SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
+                       SymbolWriter.CloseCompilerGeneratedBlock (ec);
                }
 
                void EmitHoistedFieldsInitialization (EmitContext ec)
@@ -321,18 +359,22 @@ namespace Mono.CSharp {
                        // Initialize all storey reference fields by using local or hoisted variables
                        //
                        if (used_parent_storeys != null) {
+                               var rc = new ResolveContext (ec.MemberContext);
+
                                foreach (StoreyFieldPair sf in used_parent_storeys) {
                                        //
-                                       // Setting local field
+                                       // Get instance expression of storey field
                                        //
                                        Expression instace_expr = GetStoreyInstanceExpression (ec);
-                                       FieldExpr f_set_expr = TypeManager.IsGenericType (instace_expr.Type) ?
-                                               new FieldExpr (sf.Field, instace_expr.Type, Location) :
-                                               new FieldExpr (sf.Field, Location);
+                                       var fs = sf.Field.Spec;
+                                       if (TypeManager.IsGenericType (instace_expr.Type))
+                                               fs = MemberCache.GetMember (instace_expr.Type, fs);
+
+                                       FieldExpr f_set_expr = new FieldExpr (fs, Location);
                                        f_set_expr.InstanceExpression = instace_expr;
 
                                        SimpleAssign a = new SimpleAssign (f_set_expr, sf.Storey.GetStoreyInstanceExpression (ec));
-                                       if (a.Resolve (new ResolveContext (ec.MemberContext)) != null)
+                                       if (a.Resolve (rc) != null)
                                                a.EmitStatement (ec);
                                }
                        }
@@ -441,7 +483,7 @@ namespace Mono.CSharp {
                                        //
                                        // Access inside of same storey (S -> S)
                                        //
-                                       return new CompilerGeneratedThis (TypeBuilder, Location);
+                                       return new CompilerGeneratedThis (CurrentType, Location);
                                }
                                //
                                // External field access
@@ -453,7 +495,7 @@ namespace Mono.CSharp {
                        // Storey was cached to local field
                        //
                        FieldExpr f_ind = new FieldExpr (f, Location);
-                       f_ind.InstanceExpression = new CompilerGeneratedThis (TypeBuilder, Location);
+                       f_ind.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location);
                        return f_ind;
                }
 
@@ -470,128 +512,13 @@ namespace Mono.CSharp {
                        get { return hoisted_this; }
                }
 
-               //
-               // Mutate type dispatcher
-               //
-               public Type MutateType (Type type)
-               {
-                       if (TypeManager.IsGenericType (type))
-                               return MutateGenericType (type);
-
-                       if (TypeManager.IsGenericParameter (type))
-                               return MutateGenericArgument (type);
-
-                       if (type.IsArray)
-                               return MutateArrayType (type);
-                       return type;
-               }
-
-               //
-               // Changes method type arguments (MVAR) to storey (VAR) type arguments
-               //
-               public void MutateGenericMethod (MethodSpec ms)
-               {
-                       var method = (MethodInfo) ms.MetaInfo;
-                       Type [] t_args = TypeManager.GetGenericArguments (method);
-                       if (TypeManager.IsGenericType (method.DeclaringType)) {
-                               Type t = MutateGenericType (method.DeclaringType);
-                               if (t != method.DeclaringType) {
-                                       method = (MethodInfo) TypeManager.DropGenericMethodArguments (method);
-                                       if (TypeManager.IsBeingCompiled (method))
-                                               ms.MetaInfo = TypeBuilder.GetMethod (t, method);
-                                       else
-                                               ms.MetaInfo = MethodInfo.GetMethodFromHandle (method.MethodHandle, t.TypeHandle);
-                               }                               
-                       }
-
-                       if (t_args == null || t_args.Length == 0)
-                               return;
-
-                       for (int i = 0; i < t_args.Length; ++i)
-                               t_args [i] = MutateType (t_args [i]);
-
-                       method = (MethodInfo) ms.MetaInfo;
-                       ms.MetaInfo = method.GetGenericMethodDefinition ().MakeGenericMethod (t_args);
-               }
-
-               public void MutateConstructor (MethodSpec ms)
-               {
-                       var ctor = (ConstructorInfo) ms.MetaInfo;
-                       if (TypeManager.IsGenericType (ctor.DeclaringType)) {
-                               Type t = MutateGenericType (ctor.DeclaringType);
-                               if (t != ctor.DeclaringType) {
-                                       ctor = (ConstructorInfo) TypeManager.DropGenericMethodArguments (ctor);
-                                       if (TypeManager.IsBeingCompiled (ctor))
-                                               ms.MetaInfo = TypeBuilder.GetConstructor (t, ctor);
-                                       else
-                                               ms.MetaInfo = ConstructorInfo.GetMethodFromHandle (ctor.MethodHandle, t.TypeHandle);
-                               }
-                       }
-               }
-               
-               public void MutateField (FieldSpec fs)
-               {
-                       var field = fs.MetaInfo;
-                       if (TypeManager.IsGenericType (field.DeclaringType)) {
-                               Type t = MutateGenericType (field.DeclaringType);
-                               if (t != field.DeclaringType) {
-                                       field = TypeManager.DropGenericTypeArguments (field.DeclaringType).GetField (field.Name, TypeManager.AllMembers);
-                                       
-                                       // HACK: TypeBuilder has to be used when a type is of TypeBuilder* but there is no
-                                       // way how to find out (use type comparison when this becomes an issue)
-                                       if (t.GetType ().FullName == "System.Reflection.MonoGenericClass") {
-                                               fs.MetaInfo = TypeBuilder.GetField (t, field);
-                                       } else {
-                                               fs.MetaInfo = FieldInfo.GetFieldFromHandle (field.FieldHandle, t.TypeHandle);
-                                       }
-                               }
-                       }
-               }               
-
-               protected Type MutateArrayType (Type array)
-               {
-                       Type element = TypeManager.GetElementType (array);
-                       if (element.IsArray) {
-                               element = MutateArrayType (element);
-                       } else if (TypeManager.IsGenericParameter (element)) {
-                               element = MutateGenericArgument (element);
-                       } else if (TypeManager.IsGenericType (element)) {
-                               element = MutateGenericType (element);
-                       } else {
-                               return array;
+               public TypeParameterMutator Mutator {
+                       get {
+                               return mutator;
                        }
-
-                       int rank = array.GetArrayRank ();
-                       if (rank == 1)
-                               return element.MakeArrayType ();
-
-                       return element.MakeArrayType (rank);
-               }
-
-               protected Type MutateGenericType (Type type)
-               {
-                       Type [] t_args = TypeManager.GetTypeArguments (type);
-                       if (t_args == null || t_args.Length == 0)
-                               return type;
-
-                       for (int i = 0; i < t_args.Length; ++i)
-                               t_args [i] = MutateType (t_args [i]);
-
-                       return TypeManager.DropGenericTypeArguments (type).MakeGenericType (t_args);
-               }
-
-               //
-               // Changes method generic argument (MVAR) to type generic argument (VAR)
-               //
-               public Type MutateGenericArgument (Type type)
-               {
-                       if (CurrentTypeParameters != null) {
-                               TypeParameter tp = TypeParameter.FindTypeParameter (CurrentTypeParameters, type.Name);
-                               if (tp != null)
-                                       return tp.Type;
+                       set {
+                               mutator = value;
                        }
-
-                       return type;
                }
 
                public IList<ExplicitBlock> ReferencesFromChildrenBlock {
@@ -648,7 +575,7 @@ namespace Mono.CSharp {
                Dictionary<AnonymousExpression, FieldExpr> cached_inner_access; // TODO: Hashtable is too heavyweight
                FieldExpr cached_outer_access;
 
-               protected HoistedVariable (AnonymousMethodStorey storey, string name, Type type)
+               protected HoistedVariable (AnonymousMethodStorey storey, string name, TypeSpec type)
                        : this (storey, storey.AddCapturedVariable (name, type))
                {
                }
@@ -687,9 +614,12 @@ namespace Mono.CSharp {
                                // When setting top-level hoisted variable in generic storey
                                // change storey generic types to method generic types (VAR -> MVAR)
                                //
-                               cached_outer_access = storey.MemberName.IsGeneric ?
-                                       new FieldExpr (field, storey.Instance.Type, field.Location) :
-                                       new FieldExpr (field, field.Location);
+                               if (storey.MemberName.IsGeneric) {
+                                       var fs = MemberCache.GetMember (storey.Instance.Type, field.Spec);
+                                       cached_outer_access = new FieldExpr (fs, field.Location);
+                               } else {
+                                       cached_outer_access = new FieldExpr (field, field.Location);
+                               }
 
                                cached_outer_access.InstanceExpression = storey.GetStoreyInstanceExpression (ec);
                                return cached_outer_access;
@@ -705,10 +635,13 @@ namespace Mono.CSharp {
                        }
 
                        if (inner_access == null) {
-                               inner_access = field.Parent.MemberName.IsGeneric ?
-                                       new FieldExpr (field, field.Parent.CurrentType, field.Location) :
-                                       new FieldExpr (field, field.Location);
-                                                       
+                               if (field.Parent.MemberName.IsGeneric) {
+                                       var fs = MemberCache.GetMember (field.Parent.CurrentType, field.Spec);
+                                       inner_access = new FieldExpr (fs, field.Location);
+                               } else {
+                                       inner_access = new FieldExpr (field, field.Location);
+                               }
+
                                inner_access.InstanceExpression = storey.GetStoreyInstanceExpression (ec);
                                cached_inner_access.Add (ec.CurrentAnonymousMethod, inner_access);
                        }
@@ -861,13 +794,13 @@ namespace Mono.CSharp {
                        }
                }
 
-               Dictionary<Type, Expression> compatibles;
+               Dictionary<TypeSpec, Expression> compatibles;
                public ToplevelBlock Block;
 
                public AnonymousMethodExpression (Location loc)
                {
                        this.loc = loc;
-                       this.compatibles = new Dictionary<Type, Expression> ();
+                       this.compatibles = new Dictionary<TypeSpec, Expression> ();
                }
 
                public override string ExprClassName {
@@ -890,7 +823,7 @@ namespace Mono.CSharp {
                // Returns true if the body of lambda expression can be implicitly
                // converted to the delegate of type `delegate_type'
                //
-               public bool ImplicitStandardConversionExists (ResolveContext ec, Type delegate_type)
+               public bool ImplicitStandardConversionExists (ResolveContext ec, TypeSpec delegate_type)
                {
                        using (ec.With (ResolveContext.Options.InferReturnType, false)) {
                                using (ec.Set (ResolveContext.Options.ProbingMode)) {
@@ -899,14 +832,14 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected Type CompatibleChecks (ResolveContext ec, Type delegate_type)
+               protected TypeSpec CompatibleChecks (ResolveContext ec, TypeSpec delegate_type)
                {
-                       if (TypeManager.IsDelegateType (delegate_type))
+                       if (delegate_type.IsDelegate)
                                return delegate_type;
 
-                       if (TypeManager.DropGenericTypeArguments (delegate_type) == TypeManager.expression_type) {
-                               delegate_type = TypeManager.GetTypeArguments (delegate_type) [0];
-                               if (TypeManager.IsDelegateType (delegate_type))
+                       if (delegate_type.IsGeneric && delegate_type.GetDefinition () == TypeManager.expression_type) {
+                               delegate_type = delegate_type.TypeArguments [0];
+                               if (delegate_type.IsDelegate)
                                        return delegate_type;
 
                                ec.Report.Error (835, loc, "Cannot convert `{0}' to an expression tree of non-delegate type `{1}'",
@@ -919,7 +852,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               protected bool VerifyExplicitParameters (ResolveContext ec, Type delegate_type, AParametersCollection parameters)
+               protected bool VerifyExplicitParameters (ResolveContext ec, TypeSpec delegate_type, AParametersCollection parameters)
                {
                        if (VerifyParameterCompatibility (ec, delegate_type, parameters, ec.IsInProbingMode))
                                return true;
@@ -932,7 +865,7 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               protected bool VerifyParameterCompatibility (ResolveContext ec, Type delegate_type, AParametersCollection invoke_pd, bool ignore_errors)
+               protected bool VerifyParameterCompatibility (ResolveContext ec, TypeSpec delegate_type, AParametersCollection invoke_pd, bool ignore_errors)
                {
                        if (Parameters.Count != invoke_pd.Count) {
                                if (ignore_errors)
@@ -964,7 +897,7 @@ namespace Mono.CSharp {
                                if (has_implicit_parameters)
                                        continue;
 
-                               Type type = invoke_pd.Types [i];
+                               TypeSpec type = invoke_pd.Types [i];
                                
                                // We assume that generic parameters are always inflated
                                if (TypeManager.IsGenericParameter (type))
@@ -991,26 +924,26 @@ namespace Mono.CSharp {
                //
                // Infers type arguments based on explicit arguments
                //
-               public bool ExplicitTypeInference (ResolveContext ec, TypeInferenceContext type_inference, Type delegate_type)
+               public bool ExplicitTypeInference (ResolveContext ec, TypeInferenceContext type_inference, TypeSpec delegate_type)
                {
                        if (!HasExplicitParameters)
                                return false;
 
-                       if (!TypeManager.IsDelegateType (delegate_type)) {
-                               if (TypeManager.DropGenericTypeArguments (delegate_type) != TypeManager.expression_type)
+                       if (!delegate_type.IsDelegate) {
+                               if (delegate_type.GetDefinition () != TypeManager.expression_type)
                                        return false;
 
                                delegate_type = TypeManager.GetTypeArguments (delegate_type) [0];
-                               if (!TypeManager.IsDelegateType (delegate_type))
+                               if (!delegate_type.IsDelegate)
                                        return false;
                        }
                        
-                       AParametersCollection d_params = TypeManager.GetDelegateParameters (ec, delegate_type);
+                       AParametersCollection d_params = Delegate.GetParameters (ec.Compiler, delegate_type);
                        if (d_params.Count != Parameters.Count)
                                return false;
 
                        for (int i = 0; i < Parameters.Count; ++i) {
-                               Type itype = d_params.Types [i];
+                               TypeSpec itype = d_params.Types [i];
                                if (!TypeManager.IsGenericParameter (itype)) {
                                        if (!TypeManager.HasElementType (itype))
                                                continue;
@@ -1023,7 +956,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public Type InferReturnType (ResolveContext ec, TypeInferenceContext tic, Type delegate_type)
+               public TypeSpec InferReturnType (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type)
                {
                        AnonymousExpression am;
                        using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) {
@@ -1042,13 +975,13 @@ namespace Mono.CSharp {
                // Returns AnonymousMethod container if this anonymous method
                // expression can be implicitly converted to the delegate type `delegate_type'
                //
-               public Expression Compatible (ResolveContext ec, Type type)
+               public Expression Compatible (ResolveContext ec, TypeSpec type)
                {
                        Expression am;
                        if (compatibles.TryGetValue (type, out am))
                                return am;
 
-                       Type delegate_type = CompatibleChecks (ec, type);
+                       TypeSpec delegate_type = CompatibleChecks (ec, type);
                        if (delegate_type == null)
                                return null;
 
@@ -1057,15 +990,8 @@ namespace Mono.CSharp {
                        // needed for the anonymous method.  We create the method here.
                        //
 
-                       var invoke_mb = Delegate.GetInvokeMethod (ec.Compiler,
-                               ec.CurrentType, delegate_type);
-                       Type return_type = TypeManager.TypeToCoreType (invoke_mb.ReturnType);
-
-#if MS_COMPATIBLE
-                       Type[] g_args = delegate_type.GetGenericArguments ();
-                       if (return_type.IsGenericParameter)
-                               return_type = g_args [return_type.GenericParameterPosition];
-#endif
+                       var invoke_mb = Delegate.GetInvokeMethod (ec.Compiler, delegate_type);
+                       TypeSpec return_type = invoke_mb.ReturnType;
 
                        //
                        // Second: the return type of the delegate must be compatible with 
@@ -1123,7 +1049,7 @@ namespace Mono.CSharp {
                        return am;
                }
 
-               protected virtual Expression CreateExpressionTree (ResolveContext ec, Type delegate_type)
+               protected virtual Expression CreateExpressionTree (ResolveContext ec, TypeSpec delegate_type)
                {
                        return CreateExpressionTree (ec);
                }
@@ -1134,9 +1060,9 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               protected virtual ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, Type delegate_type)
+               protected virtual ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type)
                {
-                       AParametersCollection delegate_parameters = TypeManager.GetDelegateParameters (ec, delegate_type);
+                       var delegate_parameters = Delegate.GetParameters (ec.Compiler, delegate_type);
 
                        if (Parameters == ParametersCompiled.Undefined) {
                                //
@@ -1218,7 +1144,7 @@ namespace Mono.CSharp {
                        return ExprClassName;
                }
 
-               AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, Type return_type, Type delegate_type)
+               AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, TypeSpec return_type, TypeSpec delegate_type)
                {
                        ParametersCompiled p = ResolveParameters (ec, tic, delegate_type);
                        if (p == null)
@@ -1230,7 +1156,7 @@ namespace Mono.CSharp {
 
                }
 
-               protected virtual AnonymousMethodBody CompatibleMethodFactory (Type return_type, Type delegate_type, ParametersCompiled p, ToplevelBlock b)
+               protected virtual AnonymousMethodBody CompatibleMethodFactory (TypeSpec return_type, TypeSpec delegate_type, ParametersCompiled p, ToplevelBlock b)
                {
                        return new AnonymousMethodBody (p, b, return_type, delegate_type, loc);
                }
@@ -1281,22 +1207,24 @@ namespace Mono.CSharp {
                                return ec;
                        }
 
+                       protected override void DefineTypeParameters ()
+                       {
+                               // Type parameters were cloned
+                       }
+
                        protected override bool ResolveMemberType ()
                        {
                                if (!base.ResolveMemberType ())
                                        return false;
 
-                               if (Storey != null && Storey.IsGeneric) {
-                                       AnonymousMethodStorey gstorey = Storey.GetGenericStorey ();
-                                       if (gstorey != null) {
-                                               if (!Parameters.IsEmpty) {
-                                                       Type [] ptypes = Parameters.Types;
-                                                       for (int i = 0; i < ptypes.Length; ++i)
-                                                               ptypes [i] = gstorey.MutateType (ptypes [i]);
-                                               }
-
-                                               member_type = gstorey.MutateType (member_type);
+                               if (Storey != null && Storey.Mutator != null) {
+                                       if (!parameters.IsEmpty) {
+                                               var mutated = Storey.Mutator.Mutate (parameters.Types);
+                                               if (mutated != parameters.Types)
+                                                       parameters = ParametersCompiled.CreateFullyResolved ((Parameter[]) parameters.FixedParameters, mutated);
                                        }
+
+                                       member_type = Storey.Mutator.Mutate (member_type);
                                }
 
                                return true;
@@ -1304,17 +1232,6 @@ namespace Mono.CSharp {
 
                        public override void Emit ()
                        {
-                               //
-                               // Before emitting any code we have to change all MVAR references to VAR
-                               // when the method is of generic type and has hoisted variables
-                               //
-                               if (Storey == Parent && Storey.IsGeneric) {
-                                       AnonymousMethodStorey gstorey = Storey.GetGenericStorey ();
-                                       if (gstorey != null) {
-                                               block.MutateHoistedGenericType (gstorey);
-                                       }
-                               }
-
                                if (MethodBuilder == null) {
                                        Define ();
                                }
@@ -1330,11 +1247,11 @@ namespace Mono.CSharp {
 
                readonly ToplevelBlock block;
 
-               public Type ReturnType;
+               public TypeSpec ReturnType;
 
                object return_label;
 
-               protected AnonymousExpression (ToplevelBlock block, Type return_type, Location loc)
+               protected AnonymousExpression (ToplevelBlock block, TypeSpec return_type, Location loc)
                {
                        this.ReturnType = return_type;
                        this.block = block;
@@ -1436,7 +1353,7 @@ namespace Mono.CSharp {
                static int unique_id;
 
                public AnonymousMethodBody (ParametersCompiled parameters,
-                                       ToplevelBlock block, Type return_type, Type delegate_type,
+                                       ToplevelBlock block, TypeSpec return_type, TypeSpec delegate_type,
                                        Location loc)
                        : base (block, return_type, loc)
                {
@@ -1499,7 +1416,7 @@ namespace Mono.CSharp {
                                modifiers = Modifiers.STATIC | Modifiers.PRIVATE;
                        }
 
-                       TypeContainer parent = storey != null ? storey : ec.CurrentTypeDefinition;
+                       TypeContainer parent = storey != null ? storey : ec.CurrentTypeDefinition.Parent.PartialContainer;
 
                        MemberCore mc = ec.MemberContext as MemberCore;
                        string name = CompilerGeneratedClass.MakeName (parent != storey ? block_name : null,
@@ -1510,15 +1427,14 @@ namespace Mono.CSharp {
                        if (storey == null && mc.MemberName.TypeArguments != null) {
                                member_name = new MemberName (name, mc.MemberName.TypeArguments.Clone (), Location);
 
-                               generic_method = new GenericMethod (parent.NamespaceEntry, parent, member_name,
-                                       new TypeExpression (ReturnType, Location), parameters);
-
-                               var list = new List<Constraints> ();
-                               foreach (TypeParameter tparam in ec.CurrentTypeParameters) {
-                                       if (tparam.Constraints != null)
-                                               list.Add (tparam.Constraints.Clone ());
+                               var hoisted_tparams = ec.CurrentTypeParameters;
+                               var type_params = new TypeParameter[hoisted_tparams.Length];
+                               for (int i = 0; i < type_params.Length; ++i) {
+                                       type_params[i] = hoisted_tparams[i].CreateHoistedCopy (null);
                                }
-                               generic_method.SetParameterInfo (list);
+
+                               generic_method = new GenericMethod (parent.NamespaceEntry, parent, member_name, type_params,
+                                       new TypeExpression (ReturnType, Location), parameters);
                        } else {
                                member_name = new MemberName (name, Location);
                                generic_method = null;
@@ -1592,12 +1508,11 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       ILGenerator ig = ec.ig;
-                       Label l_initialized = ig.DefineLabel ();
+                       Label l_initialized = ec.DefineLabel ();
 
                        if (am_cache != null) {
-                               ig.Emit (OpCodes.Ldsfld, am_cache.Spec.MetaInfo);
-                               ig.Emit (OpCodes.Brtrue_S, l_initialized);
+                               ec.Emit (OpCodes.Ldsfld, am_cache.Spec);
+                               ec.Emit (OpCodes.Brtrue_S, l_initialized);
                        }
 
                        //
@@ -1605,45 +1520,41 @@ namespace Mono.CSharp {
                        //
 
                        if (is_static) {
-                               ig.Emit (OpCodes.Ldnull);
+                               ec.Emit (OpCodes.Ldnull);
                        } else if (storey != null) {
                                Expression e = storey.GetStoreyInstanceExpression (ec).Resolve (new ResolveContext (ec.MemberContext));
                                if (e != null)
                                        e.Emit (ec);
                        } else {
-                               ig.Emit (OpCodes.Ldarg_0);
+                               ec.Emit (OpCodes.Ldarg_0);
                        }
 
-                       MethodInfo delegate_method = method.MethodBuilder;
+                       var delegate_method = method.Spec;
                        if (storey != null && storey.MemberName.IsGeneric) {
-                               Type t = storey.Instance.Type;
-                               
+                               TypeSpec t = storey.Instance.Type;
+
                                //
                                // Mutate anonymous method instance type if we are in nested
                                // hoisted generic anonymous method storey
                                //
                                if (ec.CurrentAnonymousMethod != null &&
                                        ec.CurrentAnonymousMethod.Storey != null &&
-                                       ec.CurrentAnonymousMethod.Storey.IsGeneric) {
-                                       t = storey.GetGenericStorey ().MutateType (t);
+                                       ec.CurrentAnonymousMethod.Storey.Mutator != null) {
+                                       t = storey.Mutator.Mutate (t);
                                }
 
-                               delegate_method = TypeBuilder.GetMethod (t, delegate_method);
+                               ec.Emit (OpCodes.Ldftn, TypeBuilder.GetMethod (t.GetMetaInfo (), (MethodInfo) delegate_method.GetMetaInfo ()));
+                       } else {
+                               ec.Emit (OpCodes.Ldftn, delegate_method);
                        }
 
-                       ig.Emit (OpCodes.Ldftn, delegate_method);
-
                        var constructor_method = Delegate.GetConstructor (ec.MemberContext.Compiler, ec.CurrentType, type);
-#if MS_COMPATIBLE
-//            if (type.IsGenericType && type is TypeBuilder)
-//                constructor_method = TypeBuilder.GetConstructor (type, constructor_method);
-#endif
-                       ig.Emit (OpCodes.Newobj, (ConstructorInfo) constructor_method.MetaInfo);
+                       ec.Emit (OpCodes.Newobj, constructor_method);
 
                        if (am_cache != null) {
-                               ig.Emit (OpCodes.Stsfld, am_cache.Spec.MetaInfo);
-                               ig.MarkLabel (l_initialized);
-                               ig.Emit (OpCodes.Ldsfld, am_cache.Spec.MetaInfo);
+                               ec.Emit (OpCodes.Stsfld, am_cache.Spec);
+                               ec.MarkLabel (l_initialized);
+                               ec.Emit (OpCodes.Ldsfld, am_cache.Spec);
                        }
                }
 
@@ -1669,11 +1580,6 @@ namespace Mono.CSharp {
                        return TypeManager.CSharpName (type);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-               }
-
                public static void Reset ()
                {
                        unique_id = 0;
@@ -1738,7 +1644,7 @@ namespace Mono.CSharp {
 
                        Constructor c = new Constructor (a_type, name, Modifiers.PUBLIC | Modifiers.DEBUGGER_HIDDEN,
                                null, new AnonymousParameters (ctx, ctor_params), null, loc);
-                       c.Block = new ToplevelBlock (ctx, c.Parameters, loc);
+                       c.Block = new ToplevelBlock (ctx, c.ParameterInfo, loc);
 
                        // 
                        // Create fields and contructor body with field initialization
@@ -1808,12 +1714,17 @@ namespace Mono.CSharp {
                                Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("ToString", loc),
                                Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null);
 
-                       ToplevelBlock equals_block = new ToplevelBlock (Compiler, equals.Parameters, loc);
+                       ToplevelBlock equals_block = new ToplevelBlock (Compiler, equals.ParameterInfo, loc);
                        TypeExpr current_type;
-                       if (IsGeneric)
-                               current_type = new GenericTypeExpr (this, loc);
-                       else
-                               current_type = new TypeExpression (TypeBuilder, loc);
+                       if (type_params != null) {
+                               var targs = new TypeArguments ();
+                               foreach (var type_param in type_params)
+                                       targs.Add (new TypeParameterExpr (type_param, type_param.Location));
+
+                               current_type = new GenericTypeExpr (Definition, targs, loc);
+                       } else {
+                               current_type = new TypeExpression (Definition, loc);
+                       }
 
                        equals_block.AddVariable (current_type, "other", loc);
                        LocalVariableReference other_variable = new LocalVariableReference (equals_block, "other", loc);
@@ -1825,12 +1736,12 @@ namespace Mono.CSharp {
                        Expression string_concat = new StringConstant ("{", loc);
                        Expression rs_hashcode = new IntConstant (-2128831035, loc);
                        for (int i = 0; i < parameters.Count; ++i) {
-                               AnonymousTypeParameter p = (AnonymousTypeParameter) parameters [i];
-                               Field f = (Field) Fields [i];
+                               var p = parameters [i];
+                               var f = Fields [i];
 
                                MemberAccess equality_comparer = new MemberAccess (new MemberAccess (
                                        system_collections_generic, "EqualityComparer",
-                                               new TypeArguments (new SimpleName (TypeParameters [i].Name, loc)), loc),
+                                               new TypeArguments (new SimpleName (CurrentTypeParameters [i].Name, loc)), loc),
                                                "Default", loc);
 
                                Arguments arguments_equal = new Arguments (2);
index be92c409100dc1692b2f3c086912ccb66f62eebb..79dc4417ddc37496f15f188c55df4343b78fdc9f 100644 (file)
@@ -47,7 +47,7 @@ namespace Mono.CSharp
                        this.Expr = expr;
                }
 
-               public Type Type {
+               public TypeSpec Type {
                        get { return Expr.Type; }
                }
 
@@ -187,7 +187,7 @@ namespace Mono.CSharp
                        if (IsByRef) {
                                var ml = (IMemoryLocation) Expr;
                                ml.AddressOf (ec, AddressOp.Load);
-                               type = TypeManager.GetReferenceType (type);
+                               type = ReferenceContainer.MakeType (type);
                        } else {
                                Expr.Emit (ec);
                        }
@@ -254,7 +254,7 @@ namespace Mono.CSharp
 
                                var arg_type = a.Expr.Type;
 
-                               if (!TypeManager.IsDynamicType (arg_type)) {
+                               if (arg_type != InternalType.Dynamic) {
                                        MethodGroupExpr mg = a.Expr as MethodGroupExpr;
                                        if (mg != null) {
                                                rc.Report.Error (1976, a.Expr.Location,
@@ -366,7 +366,7 @@ namespace Mono.CSharp
                        foreach (Argument a in args) {
                                a.Emit (ec);
                                if (dup_args) {
-                                       ec.ig.Emit (OpCodes.Dup);
+                                       ec.Emit (OpCodes.Dup);
                                        (temps [i++] = new LocalTemporary (a.Type)).Store (ec);
                                }
                        }
@@ -393,7 +393,7 @@ namespace Mono.CSharp
                public bool HasDynamic {
                        get {
                                foreach (Argument a in args) {
-                                       if (TypeManager.IsDynamicType (a.Type))
+                                       if (a.Type == InternalType.Dynamic)
                                                return true;
                                }
                                
@@ -442,16 +442,10 @@ namespace Mono.CSharp
                        dynamic = false;
                        foreach (Argument a in args) {
                                a.Resolve (ec);
-                               dynamic |= TypeManager.IsDynamicType (a.Type);
+                               dynamic |= a.Type == InternalType.Dynamic;
                        }
                }
 
-               public void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       foreach (Argument a in args)
-                               a.Expr.MutateHoistedGenericType (storey);
-               }
-
                public void RemoveAt (int index)
                {
                        args.RemoveAt (index);
index 2022af1d14ef5f1fc5b63934251b7b76273a23bf..befc203eda07436a95ca558573f261297f1a9c38 100644 (file)
@@ -179,13 +179,13 @@ namespace Mono.CSharp {
        public class LocalTemporary : Expression, IMemoryLocation, IAssignMethod {
                LocalBuilder builder;
 
-               public LocalTemporary (Type t)
+               public LocalTemporary (TypeSpec t)
                {
                        type = t;
                        eclass = ExprClass.Value;
                }
 
-               public LocalTemporary (LocalBuilder b, Type t)
+               public LocalTemporary (LocalBuilder b, TypeSpec t)
                        : this (t)
                {
                        builder = b;
@@ -216,12 +216,10 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        if (builder == null)
                                throw new InternalErrorException ("Emit without Store, or after Release");
 
-                       ig.Emit (OpCodes.Ldloc, builder);
+                       ec.Emit (OpCodes.Ldloc, builder);
                }
 
                #region IAssignMethod Members
@@ -255,11 +253,10 @@ namespace Mono.CSharp {
 
                public void Store (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
                        if (builder == null)
                                builder = ec.GetTemporaryLocal (type);
 
-                       ig.Emit (OpCodes.Stloc, builder);
+                       ec.Emit (OpCodes.Stloc, builder);
                }
 
                public void AddressOf (EmitContext ec, AddressOp mode)
@@ -267,23 +264,16 @@ namespace Mono.CSharp {
                        if (builder == null)
                                builder = ec.GetTemporaryLocal (type);
 
-                       ILGenerator ig = ec.ig;
-
                        if (builder.LocalType.IsByRef) {
                                //
                                // if is_address, than this is just the address anyways,
                                // so we just return this.
                                //
-                               ig.Emit (OpCodes.Ldloc, builder);
+                               ec.Emit (OpCodes.Ldloc, builder);
                        } else {
-                               ig.Emit (OpCodes.Ldloca, builder);
+                               ec.Emit (OpCodes.Ldloca, builder);
                        }
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-               }
        }
 
        /// <summary>
@@ -329,8 +319,8 @@ namespace Mono.CSharp {
                        if (target == null || !ok)
                                return null;
 
-                       Type target_type = target.Type;
-                       Type source_type = source.Type;
+                       TypeSpec target_type = target.Type;
+                       TypeSpec source_type = source.Type;
 
                        eclass = ExprClass.Value;
                        type = target_type;
@@ -378,14 +368,6 @@ namespace Mono.CSharp {
                        return System.Linq.Expressions.Expression.Assign (target_object, source_object);
                }
 #endif
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       source.MutateHoistedGenericType (storey);
-                       target.MutateHoistedGenericType (storey);
-                       type = storey.MutateType (type);                        
-               }
-
                protected virtual Expression ResolveConversions (ResolveContext ec)
                {
                        source = Convert.ImplicitConversionRequired (ec, source, target.Type, loc);
@@ -693,7 +675,7 @@ namespace Mono.CSharp {
 
                protected override Expression ResolveConversions (ResolveContext ec)
                {
-                       Type target_type = target.Type;
+                       TypeSpec target_type = target.Type;
 
                        //
                        // 1. the return type is implicitly convertible to the type of target
@@ -721,7 +703,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (TypeManager.IsDynamicType (source.Type)) {
+                       if (source.Type == InternalType.Dynamic) {
                                Arguments arg = new Arguments (1);
                                arg.Add (new Argument (source));
                                return new SimpleAssign (target, new DynamicConversion (target_type, CSharpBinderFlags.ConvertExplicit, arg, loc), loc).Resolve (ec);
index 0305d4ad06e1db86ded82f0a06722d18653fbb20..caef628d329e2f668297c2ba00481ab40fd7d2d9 100644 (file)
@@ -58,7 +58,7 @@ namespace Mono.CSharp {
                /// <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, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa);
+               public abstract void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa);
 
                /// <summary>
                /// Returns one AttributeTarget for this element.
@@ -98,15 +98,14 @@ namespace Mono.CSharp {
                //
                IMemberContext context;
 
-               static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
+               public static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
                static Assembly orig_sec_assembly;
                public static readonly object[] EmptyObject = new object [0];
 
                IList<KeyValuePair<MemberExpr, NamedArgument>> named_values;
 
-               static Dictionary<Type, AttributeUsageAttribute> usage_attr_cache;
                // Cache for parameter-less attributes
-               static Dictionary<Type, ConstructorInfo> att_cache;
+               static Dictionary<TypeSpec, MethodSpec> att_cache;
 
                public Attribute (string target, ATypeNameExpression expr, Arguments[] args, Location loc, bool nameEscaped)
                {
@@ -135,8 +134,7 @@ namespace Mono.CSharp {
 
                public static void Reset ()
                {
-                       usage_attr_cache = new Dictionary<Type, AttributeUsageAttribute> (ReferenceEquality<Type>.Default);
-                       att_cache = new Dictionary<Type, ConstructorInfo> (ReferenceEquality<Type>.Default);
+                       att_cache = new Dictionary<TypeSpec, MethodSpec> ();
                }
 
                //
@@ -228,14 +226,14 @@ namespace Mono.CSharp {
                        return expr.ResolveAsTypeTerminal (ec, false);
                }
 
-               Type ResolvePossibleAttributeType (ATypeNameExpression expr, ref bool is_attr)
+               TypeSpec ResolvePossibleAttributeType (ATypeNameExpression expr, ref bool is_attr)
                {
                        TypeExpr te = ResolveAsTypeTerminal (expr, context);
                        if (te == null)
                                return null;
 
-                       Type t = te.Type;
-                       if (TypeManager.IsSubclassOf (t, TypeManager.attribute_type)) {
+                       TypeSpec t = te.Type;
+                       if (t.IsAttribute) {
                                is_attr = true;
                        } else {
                                Report.SymbolRelatedToPreviousError (t);
@@ -254,7 +252,7 @@ namespace Mono.CSharp {
 
                        bool t1_is_attr = false;
                        bool t2_is_attr = false;
-                       Type t1, t2;
+                       TypeSpec t1, t2;
                        ATypeNameExpression expanded = null;
 
                        try {
@@ -295,7 +293,7 @@ namespace Mono.CSharp {
                        resolve_error = true;
                }
 
-               public virtual Type ResolveType ()
+               public virtual TypeSpec ResolveType ()
                {
                        if (Type == null && !resolve_error)
                                ResolveAttributeType ();
@@ -322,7 +320,7 @@ namespace Mono.CSharp {
                        return HasSecurityAttribute && IsSecurityActionValid (false);
                }
 
-               static bool IsValidArgumentType (Type t)
+               static bool IsValidArgumentType (TypeSpec t)
                {
                        if (t.IsArray)
                                t = TypeManager.GetElementType (t);
@@ -356,16 +354,17 @@ namespace Mono.CSharp {
                                                return;
                                }
                        }
-                       
+
+                       var char_set = Import.ImportType (typeof (CharSet));
                        NamedArguments.Add (new NamedArgument (CharSetEnumMember, loc,
-                               Constant.CreateConstant (rc, typeof (CharSet), RootContext.ToplevelTypes.DefaultCharSet, Location)));
+                               Constant.CreateConstant (rc, char_set, RootContext.ToplevelTypes.DefaultCharSet, Location)));
                }
 
                public Report Report {
                        get { return context.Compiler.Report; }
                }
 
-               public ConstructorInfo Resolve ()
+               public MethodSpec Resolve ()
                {
                        if (resolve_error)
                                return null;
@@ -384,29 +383,23 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (Type);
+                       ObsoleteAttribute obsolete_attr = Type.GetAttributeObsolete ();
                        if (obsolete_attr != null) {
                                AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location, Report);
                        }
 
-                       ConstructorInfo ctor_meta;
-
+                       MethodSpec ctor;
                        // Try if the attribute is simple has been resolved before
                        if (PosArguments == null && NamedArguments == null) {
-                               if (att_cache.TryGetValue (Type, out ctor_meta)) {
+                               if (att_cache.TryGetValue (Type, out ctor)) {
                                        resolve_error = false;
-                                       return ctor_meta;
+                                       return ctor;
                                }
                        }
 
                        ResolveContext rc = new ResolveContext (context, ResolveContext.Options.ConstantScope);
-                       var ctor = ResolveConstructor (rc);
+                       ctor = ResolveConstructor (rc);
                        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;
                        }
 
@@ -417,7 +410,7 @@ namespace Mono.CSharp {
                        }
 
                        resolve_error = false;
-                       return (ConstructorInfo) ctor.MetaInfo;
+                       return ctor;
                }
 
                protected virtual MethodSpec ResolveConstructor (ResolveContext ec)
@@ -432,8 +425,8 @@ namespace Mono.CSharp {
                        }
 
                        MethodGroupExpr mg = MemberLookupFinal (ec, ec.CurrentType,
-                               Type, ConstructorInfo.ConstructorName, MemberTypes.Constructor,
-                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               Type, ConstructorInfo.ConstructorName, 0, MemberKind.Constructor,
+                               BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly,
                                Location) as MethodGroupExpr;
 
                        if (mg == null)
@@ -466,14 +459,14 @@ namespace Mono.CSharp {
                                a.Resolve (ec);
 
                                Expression member = Expression.MemberLookup (ec.Compiler,
-                                       ec.CurrentType, Type, name,
-                                       MemberTypes.All,
-                                       BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static,
+                                       ec.CurrentType, Type, name, 0,
+                                       MemberKind.All,
+                                       BindingRestriction.AccessibleOnly,
                                        Location);
 
                                if (member == null) {
-                                       member = Expression.MemberLookup (ec.Compiler, ec.CurrentType, Type, name,
-                                               MemberTypes.All, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
+                                       member = Expression.MemberLookup (ec.Compiler, ec.CurrentType, Type, name, 0,
+                                               MemberKind.All, BindingRestriction.None,
                                                Location);
 
                                        if (member != null) {
@@ -496,9 +489,9 @@ namespace Mono.CSharp {
                                ObsoleteAttribute obsolete_attr;
 
                                if (member is PropertyExpr) {
-                                       PropertyInfo pi = ((PropertyExpr) member).PropertyInfo;
+                                       var pi = ((PropertyExpr) member).PropertyInfo;
 
-                                       if (!pi.CanWrite || !pi.CanRead || pi.GetGetMethod ().IsStatic) {
+                                       if (!pi.HasSet || !pi.HasGet || pi.IsStatic) {
                                                ec.Report.SymbolRelatedToPreviousError (pi);
                                                Error_InvalidNamedArgument (ec, a);
                                                return false;
@@ -510,12 +503,7 @@ namespace Mono.CSharp {
                                                return false;
                                        }
 
-                                       PropertyBase pb = TypeManager.GetProperty (pi);
-                                       if (pb != null)
-                                               obsolete_attr = pb.GetObsoleteAttribute ();
-                                       else
-                                               obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (pi);
-
+                                       obsolete_attr = pi.GetAttributeObsolete ();
                                } else {
                                        var fi = ((FieldExpr) member).Spec;
 
@@ -525,16 +513,12 @@ namespace Mono.CSharp {
                                        }
 
                                        if (!IsValidArgumentType (member.Type)) {
-                                               ec.Report.SymbolRelatedToPreviousError (fi.MetaInfo);
+                                               ec.Report.SymbolRelatedToPreviousError (fi);
                                                Error_InvalidNamedArgumentType (ec, a);
                                                return false;
                                        }
 
-                                       FieldBase fb = TypeManager.GetField (fi.MetaInfo);
-                                       if (fb != null)
-                                               obsolete_attr = fb.GetObsoleteAttribute ();
-                                       else
-                                               obsolete_attr = AttributeTester.GetMemberObsoleteAttribute (fi.MetaInfo);
+                                       obsolete_attr = fi.GetAttributeObsolete ();
                                }
 
                                if (obsolete_attr != null && !context.IsObsolete)
@@ -557,7 +541,7 @@ namespace Mono.CSharp {
                public string GetValidTargets ()
                {
                        StringBuilder sb = new StringBuilder ();
-                       AttributeTargets targets = GetAttributeUsage (Type).ValidOn;
+                       AttributeTargets targets = Type.GetAttributeUsage (PredefinedAttributes.Get.AttributeUsage).ValidOn;
 
                        if ((targets & AttributeTargets.Assembly) != 0)
                                sb.Append ("assembly, ");
@@ -607,46 +591,7 @@ namespace Mono.CSharp {
                        return sb.Remove (sb.Length - 2, 2).ToString ();
                }
 
-               /// <summary>
-               /// Returns AttributeUsage attribute based on types hierarchy
-               /// </summary>
-               static AttributeUsageAttribute GetAttributeUsage (Type type)
-               {
-                       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) {
-                               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;
-                       }
-
-                       Attribute a = null;
-                       if (attr_class.OptAttributes != null)
-                               a = attr_class.OptAttributes.Search (pa);
-
-                       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);
-                       return ua;
-               }
-
-               AttributeUsageAttribute GetAttributeUsageAttribute ()
+               public AttributeUsageAttribute GetAttributeUsageAttribute ()
                {
                        if (!arg_resolved)
                                // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
@@ -742,7 +687,7 @@ namespace Mono.CSharp {
                        return ((BoolConstant) PosArguments[0].Expr).Value;
                }
 
-               public Type GetCoClassAttributeValue ()
+               public TypeSpec GetCoClassAttributeValue ()
                {
                        if (!arg_resolved)
                                Resolve ();
@@ -831,9 +776,9 @@ namespace Mono.CSharp {
                {
                        Type orig_assembly_type = null;
 
-                       if (TypeManager.LookupDeclSpace (Type) != null) {
+                       if (Type.MemberDefinition is TypeContainer) {
                                if (!RootContext.StdLib) {
-                                       orig_assembly_type = Type.GetType (Type.FullName);
+                                       orig_assembly_type = System.Type.GetType (Type.GetMetaInfo ().FullName);
                                } else {
                                        string orig_version_path = Environment.GetEnvironmentVariable ("__SECURITY_BOOTSTRAP_DB");
                                        if (orig_version_path == null) {
@@ -846,7 +791,7 @@ namespace Mono.CSharp {
                                                orig_sec_assembly = Assembly.LoadFile (file);
                                        }
 
-                                       orig_assembly_type = orig_sec_assembly.GetType (Type.FullName, true);
+                                       orig_assembly_type = orig_sec_assembly.GetType (Type.GetMetaInfo ().FullName, true);
                                        if (orig_assembly_type == null) {
                                                Report.Warning (-112, 1, Location, "Self-referenced security attribute `{0}' " +
                                                                "was not found in previous version of assembly");
@@ -865,11 +810,11 @@ namespace Mono.CSharp {
                                        args[j] = ((Constant) PosArguments[j].Expr).GetTypedValue ();
                                }
 
-                               sa = (SecurityAttribute) Activator.CreateInstance (Type, args);
+                               sa = (SecurityAttribute) Activator.CreateInstance (Type.GetMetaInfo (), args);
 
                                if (named_values != null) {
                                        for (int i = 0; i < named_values.Count; ++i) {
-                                               PropertyInfo pi = ((PropertyExpr) named_values[i].Key).PropertyInfo;
+                                               PropertyInfo pi = ((PropertyExpr) named_values[i].Key).PropertyInfo.MetaInfo;
                                                pi.SetValue (sa, ((Constant) named_values [i].Value.Expr).GetTypedValue (), null);
                                        }
                                }
@@ -881,7 +826,7 @@ namespace Mono.CSharp {
                                // All types are from newly created assembly but for invocation with old one we need to convert them
                                if (named_values != null) {
                                        for (int i = 0; i < named_values.Count; ++i) {
-                                               PropertyInfo emited_pi = ((PropertyExpr) named_values[i].Key).PropertyInfo;
+                                               PropertyInfo emited_pi = ((PropertyExpr) named_values[i].Key).PropertyInfo.MetaInfo;
                                                // FIXME: We are missing return type filter
                                                // TODO: pi can be null
                                                PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name);
@@ -1065,7 +1010,7 @@ namespace Mono.CSharp {
                                        return false;
 
                                MethodImplOptions options;
-                               if (PosArguments [0].Type != typeof (MethodImplOptions))
+                               if (PosArguments[0].Type.GetMetaInfo () != typeof (MethodImplOptions))
                                        options = (MethodImplOptions) System.Enum.ToObject (typeof (MethodImplOptions), ((Constant) PosArguments[0].Expr).GetValue ());
                                else
                                        options = (MethodImplOptions) ((Constant) PosArguments [0].Expr).GetValue ();
@@ -1076,13 +1021,13 @@ namespace Mono.CSharp {
 
                public LayoutKind GetLayoutKindValue ()
                {
-                       if (!RootContext.StdLib || PosArguments [0].Type != typeof (LayoutKind))
+                       if (!RootContext.StdLib || PosArguments[0].Type.GetMetaInfo () != typeof (LayoutKind))
                                return (LayoutKind) System.Enum.ToObject (typeof (LayoutKind), ((Constant) PosArguments[0].Expr).GetValue ());
 
                        return (LayoutKind) ((Constant) PosArguments[0].Expr).GetValue ();
                }
 
-               public Constant GetParameterDefaultValue (out Type type)
+               public Constant GetParameterDefaultValue (out TypeSpec type)
                {
                        var expr = PosArguments[0].Expr;
 
@@ -1116,7 +1061,7 @@ namespace Mono.CSharp {
                        if (ctor == null)
                                return;
 
-                       AttributeUsageAttribute usage_attr = GetAttributeUsage (Type);
+                       AttributeUsageAttribute usage_attr = Type.GetAttributeUsage (PredefinedAttributes.Get.AttributeUsage);
                        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",
@@ -1129,7 +1074,7 @@ namespace Mono.CSharp {
                        AttributeEncoder encoder = new AttributeEncoder (false);
 
                        if (PosArguments != null) {
-                               var param_types = TypeManager.GetParameterData (ctor).Types;
+                               var param_types = ctor.Parameters.Types;
                                for (int j = 0; j < PosArguments.Count; ++j) {
                                        var pt = param_types[j];
                                        if (!IsValidArgumentType (pt)) {
@@ -1248,7 +1193,7 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public Type GetArgumentType ()
+               public TypeSpec GetArgumentType ()
                {
                        TypeOf e = GetValue () as TypeOf;
                        if (e == null)
@@ -1493,7 +1438,7 @@ namespace Mono.CSharp {
                        Stream.Write (buf);
                }
 
-               public void Encode (Type type)
+               public void Encode (TypeSpec type)
                {
                        if (type == TypeManager.bool_type) {
                                Stream.Write ((byte) 0x02);
@@ -1536,12 +1481,13 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool EncodeTypeName (Type type)
+               public bool EncodeTypeName (TypeSpec type)
                {
-                       if (TypeManager.ContainsGenericParameters (type) && !TypeManager.IsGenericTypeDefinition (type))
-                               return false;
+//                     if (TypeManager.ContainsGenericParameters (type) && !TypeManager.IsGenericTypeDefinition (type))
+//                             return false;
 
-                       Encode (CodeGen.Assembly.Builder == type.Assembly ? type.FullName : type.AssemblyQualifiedName);
+                       var old_type = type.GetMetaInfo ();
+                       Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
                        return true;
                }
 
@@ -1571,32 +1517,8 @@ namespace Mono.CSharp {
        /// <summary>
        /// Helper class for attribute verification routine.
        /// </summary>
-       sealed class AttributeTester
+       static class AttributeTester
        {
-               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 ()
-               {
-                       Reset ();
-               }
-
-               private AttributeTester ()
-               {
-               }
-
-               public static void Reset ()
-               {
-                       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 {
                        Ok,
                        RefOutArrayError,
@@ -1609,8 +1531,8 @@ namespace Mono.CSharp {
                /// </summary>
                public static Result AreOverloadedMethodParamsClsCompliant (AParametersCollection pa, AParametersCollection pb) 
                {
-                       Type [] types_a = pa.Types;
-                       Type [] types_b = pb.Types;
+                       TypeSpec [] types_a = pa.Types;
+                       TypeSpec [] types_b = pb.Types;
                        if (types_a == null || types_b == null)
                                return Result.Ok;
 
@@ -1619,18 +1541,19 @@ namespace Mono.CSharp {
 
                        Result result = Result.Ok;
                        for (int i = 0; i < types_b.Length; ++i) {
-                               Type aType = types_a [i];
-                               Type bType = types_b [i];
+                               TypeSpec aType = types_a [i];
+                               TypeSpec bType = types_b [i];
+
+                               var ac_a = aType as ArrayContainer;
+                               var ac_b = aType as ArrayContainer;
 
-                               if (aType.IsArray && bType.IsArray) {
-                                       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) {
+                               if (ac_a != null && ac_b != null) {
+                                       if (ac_a.Rank != ac_b.Rank && ac_a.Element == ac_b.Element) {
                                                result = Result.RefOutArrayError;
                                                continue;
                                        }
 
-                                       if (a_el_type.IsArray || b_el_type.IsArray) {
+                                       if (ac_a.Element.IsArray || ac_b.Element.IsArray) {
                                                result = Result.ArrayArrayError;
                                                continue;
                                        }
@@ -1646,34 +1569,6 @@ namespace Mono.CSharp {
                        return result;
                }
 
-               /// <summary>
-               /// This method tests the CLS compliance of external types. It doesn't test type visibility.
-               /// </summary>
-               public static bool IsClsCompliant (Type type) 
-               {
-                       if (type == null)
-                               return true;
-
-                       bool result;
-                       if (analyzed_types.TryGetValue (type, out result))
-                               return result;
-
-                       if (type.IsPointer) {
-                               analyzed_types.Add (type, false);
-                               return false;
-                       }
-
-                       if (type.IsArray) {
-                               result = IsClsCompliant (TypeManager.GetElementType (type));
-                       } else if (TypeManager.IsNullableType (type)) {
-                               result = IsClsCompliant (TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (type) [0]));
-                       } else {
-                               result = AnalyzeTypeCompliance (type);
-                       }
-                       analyzed_types.Add (type, result);
-                       return result;
-               }        
-
                public static void VerifyModulesClsCompliance (CompilerContext ctx)
                {
                        Module[] modules = GlobalRootNamespace.Instance.Modules;
@@ -1691,26 +1586,9 @@ namespace Mono.CSharp {
                        }
                }
 
-               public static Type GetImportedIgnoreCaseClsType (string name)
-               {
-                       foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
-                               Type t = a.GetType (name, false, true);
-                               if (t == null)
-                                       continue;
-
-                               if (IsClsCompliant (t))
-                                       return t;
-                       }
-                       return null;
-               }
-
                static bool GetClsCompliantAttributeValue (ICustomAttributeProvider attribute_provider, Assembly a) 
                {
-                       PredefinedAttribute pa = PredefinedAttributes.Get.CLSCompliant;
-                       if (!pa.IsDefined)
-                               return false;
-
-                       object[] cls_attr = attribute_provider.GetCustomAttributes (pa.Type, false);
+                       object[] cls_attr = attribute_provider.GetCustomAttributes (typeof (CLSCompliantAttribute), false);
                        if (cls_attr.Length == 0) {
                                if (a == null)
                                        return false;
@@ -1721,101 +1599,6 @@ namespace Mono.CSharp {
                        return ((CLSCompliantAttribute)cls_attr [0]).IsCompliant;
                }
 
-               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;
-
-                       return GetClsCompliantAttributeValue (type, type.Assembly);
-               }
-
-               /// <summary>
-               /// Returns instance of ObsoleteAttribute when type is obsolete
-               /// </summary>
-               public static ObsoleteAttribute GetObsoleteAttribute (Type type)
-               {
-                       ObsoleteAttribute result;
-                       if (analyzed_types_obsolete.TryGetValue (type, out result))
-                               return result;
-
-                       if (TypeManager.HasElementType (type)) {
-                               result = GetObsoleteAttribute (TypeManager.GetElementType (type));
-                       } 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) {
-                                       PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete;
-                                       if (pa.IsDefined) {
-                                               object[] attribute = type.GetCustomAttributes (pa.Type, false);
-                                               if (attribute.Length == 1)
-                                                       result = (ObsoleteAttribute) attribute[0];
-                                       }
-                               } else {
-                                       result = type_ds.GetObsoleteAttribute ();
-                               }
-                       }
-
-                       // Cannot use .Add because of corlib bootstrap
-                       analyzed_types_obsolete [type] = result;
-                       return result;
-               }
-
-               /// <summary>
-               /// Returns instance of ObsoleteAttribute when method is obsolete
-               /// </summary>
-               public static ObsoleteAttribute GetMethodObsoleteAttribute (MethodBase mb)
-               {
-                       IMethodData mc = TypeManager.GetMethod (mb);
-                       if (mc != null) 
-                               return mc.GetObsoleteAttribute ();
-
-                       // compiler generated methods are not registered by AddMethod
-                       if (mb.DeclaringType is TypeBuilder)
-                               return null;
-
-                       MemberInfo mi = TypeManager.GetPropertyFromAccessor (mb);
-                       if (mi != null)
-                               return GetMemberObsoleteAttribute (mi);
-
-                       mi = TypeManager.GetEventFromAccessor (mb);
-                       if (mi != null)
-                               return GetMemberObsoleteAttribute (mi);
-
-                       return GetMemberObsoleteAttribute (mb);
-               }
-
-               /// <summary>
-               /// Returns instance of ObsoleteAttribute when member is obsolete
-               /// </summary>
-               public static ObsoleteAttribute GetMemberObsoleteAttribute (MemberInfo mi)
-               {
-                       ObsoleteAttribute oa;
-                       if (analyzed_member_obsolete.TryGetValue (mi, out oa))
-                               return oa;
-
-                       if ((mi.DeclaringType is TypeBuilder) || TypeManager.IsGenericType (mi.DeclaringType))
-                               return null;
-
-                       PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete;
-                       if (!pa.IsDefined)
-                               return null;
-
-                       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>
@@ -1832,84 +1615,6 @@ namespace Mono.CSharp {
                        }
                        Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message);
                }
-
-               public static bool IsConditionalMethodExcluded (MethodBase mb, Location loc)
-               {
-                       bool excluded;
-                       if (analyzed_method_excluded.TryGetValue (mb, out excluded))
-                               return excluded;
-
-                       PredefinedAttribute pa = PredefinedAttributes.Get.Conditional;
-                       if (!pa.IsDefined)
-                               return false;
-
-                       ConditionalAttribute[] attrs = mb.GetCustomAttributes (pa.Type, true)
-                               as ConditionalAttribute[];
-                       if (attrs.Length == 0) {
-                               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);
-                                       return false;
-                               }
-                       }
-
-                       analyzed_method_excluded.Add (mb, true);
-                       return true;
-               }
-
-               /// <summary>
-               /// Analyzes class whether it has attribute which has ConditionalAttribute
-               /// and its condition is not defined.
-               /// </summary>
-               public static bool IsAttributeExcluded (Type type, Location loc)
-               {
-                       if (!type.IsClass)
-                               return false;
-
-                       Class class_decl = TypeManager.LookupDeclSpace (type) as Class;
-
-                       // TODO: add caching
-                       // TODO: merge all Type bases attribute caching to one cache to save memory
-                       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;
-                               }
-                               return attributes.Length > 0;
-                       }
-
-                       return class_decl.IsExcluded ();
-               }
-
-               public static Type GetCoClassAttribute (Type type)
-               {
-                       TypeContainer tc = TypeManager.LookupInterface (type);
-                       PredefinedAttribute pa = PredefinedAttributes.Get.CoClass;
-                       if (tc == null) {
-                               if (!pa.IsDefined)
-                                       return null;
-
-                               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)
-                               return null;
-
-                       Attribute a = tc.OptAttributes.Search (pa);
-                       if (a == null)
-                               return null;
-
-                       return a.GetCoClassAttributeValue ();
-               }
        }
 
        public class PredefinedAttributes
@@ -2024,13 +1729,13 @@ namespace Mono.CSharp {
 
        public class PredefinedAttribute
        {
-               Type type;
+               TypeSpec type;
                CustomAttributeBuilder cab;
-               ConstructorInfo ctor;
+               MethodSpec ctor;
                readonly string ns, name;
                CompilerContext compiler;
 
-               static readonly Type NotFound = typeof (PredefinedAttribute);
+               static readonly TypeSpec NotFound = InternalType.Null;
 
                public PredefinedAttribute (string ns, string name)
                {
@@ -2038,18 +1743,18 @@ namespace Mono.CSharp {
                        this.name = name;
                }
 
-               public static bool operator == (Type type, PredefinedAttribute pa)
+               public static bool operator == (TypeSpec type, PredefinedAttribute pa)
                {
                        return type == pa.type;
                }
 
-               public static bool operator != (Type type, PredefinedAttribute pa)
+               public static bool operator != (TypeSpec type, PredefinedAttribute pa)
                {
                        return type != pa.type;
                }
 
                public ConstructorInfo Constructor {
-                       get { return ctor; }
+                       get { return ctor == null ? null : (ConstructorInfo) ctor.GetMetaInfo (); }
                }
 
                public override int GetHashCode ()
@@ -2148,15 +1853,15 @@ namespace Mono.CSharp {
                        if (!Resolve (true))
                                return false;
 
-                       ConstructorInfo ci = TypeManager.GetPredefinedConstructor (type, Location.Null, Type.EmptyTypes);
+                       var ci = TypeManager.GetPredefinedConstructor (type, Location.Null, TypeSpec.EmptyTypes);
                        if (ci == null)
                                return false;
 
-                       cab = new CustomAttributeBuilder (ci, new object[0]);
+                       cab = new CustomAttributeBuilder ((ConstructorInfo) ci.GetMetaInfo (), new object[0]);
                        return true;
                }
 
-               public bool ResolveConstructor (Location loc, params Type[] argType)
+               public bool ResolveConstructor (Location loc, params TypeSpec[] argType)
                {
                        if (ctor != null)
                                throw new InternalErrorException ("Predefined ctor redefined");
@@ -2168,7 +1873,7 @@ namespace Mono.CSharp {
                        return ctor != null;
                }
 
-               public Type Type {
+               public TypeSpec Type {
                        get { return type; }
                }
        }
index a146e02fc1917f84e4fa85237a594f316e3a2ffd..b8b82ffe573f99a60cec30aaf0444ebb22f00810 100644 (file)
@@ -14,9 +14,24 @@ namespace Mono.CSharp {
 
        public class ConstantFold {
 
-               public static readonly Type[] binary_promotions = new Type[] { 
-                       TypeManager.decimal_type, TypeManager.double_type, TypeManager.float_type,
-                       TypeManager.uint64_type, TypeManager.int64_type, TypeManager.uint32_type };
+               static TypeSpec[] binary_promotions;
+
+               public static TypeSpec[] BinaryPromotionsTypes {
+                       get {
+                               if (binary_promotions == null) {
+                                        binary_promotions = new TypeSpec[] { 
+                                               TypeManager.decimal_type, TypeManager.double_type, TypeManager.float_type,
+                                               TypeManager.uint64_type, TypeManager.int64_type, TypeManager.uint32_type };
+                               }
+
+                               return binary_promotions;
+                       }
+               }
+
+               public static void Reset ()
+               {
+                       binary_promotions = null;
+               }
 
                //
                // Performs the numeric promotions on the left and right expresions
@@ -30,10 +45,10 @@ namespace Mono.CSharp {
                //              
                static bool DoBinaryNumericPromotions (ResolveContext rc, ref Constant left, ref Constant right)
                {
-                       Type ltype = left.Type;
-                       Type rtype = right.Type;
+                       TypeSpec ltype = left.Type;
+                       TypeSpec rtype = right.Type;
 
-                       foreach (Type t in binary_promotions) {
+                       foreach (TypeSpec t in BinaryPromotionsTypes) {
                                if (t == ltype)
                                        return t == rtype || ConvertPromotion (rc, ref right, ref left, t);
 
@@ -46,7 +61,7 @@ namespace Mono.CSharp {
                        return left != null && right != null;
                }
 
-               static bool ConvertPromotion (ResolveContext rc, ref Constant prim, ref Constant second, Type type)
+               static bool ConvertPromotion (ResolveContext rc, ref Constant prim, ref Constant second, TypeSpec type)
                {
                        Constant c = prim.ConvertImplicitly (rc, type);
                        if (c != null) {
@@ -99,8 +114,8 @@ namespace Mono.CSharp {
                                return new SideEffectConstant (result, right, loc);
                        }
 
-                       Type lt = left.Type;
-                       Type rt = right.Type;
+                       TypeSpec lt = left.Type;
+                       TypeSpec rt = right.Type;
                        bool bool_res;
 
                        if (lt == TypeManager.bool_type && lt == rt) {
index 77fd4b927644a9bd33acdd972e5be5bb1078163b..64b6fa35934019b4ac14ad3ab8d64b5f8305c816 100644 (file)
@@ -20,6 +20,7 @@ using System.Runtime.InteropServices;
 using System.Security;
 using System.Security.Permissions;
 using System.Text;
+using System.Linq;
 
 #if NET_2_1
 using XmlElement = System.Object;
@@ -34,14 +35,14 @@ namespace Mono.CSharp {
        /// <summary>
        ///   This is the base class for structs and classes.  
        /// </summary>
-       public abstract class TypeContainer : DeclSpace, IMemberContainer
+       public abstract class TypeContainer : DeclSpace, ITypeDefinition
        {
                //
                // Different context is needed when resolving type container base
                // types. Type names come from the parent scope but type parameter
                // names from the container scope.
                //
-               struct BaseContext : IMemberContext
+               public struct BaseContext : IMemberContext
                {
                        TypeContainer tc;
 
@@ -56,7 +57,7 @@ namespace Mono.CSharp {
                                get { return tc.Compiler; }
                        }
 
-                       public Type CurrentType {
+                       public TypeSpec CurrentType {
                                get { return tc.Parent.CurrentType; }
                        }
 
@@ -64,8 +65,12 @@ namespace Mono.CSharp {
                                get { return tc.PartialContainer.CurrentTypeParameters; }
                        }
 
-                       public TypeContainer CurrentTypeDefinition {
-                               get { return tc.Parent.CurrentTypeDefinition; }
+                       public MemberCore CurrentMemberDefinition {
+                               get { return tc; }
+                       }
+
+                       public bool HasUnresolvedConstraints {
+                               get { return true; }
                        }
 
                        public bool IsObsolete {
@@ -82,10 +87,10 @@ namespace Mono.CSharp {
 
                        public string GetSignatureForError ()
                        {
-                               throw new NotImplementedException ();
+                               return tc.GetSignatureForError ();
                        }
 
-                       public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+                       public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
                        {
                                return null;
                        }
@@ -95,16 +100,18 @@ namespace Mono.CSharp {
                                return tc.Parent.LookupNamespaceAlias (name);
                        }
 
-                       public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+                       public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
                        {
-                               TypeParameter[] tp = CurrentTypeParameters;
-                               if (tp != null) {
-                                       TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
-                                       if (t != null)
-                                               return new TypeParameterExpr (t, loc);
+                               if (arity == 0) {
+                                       TypeParameter[] tp = CurrentTypeParameters;
+                                       if (tp != null) {
+                                               TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
+                                               if (t != null)
+                                                       return new TypeParameterExpr (t, loc);
+                                       }
                                }
 
-                               return tc.Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                               return tc.Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
                        }
 
                        #endregion
@@ -131,14 +138,11 @@ namespace Mono.CSharp {
                // Holds the list of properties
                List<MemberCore> properties;
 
-               // Holds the list of delegates
-               List<TypeContainer> delegates;
-               
                // Holds the list of constructors
-               protected List<MemberCore> instance_constructors;
+               protected List<Constructor> instance_constructors;
 
                // Holds the list of fields
-               protected List<MemberCore> fields;
+               protected List<FieldBase> fields;
 
                // Holds a list of fields that have initializers
                protected List<FieldInitializer> initialized_fields;
@@ -183,30 +187,30 @@ namespace Mono.CSharp {
                // from classes from the arraylist `type_bases' 
                //
                TypeExpr base_type;
-               TypeExpr[] iface_exprs;
-               Type GenericType;
-               GenericTypeParameterBuilder[] nested_gen_params;
+               protected TypeExpr[] iface_exprs;
 
                protected List<FullNamedExpression> type_bases;
 
-               protected bool members_defined;
+               bool members_defined;
                bool members_defined_ok;
+               bool type_defined;
 
-               // The interfaces we implement.
-               protected Type[] ifaces;
+               TypeContainer InTransit;
 
-               // The base member cache and our member cache
-               MemberCache base_cache;
-               protected MemberCache member_cache;
+               GenericTypeParameterBuilder[] all_tp_builders;
 
                public const string DefaultIndexerName = "Item";
 
                private bool seen_normal_indexers = false;
                private string indexer_name = DefaultIndexerName;
                protected bool requires_delayed_unmanagedtype_check;
+               bool error;
 
                private CachedMethods cached_method;
 
+               protected TypeSpec spec;
+               TypeSpec current_type;
+
                List<TypeContainer> partial_parts;
 
                /// <remarks>
@@ -226,12 +230,62 @@ namespace Mono.CSharp {
                        this.PartialContainer = this;
                }
 
+               #region Properties
+
+               public override TypeSpec CurrentType {
+                       get {
+                               if (current_type == null) {
+                                       if (IsGeneric) {
+                                               //
+                                               // Switch to inflated version as it's used by all expressions
+                                               //
+                                               var targs = CurrentTypeParameters == null ? TypeSpec.EmptyTypes : CurrentTypeParameters.Select (l => l.Type).ToArray ();
+                                               current_type = spec.MakeGenericType (targs);
+                                       } else {
+                                               current_type = spec;
+                                       }
+                               }
+
+                               return current_type;
+                       }
+               }
+
+               public override TypeParameter[] CurrentTypeParameters {
+                       get {
+                               return PartialContainer.type_params;
+                       }
+               }
+
+               int CurrentTypeParametersStartIndex {
+                       get {
+                               int total = all_tp_builders.Length;
+                               if (CurrentTypeParameters != null) {
+                                       return total - CurrentTypeParameters.Length;
+                               }
+                               return total;
+                       }
+               }
+
+               public TypeSpec Definition {
+                       get {
+                               return spec;
+                       }
+               }
+
+               public bool HasMembersDefined {
+                       get {
+                               return members_defined;
+                       }
+               }
+
+               #endregion
+
                public bool AddMember (MemberCore symbol)
                {
                        return AddToContainer (symbol, symbol.MemberName.Basename);
                }
 
-               protected virtual bool AddMemberType (DeclSpace ds)
+               protected virtual bool AddMemberType (TypeContainer ds)
                {
                        return AddToContainer (ds, ds.Basename);
                }
@@ -330,13 +384,7 @@ namespace Mono.CSharp {
                
                public void AddDelegate (Delegate d)
                {
-                       if (!AddMemberType (d))
-                               return;
-
-                       if (delegates == null)
-                               delegates = new List<TypeContainer> ();
-
-                       delegates.Add (d);
+                       AddTypeContainer (d);
                }
 
                private void AddMemberToList (MemberCore mc, List<MemberCore> alist, bool isexplicit)
@@ -383,7 +431,7 @@ namespace Mono.CSharp {
                                ConstructorBuilder.ConstructorName : ConstructorBuilder.TypeConstructorName))
                                return;
                        
-                       if (is_static && c.Parameters.IsEmpty){
+                       if (is_static && c.ParameterInfo.IsEmpty){
                                if (default_static_constructor != null) {
                                    Report.SymbolRelatedToPreviousError (default_static_constructor);
                                        Report.Error (111, c.Location,
@@ -394,11 +442,11 @@ namespace Mono.CSharp {
 
                                default_static_constructor = c;
                        } else {
-                               if (c.Parameters.IsEmpty)
+                               if (c.ParameterInfo.IsEmpty)
                                        default_constructor = c;
                                
                                if (instance_constructors == null)
-                                       instance_constructors = new List<MemberCore> ();
+                                       instance_constructors = new List<Constructor> ();
                                
                                instance_constructors.Add (c);
                        }
@@ -410,7 +458,7 @@ namespace Mono.CSharp {
                                return false;
 
                        if (fields == null)
-                               fields = new List<MemberCore> ();
+                               fields = new List<FieldBase> ();
 
                        fields.Add (field);
 
@@ -500,7 +548,7 @@ namespace Mono.CSharp {
                        compiler_generated.Add (c);
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.DefaultMember) {
                                if (Indexers != null) {
@@ -508,8 +556,13 @@ namespace Mono.CSharp {
                                        return;
                                }
                        }
-                       
-                       base.ApplyAttributeBuilder (a, ctor, cdata, pa);
+
+                       if (a.Type == pa.Required) {
+                               Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
+                               return;
+                       }
+
+                       TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                } 
 
                public override AttributeTargets AttributeTargets {
@@ -536,19 +589,19 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected virtual Type BaseType {
+               public virtual TypeSpec BaseType {
                        get {
-                               return TypeBuilder.BaseType;
+                               return spec.BaseType;
                        }
                }
 
-               public IList<MemberCore> Fields {
+               public IList<FieldBase> Fields {
                        get {
                                return fields;
                        }
                }
 
-               public IList<MemberCore> InstanceConstructors {
+               public IList<Constructor> InstanceConstructors {
                        get {
                                return instance_constructors;
                        }
@@ -578,12 +631,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public IList<TypeContainer> Delegates {
-                       get {
-                               return delegates;
-                       }
-               }
-
                public IList<CompilerGeneratedClass> CompilerGeneratedClasses {
                        get {
                                return compiler_generated;
@@ -596,12 +643,24 @@ namespace Mono.CSharp {
                        }
                }
 
-               public string IndexerName {
+               public int TypeParametersCount {
                        get {
-                               return indexers == null ? DefaultIndexerName : indexer_name;
+                               return MemberName.Arity;
                        }
                }
 
+               TypeParameterSpec[] ITypeDefinition.TypeParameters {
+                       get {
+                               // TODO MemberCache: this is going to hurt
+                               return PartialContainer.type_params.Select (l => l.Type).ToArray ();
+                       }
+               }
+
+               public string GetAttributeDefaultMember ()
+               {
+                       return indexers == null ? DefaultIndexerName : indexer_name;
+               }
+
                public bool IsComImport {
                        get {
                                if (OptAttributes == null)
@@ -611,6 +670,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               string ITypeDefinition.Namespace {
+                       get {
+                               return NamespaceEntry.NS.MemberName.GetSignatureForError ();
+                       }
+               }
+
                public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
                {
                        if ((field.ModFlags & Modifiers.STATIC) != 0){
@@ -710,12 +775,33 @@ namespace Mono.CSharp {
                        get { return pending; }
                }
 
-               public override bool GetClsCompliantAttributeValue ()
+               public TypeSpec GetAttributeCoClass ()
                {
-                       if (PartialContainer != this)
-                               return PartialContainer.GetClsCompliantAttributeValue ();
+                       if (OptAttributes == null)
+                               return null;
+
+                       Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CoClass);
+                       if (a == null)
+                               return null;
+
+                       return a.GetCoClassAttributeValue ();
+               }
+
+               public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+               {
+                       Attribute a = null;
+                       if (OptAttributes != null) {
+                               a = OptAttributes.Search (pa);
+                       }
+
+                       if (a == null) {
+                               if (BaseType != TypeManager.attribute_type)
+                                       return BaseType.GetAttributeUsage (pa);
+
+                               return null;
+                       }
 
-                       return base.GetClsCompliantAttributeValue ();
+                       return a.GetAttributeUsageAttribute ();
                }
 
                public virtual void AddBasesForPart (DeclSpace part, List<FullNamedExpression> bases)
@@ -743,21 +829,16 @@ namespace Mono.CSharp {
 
                        int count = type_bases.Count;
                        TypeExpr [] ifaces = null;
-                       IMemberContext base_context = new BaseContext (this);
+                       var base_context = new BaseContext (this);
                        for (int i = 0, j = 0; i < count; i++){
-                               FullNamedExpression fne = (FullNamedExpression) type_bases [i];
+                               FullNamedExpression fne = type_bases [i];
 
-                               //
-                               // Standard ResolveAsTypeTerminal cannot be used in this case because
-                               // it does ObsoleteAttribute and constraint checks which require
-                               // base type to be set
-                               //
-                               TypeExpr fne_resolved = fne.ResolveAsBaseTerminal (base_context, false);
+                               TypeExpr fne_resolved = fne.ResolveAsTypeTerminal (base_context, false);
                                if (fne_resolved == null)
                                        continue;
 
                                if (i == 0 && Kind == MemberKind.Class && !fne_resolved.Type.IsInterface) {
-                                       if (fne_resolved is DynamicTypeExpr)
+                                       if (fne_resolved.Type == InternalType.Dynamic)
                                                Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
                                                        GetSignatureForError ());
                                        else
@@ -880,7 +961,7 @@ namespace Mono.CSharp {
                                        if (!TypeManager.IsEqual (o_a.ReturnType, o_b.ReturnType))
                                                continue;
 
-                                       if (!TypeManager.IsEqual (o_a.ParameterTypes, o_b.ParameterTypes))
+                                       if (!TypeSpecComparer.Default.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
                                                continue;
 
                                        operators[i] = null;
@@ -912,93 +993,46 @@ namespace Mono.CSharp {
                                                GetSignatureForError ());
                        }
                }
-
-               bool CheckGenericInterfaces (Type[] ifaces)
+       
+               bool CreateTypeBuilder ()
                {
-                       var already_checked = new List<Type> ();
-
-                       for (int i = 0; i < ifaces.Length; i++) {
-                               Type iface = ifaces [i];
-                               foreach (Type t in already_checked) {
-                                       if (iface == t)
-                                               continue;
-
-                                       Type[] inferred = new Type [CountTypeParameters];
-                                       if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, inferred, null))
-                                               continue;
+                       //
+                       // Sets .size to 1 for structs with no instance fields
+                       //
+                       int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0;
 
-                                       Report.Error (695, Location,
-                                               "`{0}' cannot implement both `{1}' and `{2}' " +
-                                               "because they may unify for some type parameter substitutions",
-                                               TypeManager.CSharpName (TypeBuilder), TypeManager.CSharpName (iface),
-                                               TypeManager.CSharpName (t));
+                       if (IsTopLevel) {
+                               if (GlobalRootNamespace.Instance.IsNamespace (Name)) {
+                                       Report.Error (519, Location, "`{0}' clashes with a predefined namespace", Name);
                                        return false;
                                }
 
-                               already_checked.Add (iface);
-                       }
-
-                       return true;
-               }
-
-               bool error = false;
-               
-               bool CreateTypeBuilder ()
-               {
-                       try {
-                               Type default_parent = null;
-                               if (Kind == MemberKind.Struct)
-                                       default_parent = TypeManager.value_type;
-                               else if (Kind == MemberKind.Enum)
-                                       default_parent = TypeManager.enum_type;
-                               else if (Kind == MemberKind.Delegate)
-                                       default_parent = TypeManager.multicast_delegate_type;
-
-                               //
-                               // Sets .size to 1 for structs with no instance fields
-                               //
-                               int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0;
-
-                               if (IsTopLevel){
-                                       if (GlobalRootNamespace.Instance.IsNamespace (Name)) {
-                                               Report.Error (519, Location, "`{0}' clashes with a predefined namespace", Name);
-                                               return false;
-                                       }
-
-                                       ModuleBuilder builder = Module.Compiled.Builder;
-                                       TypeBuilder = builder.DefineType (
-                                               Name, TypeAttr, default_parent, type_size);
-                               } else {
-                                       TypeBuilder builder = Parent.TypeBuilder;
+                               ModuleBuilder builder = Module.Compiled.Builder;
+                               TypeBuilder = builder.DefineType (Name, TypeAttr, null, type_size);
+                       } else {
+                               TypeBuilder builder = Parent.TypeBuilder;
 
-                                       TypeBuilder = builder.DefineNestedType (
-                                               Basename, TypeAttr, default_parent, type_size);
-                               }
-                       } catch (ArgumentException) {
-                               Report.RuntimeMissingSupport (Location, "static classes");
-                               return false;
+                               TypeBuilder = builder.DefineNestedType (Basename, TypeAttr, null, type_size);
                        }
 
-                       TypeManager.AddUserType (this);
+                       spec.SetMetaInfo (TypeBuilder);
+                       spec.MemberCache = new MemberCache (this);
+                       spec.DeclaringType = Parent.CurrentType;
+
+                       if (!IsTopLevel)
+                               Parent.MemberCache.AddMember (spec);
 
                        if (IsGeneric) {
-                               string[] param_names = new string [TypeParameters.Length];
+                               string[] param_names = new string[TypeParameters.Length];
                                for (int i = 0; i < TypeParameters.Length; i++)
-                                       param_names [i] = TypeParameters [i].Name;
+                                       param_names [i] = TypeParameters[i].Name;
 
-                               GenericTypeParameterBuilder[] gen_params = TypeBuilder.DefineGenericParameters (param_names);
+                               all_tp_builders = TypeBuilder.DefineGenericParameters (param_names);
 
-                               int offset = CountTypeParameters;
-                               if (CurrentTypeParameters != null)
-                                       offset -= CurrentTypeParameters.Length;
-
-                               if (offset > 0) {
-                                       nested_gen_params = new GenericTypeParameterBuilder [offset];
-                                       Array.Copy (gen_params, nested_gen_params, offset);
+                               int offset = CurrentTypeParametersStartIndex;
+                               for (int i = offset; i < all_tp_builders.Length; i++) {
+                                       CurrentTypeParameters [i - offset].Define (all_tp_builders [i], spec);
                                }
-
-                               for (int i = offset; i < gen_params.Length; i++)
-                                       CurrentTypeParameters [i - offset].Define (gen_params [i]);
                        }
 
                        return true;
@@ -1011,44 +1045,138 @@ namespace Mono.CSharp {
                                iface_exprs = GetNormalPartialBases (ref base_type);
                        }
 
-                       //
-                       // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
-                       // which in turn should have called DefineType()s on base types if necessary.
-                       //
-                       // None of the code below should trigger DefineType()s on classes that we depend on.
-                       // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
-                       //
-                       // Let's do it as soon as possible, since code below can call DefineType() on classes
-                       // that depend on us to be populated before they are.
-                       //
-                       if (!(this is CompilerGeneratedClass) && !(this is Delegate))
-                               RootContext.RegisterOrder (this); 
-
-                       if (!CheckRecursiveDefinition (this))
-                               return false;
+                       var cycle = CheckRecursiveDefinition (this);
+                       if (cycle != null) {
+                               Report.SymbolRelatedToPreviousError (cycle);
+                               if (this is Interface) {
+                                       Report.Error (529, Location,
+                                               "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
+                                           GetSignatureForError (), cycle.GetSignatureForError ());
+                               } else {
+                                       Report.Error (146, Location,
+                                               "Circular base class dependency involving `{0}' and `{1}'",
+                                               GetSignatureForError (), cycle.GetSignatureForError ());
+                               }
 
-                       if (base_type != null && base_type.Type != null) {
-                               TypeBuilder.SetParent (base_type.Type);
+                               base_type = null;
                        }
 
-                       // add interfaces that were not added at type creation
                        if (iface_exprs != null) {
-                               ifaces = TypeManager.ExpandInterfaces (iface_exprs);
-                               if (ifaces == null)
-                                       return false;
+                               foreach (TypeExpr iface in iface_exprs) {
+                                       var iface_type = iface.Type;
 
-                               foreach (Type itype in ifaces)
-                                       TypeBuilder.AddInterfaceImplementation (itype);
+                                       if (!spec.AddInterface (iface_type))
+                                               continue;
 
-                               if (!CheckGenericInterfaces (ifaces))
-                                       return false;
+                                       if (iface_type.IsGeneric && spec.Interfaces != null) {
+                                               foreach (var prev_iface in iface_exprs) {
+                                                       if (prev_iface == iface)
+                                                               break;
+
+                                                       if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface.Type))
+                                                               continue;
+
+                                                       Report.Error (695, Location,
+                                                               "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
+                                                               GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
+                                               }
+                                       }
+
+                                       TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
+
+                                       // Ensure the base is always setup
+                                       var compiled_iface = iface_type.MemberDefinition as Interface;
+                                       if (compiled_iface != null) {
+                                               // TODO: Need DefineBaseType only
+                                               compiled_iface.DefineType ();
+                                       }
+
+                                       if (iface_type.Interfaces != null) {
+                                               var base_ifaces = new List<TypeSpec> (iface_type.Interfaces);
+                                               for (int i = 0; i < base_ifaces.Count; ++i) {
+                                                       var ii_iface_type = base_ifaces[i];
+                                                       if (spec.AddInterface (ii_iface_type)) {
+                                                               TypeBuilder.AddInterfaceImplementation (ii_iface_type.GetMetaInfo ());
+
+                                                               if (ii_iface_type.Interfaces != null)
+                                                                       base_ifaces.AddRange (ii_iface_type.Interfaces);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
 
-                               TypeManager.RegisterBuilder (TypeBuilder, ifaces);
+                       if (Kind == MemberKind.Interface) {
+                               spec.BaseType = TypeManager.object_type;
+                               return true;
+                       }
+
+                       TypeSpec base_ts;
+                       if (base_type != null)
+                               base_ts = base_type.Type;
+                       else if (spec.IsStruct)
+                               base_ts = TypeManager.value_type;
+                       else if (spec.IsEnum)
+                               base_ts = TypeManager.enum_type;
+                       else if (spec.IsDelegate)
+                               base_ts = TypeManager.multicast_delegate_type;
+                       else
+                               base_ts = null;
+
+                       if (base_ts != null) {
+                               spec.BaseType = base_ts;
+
+                               // Set base type after type creation
+                               TypeBuilder.SetParent (base_ts.GetMetaInfo ());
                        }
 
                        return true;
                }
 
+               public virtual void DefineConstants ()
+               {
+                       if (constants != null) {
+                               foreach (Const c in constants) {
+                                       c.DefineValue ();
+                               }
+                       }
+
+                       if (instance_constructors != null) {
+                               foreach (MethodCore m in instance_constructors) {
+                                       var p = m.ParameterInfo;
+                                       if (!p.IsEmpty && p[p.Count - 1].HasDefaultValue) {
+                                               var rc = new ResolveContext (m);
+                                               p.ResolveDefaultValues (rc);
+                                       }
+                               }
+                       }
+
+                       if (methods != null) {
+                               foreach (MethodCore m in methods) {
+                                       var p = m.ParameterInfo;
+                                       if (!p.IsEmpty && p[p.Count - 1].HasDefaultValue) {
+                                               var rc = new ResolveContext (m);
+                                               p.ResolveDefaultValues (rc);
+                                       }
+                               }
+                       }
+
+                       if (indexers != null) {
+                               foreach (Indexer i in indexers) {
+                                       var p = i.ParameterInfo;
+                                       if (p[p.Count - 1].HasDefaultValue) {
+                                           var rc = new ResolveContext (i);
+                                               p.ResolveDefaultValues (rc);
+                                       }
+                               }
+                       }
+
+                       if (types != null) {
+                               foreach (var t in types)
+                                       t.DefineConstants ();
+                       }
+               }
+
                //
                // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
                //
@@ -1066,8 +1194,11 @@ namespace Mono.CSharp {
                        }
 
                        if (partial_parts != null) {
-                               foreach (TypeContainer part in partial_parts)
+                               foreach (TypeContainer part in partial_parts) {
+                                       part.spec = spec;
+                                       part.current_type = current_type;
                                        part.TypeBuilder = TypeBuilder;
+                               }
                        }
 
                        if (Types != null) {
@@ -1082,8 +1213,6 @@ namespace Mono.CSharp {
                        return TypeBuilder;
                }
 
-               bool type_defined;
-
                public override TypeBuilder DefineType ()
                {
                        if (error)
@@ -1093,11 +1222,6 @@ namespace Mono.CSharp {
 
                        type_defined = true;
 
-                       if (CreateType () == null) {
-                               error = true;
-                               return null;
-                       }
-
                        if (!DefineBaseTypes ()) {
                                error = true;
                                return null;
@@ -1115,10 +1239,10 @@ namespace Mono.CSharp {
                {
                        base.SetParameterInfo (constraints_list);
 
-                       if (!is_generic || PartialContainer == this)
+                       if (PartialContainer.CurrentTypeParameters == null || PartialContainer == this)
                                return;
 
-                       TypeParameter[] tc_names = PartialContainer.TypeParameters;
+                       TypeParameter[] tc_names = PartialContainer.CurrentTypeParameters;
                        for (int i = 0; i < tc_names.Length; ++i) {
                                if (tc_names [i].Name != type_params [i].Name) {
                                        Report.SymbolRelatedToPreviousError (PartialContainer.Location, "");
@@ -1136,15 +1260,20 @@ namespace Mono.CSharp {
                        }
                }
 
+               //
+               // Replaces normal spec with predefined one when compiling corlib
+               // and this type container defines predefined type
+               //
+               public void SetPredefinedSpec (PredefinedTypeSpec spec)
+               {
+                       this.spec = spec;
+               }
+
                void UpdateTypeParameterConstraints (TypeContainer part)
                {
                        TypeParameter[] current_params = type_params;
                        for (int i = 0; i < current_params.Length; i++) {
-                               Constraints c = part.type_params [i].Constraints;
-                               if (c == null)
-                                       continue;
-
-                               if (current_params [i].UpdateConstraints (part, c))
+                               if (current_params [i].AddPartialConstraints (part, part.type_params [i]))
                                        continue;
 
                                Report.SymbolRelatedToPreviousError (Location, "");
@@ -1154,69 +1283,47 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool ResolveType ()
+               public bool ResolveTypeParameters ()
                {
-                       if (!DoResolveType ())
+                       if (!DoResolveTypeParameters ())
                                return false;
 
+                       if (types != null) {
+                               foreach (var type in types)
+                                       if (!type.ResolveTypeParameters ())
+                                               return false;
+                       }
+
                        if (compiler_generated != null) {
                                foreach (CompilerGeneratedClass c in compiler_generated)
-                                       if (!c.ResolveType ())
+                                       if (!c.ResolveTypeParameters ())
                                                return false;
                        }
 
                        return true;
                }
 
-               protected virtual bool DoResolveType ()
+               protected virtual bool DoResolveTypeParameters ()
                {
-                       if (!IsGeneric)
+                       if (CurrentTypeParameters == null)
                                return true;
 
                        if (PartialContainer != this)
                                throw new InternalErrorException ();
 
-                       TypeExpr current_type = null;
-                       if (CurrentTypeParameters != null) {
-                               foreach (TypeParameter type_param in CurrentTypeParameters) {
-                                       if (!type_param.Resolve (this)) {
-                                               error = true;
-                                               return false;
-                                       }
-                               }
-
-                               if (partial_parts != null) {
-                                       foreach (TypeContainer part in partial_parts)
-                                               UpdateTypeParameterConstraints (part);
-                               }
-                       }
-
-                       for (int i = 0; i < TypeParameters.Length; ++i) {
-                               //
-                               // FIXME: Same should be done for delegates
-                               // TODO: Quite ugly way how to propagate constraints to
-                               // nested types
-                               //
-                               if (nested_gen_params != null && i < nested_gen_params.Length) {
-                                       TypeParameters [i].SetConstraints (nested_gen_params [i]);
-                               } else {
-                                       if (!TypeParameters [i].DefineType (this)) {
-                                               error = true;
-                                               return false;
-                                       }
+                       var base_context = new BaseContext (this);
+                       foreach (TypeParameter type_param in CurrentTypeParameters) {
+                               if (!type_param.ResolveConstraints (base_context)) {
+                                       error = true;
+                                       return false;
                                }
                        }
 
-                       // TODO: Very strange, why not simple make generic type from
-                       // current type parameters
-                       current_type = new GenericTypeExpr (this, Location);
-                       current_type = current_type.ResolveAsTypeTerminal (this, false);
-                       if (current_type == null) {
-                               error = true;
-                               return false;
+                       if (partial_parts != null) {
+                               foreach (TypeContainer part in partial_parts)
+                                       UpdateTypeParameterConstraints (part);
                        }
 
-                       currentType = current_type.Type;
                        return true;
                }
 
@@ -1228,63 +1335,35 @@ namespace Mono.CSharp {
                                                return false;
                        }
 
-                       if (Delegates != null) {
-                               foreach (Delegate d in Delegates)
-                                       if (d.DefineType () == null)
-                                               return false;
-                       }
-
                        return true;
                }
 
-               TypeContainer InTransit;
-
-               protected bool CheckRecursiveDefinition (TypeContainer tc)
+               TypeSpec CheckRecursiveDefinition (TypeContainer tc)
                {
-                       if (InTransit != null) {
-                               Report.SymbolRelatedToPreviousError (this);
-                               if (this is Interface)
-                                       Report.Error (
-                                               529, tc.Location, "Inherited interface `{0}' causes a " +
-                                               "cycle in the interface hierarchy of `{1}'",
-                                               GetSignatureForError (), tc.GetSignatureForError ());
-                               else
-                                       Report.Error (
-                                               146, tc.Location, "Circular base class dependency " +
-                                               "involving `{0}' and `{1}'",
-                                               tc.GetSignatureForError (), GetSignatureForError ());
-                               return false;
-                       }
+                       if (InTransit != null)
+                               return spec;
 
                        InTransit = tc;
 
                        if (base_type != null && base_type.Type != null) {
-                               Type t = TypeManager.DropGenericTypeArguments (base_type.Type);
-                               TypeContainer ptc = TypeManager.LookupTypeContainer (t);
-                               if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
-                                       return false;
+                               var ptc = base_type.Type.MemberDefinition as TypeContainer;
+                               if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
+                                       return base_type.Type;
                        }
 
                        if (iface_exprs != null) {
                                foreach (TypeExpr iface in iface_exprs) {
-                                       Type itype = TypeManager.DropGenericTypeArguments (iface.Type);
-                                       TypeContainer ptc = TypeManager.LookupTypeContainer (itype);
-                                       if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
-                                               return false;
+                                       var ptc = iface.Type.MemberDefinition as Interface;
+                                       if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
+                                               return iface.Type;
                                }
                        }
 
-                       if (!IsTopLevel && !Parent.PartialContainer.CheckRecursiveDefinition (this))
-                               return false;
+                       if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
+                               return spec;
 
                        InTransit = null;
-                       return true;
-               }
-
-               public override TypeParameter[] CurrentTypeParameters {
-                       get {
-                               return PartialContainer.type_params;
-                       }
+                       return null;
                }
 
                /// <summary>
@@ -1298,6 +1377,11 @@ namespace Mono.CSharp {
                        members_defined_ok = DoDefineMembers ();
                        members_defined = true;
 
+                       if (types != null) {
+                               foreach (var nested in types)
+                                       nested.Define ();
+                       }
+
                        return members_defined_ok;
                }
 
@@ -1305,18 +1389,26 @@ namespace Mono.CSharp {
                {
                        if (iface_exprs != null) {
                                foreach (TypeExpr iface in iface_exprs) {
-                                       ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (iface.Type);
-                                       if ((oa != null) && !IsObsolete)
-                                               AttributeTester.Report_ObsoleteMessage (
-                                                       oa, iface.GetSignatureForError (), Location, Report);
+                                       var iface_type = iface.Type;
+
+                                       // Ensure the base is always setup
+                                       var compiled_iface = iface_type.MemberDefinition as Interface;
+                                       if (compiled_iface != null)
+                                               compiled_iface.Define ();
+
+                                       if (Kind == MemberKind.Interface)
+                                               MemberCache.AddInterface (iface_type);
+
+                                       ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
+                                       if (oa != null && !IsObsolete)
+                                               AttributeTester.Report_ObsoleteMessage (oa, iface.GetSignatureForError (), Location, Report);
 
                                        GenericTypeExpr ct = iface as GenericTypeExpr;
                                        if (ct != null) {
                                                // TODO: passing `this' is wrong, should be base type iface instead
                                                TypeManager.CheckTypeVariance (ct.Type, Variance.Covariant, this);
 
-                                               if (!ct.CheckConstraints (this))
-                                                       return false;
+                                               ct.CheckConstraints (this);
 
                                                if (ct.HasDynamicArguments ()) {
                                                        Report.Error (1966, iface.Location,
@@ -1329,51 +1421,40 @@ namespace Mono.CSharp {
                        }
 
                        if (base_type != null) {
-                               ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (base_type.Type);
+                               ObsoleteAttribute obsolete_attr = base_type.Type.GetAttributeObsolete ();
                                if (obsolete_attr != null && !IsObsolete)
                                        AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location, Report);
 
-                               GenericTypeExpr ct = base_type as GenericTypeExpr;
-                               if ((ct != null) && !ct.CheckConstraints (this))
-                                       return false;
-                               
-                               TypeContainer baseContainer = TypeManager.LookupTypeContainer(base_type.Type);
+                               var ct = base_type as GenericTypeExpr;
+                               if (ct != null)
+                                       ct.CheckConstraints (this);
+
+                               var baseContainer = base_type.Type.MemberDefinition as ClassOrStruct;
                                if (baseContainer != null)
-                                       baseContainer.Define();                         
-                               
-                               member_cache = new MemberCache (base_type.Type, this);
-                       } else if (Kind == MemberKind.Interface) {
-                               member_cache = new MemberCache (null, this);
-                               Type [] ifaces = TypeManager.GetInterfaces (TypeBuilder);
-                               for (int i = 0; i < ifaces.Length; ++i)
-                                       member_cache.AddInterface (TypeManager.LookupMemberCache (ifaces [i]));
-                       } else {
-                               member_cache = new MemberCache (null, this);
+                                       baseContainer.Define ();
                        }
 
-                       if (types != null)
-                               foreach (TypeContainer tc in types)
-                                       member_cache.AddNestedType (tc);
-
-                       if (delegates != null)
-                               foreach (Delegate d in delegates)
-                                       member_cache.AddNestedType (d);
-
-                       if (partial_parts != null) {
-                               foreach (TypeContainer part in partial_parts)
-                                       part.member_cache = member_cache;
+                       if (type_params != null) {
+                               foreach (var tp in type_params) {
+                                       tp.CheckGenericConstraints ();
+                               }
                        }
 
                        if (!IsTopLevel) {
-                               MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Basename, false);
-                               if (conflict_symbol == null) {
+                               MemberSpec candidate;
+                               var conflict_symbol = MemberCache.FindBaseMember (this, out candidate);
+                               if (conflict_symbol == null && candidate == null) {
                                        if ((ModFlags & Modifiers.NEW) != 0)
-                                               Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
+                                               Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+                                                       GetSignatureForError ());
                                } else {
                                        if ((ModFlags & Modifiers.NEW) == 0) {
-                                               Report.SymbolRelatedToPreviousError (conflict_symbol);
+                                               if (candidate == null)
+                                                       candidate = conflict_symbol;
+
+                                               Report.SymbolRelatedToPreviousError (candidate);
                                                Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
-                                                       GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
+                                                       GetSignatureForError (), candidate.GetSignatureForError ());
                                        }
                                }
                        }
@@ -1407,23 +1488,9 @@ namespace Mono.CSharp {
                                CheckPairedOperators ();
                        }
 
-                       DefineContainerMembers (delegates);
-
                        ComputeIndexerName();
                        CheckEqualsAndGetHashCode();
 
-                       if (CurrentType != null) {
-                               GenericType = CurrentType;
-                       }
-
-                       //
-                       // FIXME: This hack is needed because member cache does not work
-                       // with generic types, we rely on runtime to inflate dynamic types.
-                       // TODO: This hack requires member cache refactoring to be removed
-                       //
-                       if (TypeManager.IsGenericType (TypeBuilder))
-                               member_cache = new MemberCache (this);
-
                        return true;
                }
 
@@ -1486,7 +1553,7 @@ namespace Mono.CSharp {
                                !pa.ResolveConstructor (Location, TypeManager.string_type))
                                return;
 
-                       CustomAttributeBuilder cb = new CustomAttributeBuilder (pa.Constructor, new string [] { IndexerName });
+                       CustomAttributeBuilder cb = new CustomAttributeBuilder (pa.Constructor, new string [] { GetAttributeDefaultMember () });
                        TypeBuilder.SetCustomAttribute (cb);
                }
 
@@ -1500,94 +1567,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
-               {
-                       return BaseCache == null ? null : BaseCache.FindMemberWithSameName (name, ignore_methods, null);
-               }
-
-               /// <summary>
-               ///   This function is based by a delegate to the FindMembers routine
-               /// </summary>
-               static bool AlwaysAccept (MemberInfo m, object filterCriteria)
-               {
-                       return true;
-               }
-
-               /// <summary>
-               ///   This filter is used by FindMembers, and we just keep
-               ///   a global for the filter to `AlwaysAccept'
-               /// </summary>
-               static MemberFilter accepting_filter;
-
-               
-               static TypeContainer ()
-               {
-                       accepting_filter = new MemberFilter (AlwaysAccept);
-               }
-
-               public MethodInfo[] GetMethods ()
-               {
-                       var members = new List<MethodInfo> ();
-
-                       Define ();
-
-                       if (methods != null) {
-                               int len = methods.Count;
-                               for (int i = 0; i < len; i++) {
-                                       Method m = (Method) methods [i];
-
-                                       members.Add (m.MethodBuilder);
-                               }
-                       }
-
-                       if (operators != null) {
-                               int len = operators.Count;
-                               for (int i = 0; i < len; i++) {
-                                       Operator o = (Operator) operators [i];
-
-                                       members.Add (o.MethodBuilder);
-                               }
-                       }
-
-                       if (properties != null) {
-                               int len = properties.Count;
-                               for (int i = 0; i < len; i++) {
-                                       Property p = (Property) properties [i];
-
-                                       if (p.GetBuilder != null)
-                                               members.Add (p.GetBuilder);
-                                       if (p.SetBuilder != null)
-                                               members.Add (p.SetBuilder);
-                               }
-                       }
-                               
-                       if (indexers != null) {
-                               int len = indexers.Count;
-                               for (int i = 0; i < len; i++) {
-                                       Indexer ix = (Indexer) indexers [i];
-
-                                       if (ix.GetBuilder != null)
-                                               members.Add (ix.GetBuilder);
-                                       if (ix.SetBuilder != null)
-                                               members.Add (ix.SetBuilder);
-                               }
-                       }
-
-                       if (events != null) {
-                               int len = events.Count;
-                               for (int i = 0; i < len; i++) {
-                                       Event e = (Event) events [i];
-
-                                       if (e.AddBuilder != null)
-                                               members.Add (e.AddBuilder);
-                                       if (e.RemoveBuilder != null)
-                                               members.Add (e.RemoveBuilder);
-                               }
-                       }
-
-                       return members.ToArray ();
-               }
-               
                // Indicated whether container has StructLayout attribute set Explicit
                public bool HasExplicitLayout {
                        get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
@@ -1596,447 +1575,13 @@ namespace Mono.CSharp {
 
                public bool HasStructLayout {
                        get { return (caching_flags & Flags.HasStructLayout) != 0; }
-                       set { caching_flags |= Flags.HasStructLayout; }
-               }
-
-               //
-               // Return the nested type with name @name.  Ensures that the nested type
-               // is defined if necessary.  Do _not_ use this when you have a MemberCache handy.
-               //
-               public Type FindNestedType (string name)
-               {
-                       if (PartialContainer != this)
-                               throw new InternalErrorException ("should not happen");
-
-                       var lists = new[] { types, delegates };
-
-                       for (int j = 0; j < lists.Length; ++j) {
-                               var list = lists [j];
-                               if (list == null)
-                                       continue;
-                               
-                               int len = list.Count;
-                               for (int i = 0; i < len; ++i) {
-                                       var ds = list [i];
-                                       if (ds.Basename == name) {
-                                               return ds.DefineType ();
-                                       }
-                               }
-                       }
-
-                       return null;
-               }
-
-               private void FindMembers_NestedTypes (Modifiers modflags,
-                                                     BindingFlags bf, MemberFilter filter, object criteria,
-                                                         ref List<MemberInfo> members)
-               {
-                       var lists = new[] { types, delegates };
-
-                       for (int j = 0; j < lists.Length; ++j) {
-                               var list = lists [j];
-                               if (list == null)
-                                       continue;
-                       
-                               int len = list.Count;
-                               for (int i = 0; i < len; i++) {
-                                       var ds = list [i];
-                                       
-                                       if ((ds.ModFlags & modflags) == 0)
-                                               continue;
-                                       
-                                       TypeBuilder tb = ds.TypeBuilder;
-                                       if (tb == null) {
-                                               if (!(criteria is string) || ds.Basename.Equals (criteria))
-                                                       tb = ds.DefineType ();
-                                       }
-                                       
-                                       if (tb != null && (filter (tb, criteria) == true)) {
-                                               if (members == null)
-                                                       members = new List<MemberInfo> ();
-                                               
-                                               members.Add (tb);
-                                       }
-                               }
-                       }
-               }
-               
-               /// <summary>
-               ///   This method returns the members of this type just like Type.FindMembers would
-               ///   Only, we need to use this for types which are _being_ defined because MS' 
-               ///   implementation can't take care of that.
-               /// </summary>
-               //
-               // FIXME: return an empty static array instead of null, that cleans up
-               // some code and is consistent with some coding conventions I just found
-               // out existed ;-)
-               //
-               //
-               // Notice that in various cases we check if our field is non-null,
-               // something that would normally mean that there was a bug elsewhere.
-               //
-               // The problem happens while we are defining p-invoke methods, as those
-               // will trigger a FindMembers, but this happens before things are defined
-               //
-               // Since the whole process is a no-op, it is fine to check for null here.
-               //
-               // TODO: This approach will be one day completely removed, it's already
-               // used at few places only
-               //
-               //
-               public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
-                                                       MemberFilter filter, object criteria)
-               {
-                       List<MemberInfo> members = null;
-
-                       Modifiers modflags = 0;
-                       if ((bf & BindingFlags.Public) != 0)
-                               modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
-                                       Modifiers.INTERNAL;
-                       if ((bf & BindingFlags.NonPublic) != 0)
-                               modflags |= Modifiers.PRIVATE;
-
-                       Modifiers static_mask = 0, static_flags = 0;
-                       switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
-                       case BindingFlags.Static:
-                               static_mask = static_flags = Modifiers.STATIC;
-                               break;
-
-                       case BindingFlags.Instance:
-                               static_mask = Modifiers.STATIC;
-                               static_flags = 0;
-                               break;
-
-                       default:
-                               static_mask = static_flags = 0;
-                               break;
-                       }
-
-                       Timer.StartTimer (TimerType.TcFindMembers);
-
-                       if (filter == null)
-                               filter = accepting_filter; 
-
-                       if ((mt & MemberTypes.Field) != 0) {
-                               if (fields != null) {
-                                       int len = fields.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               FieldBase f = (FieldBase) fields [i];
-                                               
-                                               if ((f.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((f.ModFlags & static_mask) != static_flags)
-                                                       continue;
-
-                                               FieldBuilder fb = f.FieldBuilder;
-                                               if (fb != null && filter (fb, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-                                                       
-                                                       members.Add (fb);
-                                               }
-                                       }
-                               }
-
-                               if (constants != null) {
-                                       int len = constants.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               Const con = (Const) constants [i];
-                                               
-                                               if ((con.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((con.ModFlags & static_mask) != static_flags)
-                                                       continue;
-
-                                               FieldBuilder fb = con.FieldBuilder;
-                                               if (fb == null) {
-                                                       // Define parent and not member, otherwise membercache can be null
-                                                       if (con.Parent.Define ())
-                                                               fb = con.FieldBuilder;
-                                               }
-                                               if (fb != null && filter (fb, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-                                                       
-                                                       members.Add (fb);
-                                               }
-                                       }
-                               }
-                       }
-
-                       if ((mt & MemberTypes.Method) != 0) {
-                               if (methods != null) {
-                                       int len = methods.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               MethodOrOperator m = (MethodOrOperator) methods [i];
-                                               
-                                               if ((m.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((m.ModFlags & static_mask) != static_flags)
-                                                       continue;
-                                               
-                                               MethodBuilder mb = m.MethodBuilder;
-
-                                               if (mb != null && filter (mb, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-
-                                                       members.Add (mb);
-                                               }
-                                       }
-                               }
-
-                               if (operators != null) {
-                                       int len = operators.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               Operator o = (Operator) operators [i];
-                                               
-                                               if ((o.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((o.ModFlags & static_mask) != static_flags)
-                                                       continue;
-                                               
-                                               MethodBuilder ob = o.MethodBuilder;
-                                               if (ob != null && filter (ob, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-                                                       
-                                                       members.Add (ob);
-                                               }
-                                       }
-                               }
-
-                               if (events != null) {
-                                       foreach (Event e in events) {
-                                               if ((e.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((e.ModFlags & static_mask) != static_flags)
-                                                       continue;
-
-                                               MethodBuilder b = e.AddBuilder;
-                                               if (b != null && filter (b, criteria)) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-
-                                                       members.Add (b);
-                                               }
-
-                                               b = e.RemoveBuilder;
-                                               if (b != null && filter (b, criteria)) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-
-                                                       members.Add (b);
-                                               }
-                                       }
-                               }
-
-                               if (properties != null) {
-                                       int len = properties.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               Property p = (Property) properties [i];
-                                               
-                                               if ((p.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((p.ModFlags & static_mask) != static_flags)
-                                                       continue;
-                                               
-                                               MethodBuilder b;
-
-                                               b = p.GetBuilder;
-                                               if (b != null && filter (b, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-                                                       
-                                                       members.Add (b);
-                                               }
-
-                                               b = p.SetBuilder;
-                                               if (b != null && filter (b, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-                                                       
-                                                       members.Add (b);
-                                               }
-                                       }
-                               }
-                               
-                               if (indexers != null) {
-                                       int len = indexers.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               Indexer ix = (Indexer) indexers [i];
-                                               
-                                               if ((ix.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((ix.ModFlags & static_mask) != static_flags)
-                                                       continue;
-                                               
-                                               MethodBuilder b;
-
-                                               b = ix.GetBuilder;
-                                               if (b != null && filter (b, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-                                                       
-                                                       members.Add (b);
-                                               }
-
-                                               b = ix.SetBuilder;
-                                               if (b != null && filter (b, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-                                                       
-                                                       members.Add (b);
-                                               }
-                                       }
-                               }
-                       }
-
-                       if ((mt & MemberTypes.Event) != 0) {
-                               if (events != null) {
-                                       int len = events.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               Event e = (Event) events [i];
-                                               
-                                               if ((e.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((e.ModFlags & static_mask) != static_flags)
-                                                       continue;
-
-                                               MemberInfo eb = e.EventBuilder;
-                                               if (eb != null && filter (eb, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-
-                                                       members.Add (e.EventBuilder);
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       if ((mt & MemberTypes.Property) != 0){
-                               if (properties != null) {
-                                       int len = properties.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               Property p = (Property) properties [i];
-                                               
-                                               if ((p.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((p.ModFlags & static_mask) != static_flags)
-                                                       continue;
-
-                                               MemberInfo pb = p.PropertyBuilder;
-                                               if (pb != null && filter (pb, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-                                                       
-                                                       members.Add (p.PropertyBuilder);
-                                               }
-                                       }
-                               }
-
-                               if (indexers != null) {
-                                       int len = indexers.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               Indexer ix = (Indexer) indexers [i];
-                                               
-                                               if ((ix.ModFlags & modflags) == 0)
-                                                       continue;
-                                               if ((ix.ModFlags & static_mask) != static_flags)
-                                                       continue;
-
-                                               MemberInfo ib = ix.PropertyBuilder;
-                                               if (ib != null && filter (ib, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-                                                       
-                                                       members.Add (ix.PropertyBuilder);
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       if ((mt & MemberTypes.NestedType) != 0)
-                               FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
-
-                       if ((mt & MemberTypes.Constructor) != 0){
-                               if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
-                                       int len = instance_constructors.Count;
-                                       for (int i = 0; i < len; i++) {
-                                               Constructor c = (Constructor) instance_constructors [i];
-                                               
-                                               ConstructorBuilder cb = c.ConstructorBuilder;
-                                               if (cb != null && filter (cb, criteria) == true) {
-                                                       if (members == null)
-                                                               members = new List<MemberInfo> ();
-
-                                                       members.Add (cb);
-                                               }
-                                       }
-                               }
-
-                               if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
-                                       ConstructorBuilder cb =
-                                               default_static_constructor.ConstructorBuilder;
-                                       
-                                       if (cb != null && filter (cb, criteria) == true) {
-                                               if (members == null)
-                                                       members = new List<MemberInfo> ();
-                                               
-                                               members.Add (cb);
-                                       }
-                               }
-                       }
-
-                       //
-                       // Lookup members in base if requested.
-                       //
-                       if ((bf & BindingFlags.DeclaredOnly) == 0) {
-                               if (TypeBuilder.BaseType != null) {
-                                       MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
-                                       if (list.Count > 0) {
-                                               if (members == null)
-                                                       members = new List<MemberInfo> ();
-                                       
-                                               members.AddRange (list);
-                                       }
-                               }
-                       }
-
-                       Timer.StopTimer (TimerType.TcFindMembers);
-
-                       if (members == null)
-                               return MemberList.Empty;
-                       else
-                               return new MemberList (members);
-               }
-
-               public override MemberCache MemberCache {
-                       get {
-                               return member_cache;
-                       }
-               }
-
-               public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
-                                                     MemberFilter filter, object criteria)
-               {
-                       DeclSpace ds = TypeManager.LookupDeclSpace (t);
-
-                       if (ds != null)
-                               return ds.FindMembers (mt, bf, filter, criteria);
-                       else
-                               return new MemberList (t.FindMembers (mt, bf, filter, criteria));
-                }
-
-               /// <summary>
-               ///   Emits the values for the constants
-               /// </summary>
-               public void EmitConstants ()
-               {
-                       if (constants != null)
-                               foreach (Const con in constants)
-                                       con.Emit ();
-                       return;
+                       set { caching_flags |= Flags.HasStructLayout; }
+               }
+
+               public MemberCache MemberCache {
+                       get {
+                               return spec.MemberCache;
+                       }
                }
 
                void CheckMemberUsage (List<MemberCore> al, string member_type)
@@ -2109,13 +1654,32 @@ namespace Mono.CSharp {
                        }
                }
 
+               public override void Emit ()
+               {
+                       if (all_tp_builders != null) {
+                               int current_starts_index = CurrentTypeParametersStartIndex;
+                               for (int i = 0; i < all_tp_builders.Length; i++) {
+                                       if (i < current_starts_index) {
+                                               TypeParameters[i].EmitConstraints (all_tp_builders [i]);
+                                       } else {
+                                               CurrentTypeParameters [i - current_starts_index].Emit ();
+                                       }
+                               }
+                       }
+
+                       if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
+                               PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (TypeBuilder);
+
+                       base.Emit ();
+               }
+
                // TODO: move to ClassOrStruct
                void EmitConstructors ()
                {
                        if (instance_constructors == null)
                                return;
 
-                       if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsComplianceRequired ()) {
+                       if (spec.IsAttribute && IsExposedFromAssembly () && RootContext.VerifyClsCompliance && IsClsComplianceRequired ()) {
                                bool has_compliant_args = false;
 
                                foreach (Constructor c in instance_constructors) {
@@ -2158,10 +1722,9 @@ namespace Mono.CSharp {
 
                        EmitConstructors ();
 
-                       // Can not continue if constants are broken
-                       EmitConstants ();
-                       if (Report.Errors > 0)
-                               return;
+                       if (constants != null)
+                               foreach (Const con in constants)
+                                       con.Emit ();
 
                        if (default_static_constructor != null)
                                default_static_constructor.Emit ();
@@ -2194,10 +1757,9 @@ namespace Mono.CSharp {
                                foreach (FieldBase f in fields)
                                        f.Emit ();
 
-                       if (delegates != null) {
-                               foreach (Delegate d in Delegates) {
-                                       d.Emit ();
-                               }
+                       if (types != null) {
+                               foreach (TypeContainer t in types)
+                                       t.EmitType ();
                        }
 
                        if (pending != null)
@@ -2208,15 +1770,22 @@ namespace Mono.CSharp {
 
                        if (compiler_generated != null) {
                                for (int i = 0; i < compiler_generated.Count; ++i)
-                                       ((CompilerGeneratedClass) compiler_generated [i]).EmitType ();
+                                       compiler_generated [i].EmitType ();
                        }
                }
-               
-               public override void CloseType ()
+
+               public void CloseType ()
                {
                        if ((caching_flags & Flags.CloseTypeCreated) != 0)
                                return;
 
+                       // Close base type container first to avoid TypeLoadException
+                       if (spec.BaseType != null) {
+                               var btype = spec.BaseType.MemberDefinition as TypeContainer;
+                               if (btype != null)
+                                       btype.CloseType ();
+                       }
+
                        try {
                                caching_flags |= Flags.CloseTypeCreated;
                                TypeBuilder.CreateType ();
@@ -2232,26 +1801,14 @@ namespace Mono.CSharp {
                        
                        if (Types != null){
                                foreach (TypeContainer tc in Types)
-                                       if (tc.Kind == MemberKind.Struct)
-                                               tc.CloseType ();
-
-                               foreach (TypeContainer tc in Types)
-                                       if (tc.Kind != MemberKind.Struct)
-                                               tc.CloseType ();
+                                       tc.CloseType ();
                        }
 
-                       if (Delegates != null)
-                               foreach (Delegate d in Delegates)
-                                       d.CloseType ();
-
                        if (compiler_generated != null)
                                foreach (CompilerGeneratedClass c in compiler_generated)
                                        c.CloseType ();
                        
-                       PartialContainer = null;
                        types = null;
-//                     properties = null;
-                       delegates = null;
                        fields = null;
                        initialized_fields = null;
                        initialized_static_fields = null;
@@ -2267,9 +1824,6 @@ namespace Mono.CSharp {
                        default_static_constructor = null;
                        type_bases = null;
                        OptAttributes = null;
-                       ifaces = null;
-                       base_cache = null;
-                       member_cache = null;
                }
 
                //
@@ -2363,59 +1917,20 @@ namespace Mono.CSharp {
                        if (!base.VerifyClsCompliance ())
                                return false;
 
-                       VerifyClsName ();
-
-                       Type base_type = TypeBuilder.BaseType;
-                       if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
-                               Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
-                       }
-                       return true;
-               }
-
-
-               /// <summary>
-               /// Checks whether container name is CLS Compliant
-               /// </summary>
-               void VerifyClsName ()
-               {
-                       Dictionary<string, object> base_members = base_cache == null ?
-                               new Dictionary<string, object> () :
-                               base_cache.GetPublicMembers ();
-                       var this_members = new Dictionary<string, object> ();
-
-                       foreach (var entry in defined_names) {
-                               MemberCore mc = entry.Value;
-                               if (!mc.IsClsComplianceRequired ())
-                                       continue;
-
-                               string name = entry.Key;
-                               string basename = name.Substring (name.LastIndexOf ('.') + 1);
-
-                               string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
-                               object found;
-                               if (!base_members.TryGetValue (lcase, out found)) {
-                                       if (!this_members.TryGetValue (lcase, out found)) {
-                                               this_members.Add (lcase, mc);
-                                               continue;
-                                       }
-                               }
+                       // Check this name against other containers
+                       NamespaceEntry.NS.VerifyClsCompliance ();
 
-                               if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
-                                       continue;                                       
-
-                               if (found is MemberInfo) {
-                                       if (basename == ((MemberInfo) found).Name)
-                                               continue;
-                                       Report.SymbolRelatedToPreviousError ((MemberInfo) found);
-                               } else {
-                                       Report.SymbolRelatedToPreviousError ((MemberCore) found);
-                               }
+                       // Check all container names for user classes
+                       if (Kind != MemberKind.Delegate)
+                               MemberCache.VerifyClsCompliance (Definition, Report);
 
-                               Report.Warning (3005, 1, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
+                       if (BaseType != null && !BaseType.IsCLSCompliant ()) {
+                               Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
+                                       GetSignatureForError (), BaseType.GetSignatureForError ());
                        }
+                       return true;
                }
 
-
                /// <summary>
                ///   Performs checks for an explicit interface implementation.  First it
                ///   checks whether the `interface_type' is a base inteface implementation.
@@ -2423,8 +1938,9 @@ namespace Mono.CSharp {
                /// </summary>
                public bool VerifyImplements (InterfaceMemberBase mb)
                {
+                       var ifaces = spec.Interfaces;
                        if (ifaces != null) {
-                               foreach (Type t in ifaces){
+                               foreach (TypeSpec t in ifaces){
                                        if (TypeManager.IsEqual (t, mb.InterfaceType))
                                                return true;
                                }
@@ -2436,20 +1952,30 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public override Type LookupAnyGeneric (string typeName)
+               //
+               // Used for visiblity checks to tests whether this definition shares
+               // base type baseType, it does member-definition search
+               //
+               public bool IsBaseTypeDefinition (TypeSpec baseType)
                {
-                       if (types != null) {
-                               foreach (TypeContainer tc in types) {
-                                       if (!tc.IsGeneric)
-                                               continue;
+                       // RootContext check
+                       if (TypeBuilder == null)
+                               return false;
 
-                                       int pos = tc.Basename.LastIndexOf ('`');
-                                       if (pos == typeName.Length && String.Compare (typeName, 0, tc.Basename, 0, pos) == 0)
-                                               return tc.TypeBuilder;
-                               }
-                       }
+                       var type = spec;
+                       do {
+                               if (type.MemberDefinition == baseType.MemberDefinition)
+                                       return true;
+
+                               type = type.BaseType;
+                       } while (type != null);
+
+                       return false;
+               }
 
-                       return base.LookupAnyGeneric (typeName);
+               public MemberCache LoadMembers (TypeSpec declaringType)
+               {
+                       throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
                }
 
                public void Mark_HasEquals ()
@@ -2492,39 +2018,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               //
-               // IMemberContainer
-               //
-
-               string IMemberContainer.Name {
-                       get {
-                               return Name;
-                       }
-               }
-
-               Type IMemberContainer.Type {
-                       get {
-                               return TypeBuilder;
-                       }
-               }
-
-               bool IMemberContainer.IsInterface {
-                       get {
-                               return Kind == MemberKind.Interface;
-                       }
-               }
-
-               MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
-               {
-                       BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
-
-                       if (GenericType != null)
-                               return TypeManager.FindMembers (GenericType, mt, new_bf,
-                                                               null, null);
-                       else
-                               return FindMembers (mt, new_bf, null, null);
-               }
-
                //
                // Generates xml doc comments (if any), and if required,
                // handle warning report.
@@ -2537,18 +2030,6 @@ namespace Mono.CSharp {
                public override string DocCommentHeader {
                        get { return "T:"; }
                }
-
-               public MemberCache BaseCache {
-                       get {
-                               if (base_cache != null)
-                                       return base_cache;
-                               if (TypeBuilder.BaseType != null)
-                                       base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
-                               if (TypeBuilder.IsInterface)
-                                       base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
-                               return base_cache;
-                       }
-               }
        }
 
        public abstract class ClassOrStruct : TypeContainer
@@ -2597,7 +2078,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.IsValidSecurityAttribute ()) {
                                if (declarative_security == null)
@@ -2675,19 +2156,19 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+               public override ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
                {
                        DeclSpace top_level = Parent;
                        if (top_level != null) {
                                while (top_level.Parent != null)
                                        top_level = top_level.Parent;
 
-                               var candidates = NamespaceEntry.NS.LookupExtensionMethod (extensionType, this, name);
+                               var candidates = NamespaceEntry.NS.LookupExtensionMethod (extensionType, this, name, arity);
                                if (candidates != null)
                                        return new ExtensionMethodGroupExpr (candidates, NamespaceEntry, extensionType, loc);
                        }
 
-                       return NamespaceEntry.LookupExtensionMethod (extensionType, name, loc);
+                       return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity, loc);
                }
 
                protected override TypeAttributes TypeAttr {
@@ -2720,8 +2201,9 @@ namespace Mono.CSharp {
                              Attributes attrs)
                        : base (ns, parent, name, attrs, MemberKind.Class)
                {
-                       var accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
+                       var accmods = (Parent == null || Parent.Parent == null) ? Modifiers.INTERNAL : Modifiers.PRIVATE;
                        this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
+                       spec = new TypeSpec (Kind, null, this, null, ModFlags);
 
                        if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
                                Report.FeatureIsNotAvailable (Location, "static classes");
@@ -2736,16 +2218,15 @@ namespace Mono.CSharp {
                        base.AddBasesForPart (part, bases);
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.AttributeUsage) {
-                               if (!TypeManager.IsAttributeType (BaseType) &&
-                                       TypeBuilder.FullName != "System.Attribute") {
+                               if (!BaseType.IsAttribute && spec != TypeManager.attribute_type) {
                                        Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
                                }
                        }
 
-                       if (a.Type == pa.Conditional && !TypeManager.IsAttributeType (BaseType)) {
+                       if (a.Type == pa.Conditional && !BaseType.IsAttribute) {
                                Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
                                return;
                        }
@@ -2760,7 +2241,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (AttributeTester.IsAttributeExcluded (a.Type, Location))
+                       if (a.Type.IsConditionallyExcluded (Location))
                                return;
 
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
@@ -2807,7 +2288,7 @@ namespace Mono.CSharp {
                                }
 
                                Method method = m as Method;
-                               if (method != null && method.Parameters.HasExtensionMethodType) {
+                               if (method != null && method.ParameterInfo.HasExtensionMethodType) {
                                        Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static", m.GetSignatureForError ());
                                        continue;
                                }
@@ -2847,51 +2328,44 @@ namespace Mono.CSharp {
                        TypeExpr[] ifaces = base.ResolveBaseTypes (out base_class);
 
                        if (base_class == null) {
-                               if (RootContext.StdLib)
-                                       base_class = TypeManager.system_object_expr;
-                               else if (Name != "System.Object")
+                               if (spec != TypeManager.object_type)
                                        base_class = TypeManager.system_object_expr;
                        } else {
-                               if (Kind == MemberKind.Class && TypeManager.IsGenericParameter (base_class.Type)){
-                                       Report.Error (
-                                               689, base_class.Location,
-                                               "Cannot derive from `{0}' because it is a type parameter",
-                                               base_class.GetSignatureForError ());
-                                       return ifaces;
-                               }
+                               var base_type = base_class.Type;
 
-                               if (IsGeneric && TypeManager.IsAttributeType (base_class.Type)) {
+                               if (base_type.IsGenericParameter){
+                                       Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
+                                               GetSignatureForError (), base_type.GetSignatureForError ());
+                               } else if (IsGeneric && base_type.IsAttribute) {
                                        Report.Error (698, base_class.Location,
                                                "A generic type cannot derive from `{0}' because it is an attribute class",
                                                base_class.GetSignatureForError ());
-                               }
-
-                               if (base_class.IsSealed){
+                               } else if (base_type.IsStatic) {
                                        Report.SymbolRelatedToPreviousError (base_class.Type);
-                                       if (base_class.Type.IsAbstract) {
-                                               Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
-                                                       GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
-                                       } else {
-                                               Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
-                                                       GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
-                                       }
-                                       return ifaces;
+                                       Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
+                                               GetSignatureForError (), base_type.GetSignatureForError ());
+                               } else if (base_type.IsSealed){
+                                       Report.SymbolRelatedToPreviousError (base_class.Type);
+                                       Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
+                                               GetSignatureForError (), base_type.GetSignatureForError ());
                                }
 
-                               if (!base_class.CanInheritFrom ()){
+                               if (base_type is PredefinedTypeSpec && !(spec is PredefinedTypeSpec) &&
+                                       (base_type == TypeManager.enum_type || base_type == TypeManager.value_type || base_type == TypeManager.multicast_delegate_type ||
+                                       base_type == TypeManager.delegate_type || base_type == TypeManager.array_type)) {
                                        Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
-                                               GetSignatureForError (), base_class.GetSignatureForError ());
-                                       return ifaces;
+                                               GetSignatureForError (), base_type.GetSignatureForError ());
+                                       base_class = TypeManager.system_object_expr;
                                }
 
-                               if (!IsAccessibleAs (base_class.Type)) {
-                                       Report.SymbolRelatedToPreviousError (base_class.Type);
-                                       Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'", 
-                                               TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
+                               if (!IsAccessibleAs (base_type)) {
+                                       Report.SymbolRelatedToPreviousError (base_type);
+                                       Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
+                                               base_type.GetSignatureForError (), GetSignatureForError ());
                                }
                        }
 
-                       if (PartialContainer.IsStaticClass) {
+                       if (PartialContainer.IsStatic) {
                                if (base_class.Type != TypeManager.object_type) {
                                        Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
                                                GetSignatureForError (), base_class.GetSignatureForError ());
@@ -2910,28 +2384,26 @@ namespace Mono.CSharp {
 
                /// Search for at least one defined condition in ConditionalAttribute of attribute class
                /// Valid only for attribute classes.
-               public bool IsExcluded ()
+               public override string[] ConditionalConditions ()
                {
-                       if ((caching_flags & Flags.Excluded_Undetected) == 0)
-                               return (caching_flags & Flags.Excluded) != 0;
+                       if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
+                               return null;
 
                        caching_flags &= ~Flags.Excluded_Undetected;
 
                        if (OptAttributes == null)
-                               return false;
+                               return null;
 
                        Attribute[] attrs = OptAttributes.SearchMulti (PredefinedAttributes.Get.Conditional);
                        if (attrs == null)
-                               return false;
+                               return null;
 
-                       foreach (Attribute a in attrs) {
-                               string condition = a.GetConditionalAttributeValue ();
-                               if (Location.CompilationUnit.IsConditionalDefined (condition))
-                                       return false;
-                       }
+                       string[] conditions = new string[attrs.Length];
+                       for (int i = 0; i < conditions.Length; ++i)
+                               conditions[i] = attrs[i].GetConditionalAttributeValue ();
 
                        caching_flags |= Flags.Excluded;
-                       return true;
+                       return conditions;
                }
 
                //
@@ -2951,6 +2423,7 @@ namespace Mono.CSharp {
        public sealed class Struct : ClassOrStruct {
 
                bool is_unmanaged, has_unmanaged_check_done;
+               bool InTransit;
 
                // <summary>
                //   Modifiers allowed in a struct declaration
@@ -2967,14 +2440,18 @@ namespace Mono.CSharp {
                               Modifiers mod, Attributes attrs)
                        : base (ns, parent, name, attrs, MemberKind.Struct)
                {
-                       var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
-                       
-                       this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
+                       var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;                   
+                       this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
+                       spec = new TypeSpec (Kind, null, this, null, ModFlags);
+               }
 
-                       this.ModFlags |= Modifiers.SEALED;
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Struct;
+                       }
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
@@ -2992,10 +2469,61 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override AttributeTargets AttributeTargets {
-                       get {
-                               return AttributeTargets.Struct;
+               bool CheckStructCycles (Struct s)
+               {
+                       if (s.Fields == null)
+                               return true;
+
+                       if (s.InTransit)
+                               return false;
+
+                       s.InTransit = true;
+                       foreach (FieldBase field in s.Fields) {
+                               TypeSpec ftype = field.Spec.MemberType;
+                               if (!ftype.IsStruct)
+                                       continue;
+
+                               if (ftype is PredefinedTypeSpec)
+                                       continue;
+
+                               foreach (var targ in ftype.TypeArguments) {
+                                       if (!CheckFieldTypeCycle (targ)) {
+                                               Report.Error (523, field.Location,
+                                                       "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
+                                                       field.GetSignatureForError (), ftype.GetSignatureForError ());
+                                               break;
+                                       }
+                               }
+
+                               if ((field.IsStatic && !ftype.IsGeneric))
+                                       continue;
+
+                               if (!CheckFieldTypeCycle (ftype)) {
+                                       Report.Error (523, field.Location,
+                                               "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
+                                               field.GetSignatureForError (), ftype.GetSignatureForError ());
+                                       break;
+                               }
                        }
+
+                       s.InTransit = false;
+                       return true;
+               }
+
+               bool CheckFieldTypeCycle (TypeSpec ts)
+               {
+                       var fts = ts.MemberDefinition as Struct;
+                       if (fts == null)
+                               return true;
+
+                       return CheckStructCycles (fts);
+               }
+
+               public override void Emit ()
+               {
+                       CheckStructCycles (this);
+
+                       base.Emit ();
                }
 
                public override bool IsUnmanagedType ()
@@ -3012,12 +2540,12 @@ namespace Mono.CSharp {
                        has_unmanaged_check_done = true;
 
                        foreach (FieldBase f in fields) {
-                               if ((f.ModFlags & Modifiers.STATIC) != 0)
+                               if (f.IsStatic)
                                        continue;
 
                                // It can happen when recursive unmanaged types are defined
                                // struct S { S* s; }
-                               Type mt = f.MemberType;
+                               TypeSpec mt = f.MemberType;
                                if (mt == null) {
                                        has_unmanaged_check_done = false;
                                        requires_delayed_unmanagedtype_check = true;
@@ -3027,8 +2555,14 @@ namespace Mono.CSharp {
                                // TODO: Remove when pointer types are under mcs control
                                while (mt.IsPointer)
                                        mt = TypeManager.GetElementType (mt);
-                               if (TypeManager.IsEqual (mt, TypeBuilder))
+
+                               if (mt.MemberDefinition == this) {
+                                       for (var p = Parent; p != null; p = p.Parent) {
+                                               if (p.Kind == MemberKind.Class)
+                                                       return false;
+                                       }
                                        continue;
+                               }
 
                                if (TypeManager.IsUnmanagedType (mt))
                                        continue;
@@ -3043,26 +2577,10 @@ namespace Mono.CSharp {
                protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
                {
                        TypeExpr[] ifaces = base.ResolveBaseTypes (out base_class);
-                       //
-                       // If we are compiling our runtime,
-                       // and we are defining ValueType, then our
-                       // base is `System.Object'.
-                       //
-                       if (base_class == null) {
-                               if (!RootContext.StdLib && Name == "System.ValueType")
-                                       base_class = TypeManager.system_object_expr;
-                               else
-                                       base_class = TypeManager.system_valuetype_expr;
-                       }
-
+                       base_class = TypeManager.system_valuetype_expr;
                        return ifaces;
                }
 
-               //
-               // FIXME: Allow the user to specify a different set of attributes
-               // in some cases (Sealed for example is mandatory for a class,
-               // but what SequentialLayout can be changed
-               //
                protected override TypeAttributes TypeAttr {
                        get {
                                const TypeAttributes DefaultTypeAttributes =
@@ -3088,7 +2606,7 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Interfaces
        /// </summary>
-       public sealed class Interface : TypeContainer, IMemberContainer {
+       public sealed class Interface : TypeContainer {
 
                /// <summary>
                ///   Modifiers allowed in a class declaration
@@ -3108,9 +2626,10 @@ namespace Mono.CSharp {
                        var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
 
                        this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
+                       spec = new TypeSpec (Kind, null, this, null, ModFlags);
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
                                a.Error_MissingGuidAttribute ();
@@ -3143,14 +2662,14 @@ namespace Mono.CSharp {
                        if (!base.VerifyClsCompliance ())
                                return false;
 
-                       if (ifaces != null) {
-                               foreach (Type t in ifaces) {
-                                       if (AttributeTester.IsClsCompliant (t))
+                       if (iface_exprs != null) {
+                               foreach (var iface in iface_exprs) {
+                                       if (iface.Type.IsCLSCompliant ())
                                                continue;
 
-                                       Report.SymbolRelatedToPreviousError (t);
+                                       Report.SymbolRelatedToPreviousError (iface.Type);
                                        Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
-                                               GetSignatureForError (), TypeManager.CSharpName (t));
+                                               GetSignatureForError (), TypeManager.CSharpName (iface.Type));
                                }
                        }
 
@@ -3174,12 +2693,12 @@ namespace Mono.CSharp {
                //
                // The interface type we are explicitly implementing
                //
-               public Type InterfaceType;
+               public TypeSpec InterfaceType;
 
                //
                // The method we're overriding if this is an override method.
                //
-               protected MethodInfo base_method;
+               protected MethodSpec base_method;
 
                readonly Modifiers explicit_mod_flags;
                public MethodAttributes flags;
@@ -3203,75 +2722,92 @@ namespace Mono.CSharp {
                        if ((caching_flags & Flags.MethodOverloadsExist) != 0)
                                CheckForDuplications ();
                        
-                       if (IsExplicitImpl || this is Destructor)
+                       if (IsExplicitImpl)
                                return true;
 
-                       // Is null for System.Object while compiling corlib and base interfaces
-                       if (Parent.PartialContainer.BaseCache == null) {
-                               if ((ModFlags & Modifiers.NEW) != 0) {
-                                       Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
-                               }
+                       // For System.Object only
+                       if (Parent.BaseType == null)
                                return true;
-                       }
-
-                       Type base_ret_type = null;
-                       base_method = FindOutBaseMethod (ref base_ret_type);
 
-                       // method is override
-                       if (base_method != null) {
-                               if (!CheckMethodAgainstBase (base_ret_type))
-                                       return false;
+                       MemberSpec candidate;
+                       var base_member = FindBaseMember (out candidate);
 
-                               if ((ModFlags & Modifiers.OVERRIDE) != 0) {
-                                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
-                                       if (oa != null) {
-                                               if (OptAttributes == null || !OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
-                                                       Report.SymbolRelatedToPreviousError (base_method);
-                                                               Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
-                                                                       GetSignatureForError (), TypeManager.CSharpSignature (base_method));
+                       if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+                               if (base_member == null) {
+                                       if (candidate == null) {
+                                               if (this is Method && ((Method)this).ParameterInfo.IsEmpty && MemberName.Name == Destructor.MetadataName && MemberName.Arity == 0) {
+                                                       Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
+                                                               "object.Finalize()");
+                                               } else {
+                                                       Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
+                                                               GetSignatureForError (), SimpleName.GetMemberType (this));
                                                }
                                        } else {
-                                               if (OptAttributes != null && OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
-                                                       Report.SymbolRelatedToPreviousError (base_method);
-                                                       Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
-                                                               GetSignatureForError (), TypeManager.CSharpSignature (base_method));
-                                               }
+                                               Report.SymbolRelatedToPreviousError (candidate);
+                                               if (this is Event)
+                                                       Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event",
+                                                               GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
+                                               else if (this is PropertyBase)
+                                                       Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property",
+                                                               GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
+                                               else
+                                                       Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method",
+                                                               GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
                                        }
+
+                                       return false;
                                }
-                               return true;
-                       }
 
-                       MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, !((this is Event) || (this is Property)));
-                       if ((ModFlags & Modifiers.OVERRIDE) != 0) {
-                               if (conflict_symbol != null) {
-                                       Report.SymbolRelatedToPreviousError (conflict_symbol);
-                                       if (this is Event)
-                                               Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
-                                       else if (this is PropertyBase)
-                                               Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
-                                       else
-                                               Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
+                               if (!CheckOverrideAgainstBase (base_member))
+                                       return false;
+
+                               ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
+                               if (oa != null) {
+                                       if (OptAttributes == null || !OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
+                                               Report.SymbolRelatedToPreviousError (base_member);
+                                               Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
+                                                       GetSignatureForError (), TypeManager.GetFullNameSignature (base_member));
+                                       }
                                } else {
-                                       Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
-                                               GetSignatureForError (), SimpleName.GetMemberType (this));
+                                       if (OptAttributes != null && OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
+                                               Report.SymbolRelatedToPreviousError (base_member);
+                                               Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
+                                                       GetSignatureForError (), TypeManager.GetFullNameSignature (base_member));
+                                       }
                                }
-                               return false;
-                       }
 
-                       if (conflict_symbol == null) {
-                               if ((ModFlags & Modifiers.NEW) != 0) {
-                                       Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
-                               }
+                               base_method = base_member as MethodSpec;
                                return true;
                        }
 
-                       if ((ModFlags & Modifiers.NEW) == 0) {
-                               if (this is MethodOrOperator && conflict_symbol.MemberType == MemberTypes.Method)
-                                       return true;
+                       if (base_member == null && candidate != null && (!(candidate is IParametersMember) || !(this is IParametersMember)))
+                               base_member = candidate;
+
+                       if (base_member == null) {
+                               if ((ModFlags & Modifiers.NEW) != 0) {
+                                       if (base_member == null) {
+                                               Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+                                                       GetSignatureForError ());
+                                       }
+                               }
+                       } else {
+                               if ((ModFlags & Modifiers.NEW) == 0) {
+                                       ModFlags |= Modifiers.NEW;
+                                       Report.SymbolRelatedToPreviousError (base_member);
+                                       if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
+                                               Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
+                                                       GetSignatureForError (), base_member.GetSignatureForError ());
+                                       } else {
+                                               Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
+                                                       GetSignatureForError (), base_member.GetSignatureForError ());
+                                       }
+                               }
 
-                               Report.SymbolRelatedToPreviousError (conflict_symbol);
-                               Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
-                                       GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
+                               if (!IsInterface && base_member.IsAbstract) {
+                                       Report.SymbolRelatedToPreviousError (base_member);
+                                       Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
+                                               GetSignatureForError (), base_member.GetSignatureForError ());
+                               }
                        }
 
                        return true;
@@ -3279,124 +2815,87 @@ namespace Mono.CSharp {
 
                protected virtual bool CheckForDuplications ()
                {
-                       return Parent.MemberCache.CheckExistingMembersOverloads (
-                               this, GetFullName (MemberName), ParametersCompiled.EmptyReadOnlyParameters, Report);
+                       return Parent.MemberCache.CheckExistingMembersOverloads (this, ParametersCompiled.EmptyReadOnlyParameters);
                }
 
                //
                // Performs various checks on the MethodInfo `mb' regarding the modifier flags
                // that have been defined.
                //
-               // `name' is the user visible name for reporting errors (this is used to
-               // provide the right name regarding method names and properties)
-               //
-               bool CheckMethodAgainstBase (Type base_method_type)
+               protected virtual bool CheckOverrideAgainstBase (MemberSpec base_member)
                {
                        bool ok = true;
 
-                       if ((ModFlags & Modifiers.OVERRIDE) != 0){
-                               if (!(base_method.IsAbstract || base_method.IsVirtual)){
-                                       Report.SymbolRelatedToPreviousError (base_method);
-                                       Report.Error (506, Location,
-                                               "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
-                                                GetSignatureForError (), TypeManager.CSharpSignature (base_method));
-                                       ok = false;
-                               }
-                               
-                               // Now we check that the overriden method is not final
-                               
-                               if (base_method.IsFinal) {
-                                       Report.SymbolRelatedToPreviousError (base_method);
-                                       Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
-                                                             GetSignatureForError (), TypeManager.CSharpSignature (base_method));
-                                       ok = false;
-                               }
-                               //
-                               // Check that the permissions are not being changed
-                               //
-                               MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
-                               MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
-
-                               if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
-                                       Error_CannotChangeAccessModifiers (Location, base_method, base_classp, null);
-                                       ok = false;
-                               }
+                       if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE | Modifiers.OVERRIDE_UNCHECKED)) == 0) {
+                               Report.SymbolRelatedToPreviousError (base_member);
+                               Report.Error (506, Location,
+                                       "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
+                                        GetSignatureForError (), TypeManager.CSharpSignature (base_member));
+                               ok = false;
+                       }
 
-                               if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (base_method_type))) {
-                                       Report.SymbolRelatedToPreviousError (base_method);
-                                       if (this is PropertyBasedMember) {
-                                               Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'", 
-                                                       GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
-                                       }
-                                       else {
-                                               Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
-                                                       GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
-                                       }
-                                       ok = false;
-                               }
+                       // Now we check that the overriden method is not final  
+                       if ((base_member.Modifiers & Modifiers.SEALED) != 0) {
+                               Report.SymbolRelatedToPreviousError (base_member);
+                               Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
+                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_member));
+                               ok = false;
                        }
 
-                       if ((ModFlags & Modifiers.NEW) == 0) {
-                               if ((ModFlags & Modifiers.OVERRIDE) == 0) {
-                                       ModFlags |= Modifiers.NEW;
-                                       Report.SymbolRelatedToPreviousError (base_method);
-                                       if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
-                                               Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
-                                                       GetSignatureForError (), TypeManager.CSharpSignature (base_method));
-                                               if (base_method.IsAbstract){
-                                                       Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
-                                                                     GetSignatureForError (), TypeManager.CSharpSignature (base_method));
-                                                       ok = false;
-                                               }
-                                       } else {
-                                               Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
-                                                       GetSignatureForError (), TypeManager.CSharpSignature (base_method));
-                                       }
-                               }
-                       } else {
-                               if (base_method.IsAbstract && !IsInterface) {
-                                       Report.SymbolRelatedToPreviousError (base_method);
-                                       Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
-                                               GetSignatureForError (), TypeManager.CSharpSignature (base_method));
-                                       return ok = false;
+                       var base_member_type = ((IInterfaceMemberSpec) base_member).MemberType;
+                       if (!TypeSpecComparer.Override.IsEqual (MemberType, base_member_type)) {
+                               Report.SymbolRelatedToPreviousError (base_member);
+                               if (this is PropertyBasedMember) {
+                                       Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
+                                               GetSignatureForError (), TypeManager.CSharpName (base_member_type), TypeManager.CSharpSignature (base_member));
+                               } else {
+                                       Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
+                                               GetSignatureForError (), TypeManager.CSharpName (base_member_type), TypeManager.CSharpSignature (base_member));
                                }
+                               ok = false;
                        }
 
                        return ok;
                }
-               
-               protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
+
+               protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member)
                {
-                       if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
+                       var thisp = this_member.ModFlags & Modifiers.AccessibilityMask;
+                       var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
+
+                       if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
                                //
                                // when overriding protected internal, the method can be declared
                                // protected internal only within the same assembly or assembly
                                // which has InternalsVisibleTo
                                //
-                               if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
-                                       return TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, base_method.DeclaringType.Assembly);
-                               } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
+                               if ((thisp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
+                                       return TypeManager.IsThisOrFriendAssembly (this_member.Assembly, base_member.Assembly);
+                               } 
+                               if ((thisp & Modifiers.PROTECTED) != Modifiers.PROTECTED) {
                                        //
                                        // if it's not "protected internal", it must be "protected"
                                        //
 
                                        return false;
-                               } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
+                               }
+                               if (this_member.Parent.PartialContainer.Module.Assembly == base_member.Assembly) {
                                        //
                                        // protected within the same assembly - an error
                                        //
                                        return false;
-                               } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
-                                          (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
+                               }
+                               if ((thisp & ~(Modifiers.PROTECTED | Modifiers.INTERNAL)) !=
+                                          (base_classp & ~(Modifiers.PROTECTED | Modifiers.INTERNAL))) {
                                        //
                                        // protected ok, but other attributes differ - report an error
                                        //
                                        return false;
                                }
                                return true;
-                       } else {
-                               return (thisp == base_classp);
                        }
+
+                       return thisp == base_classp;
                }
 
                public override bool Define ()
@@ -3417,7 +2916,7 @@ namespace Mono.CSharp {
                        }
 
                        if (IsExplicitImpl) {
-                               TypeExpr iface_texpr = MemberName.Left.GetTypeExpression ().ResolveAsTypeTerminal (this, false);
+                               TypeExpr iface_texpr = MemberName.Left.GetTypeExpression ().ResolveAsTypeTerminal (Parent, false);
                                if (iface_texpr == null)
                                        return false;
 
@@ -3457,7 +2956,7 @@ namespace Mono.CSharp {
                                if (p.CheckAccessibility (this))
                                        continue;
 
-                               Type t = parameters.Types [i];
+                               TypeSpec t = parameters.Types [i];
                                Report.SymbolRelatedToPreviousError (t);
                                if (this is Indexer)
                                        Report.Error (55, Location,
@@ -3511,37 +3010,36 @@ namespace Mono.CSharp {
                        return IsExplicitImpl;
                }
 
-               protected void Error_CannotChangeAccessModifiers (Location loc, MemberInfo base_method, MethodAttributes ma, string suffix)
+               protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
                {
-                       Report.SymbolRelatedToPreviousError (base_method);
-                       string base_name = TypeManager.GetFullNameSignature (base_method);
-                       string this_name = GetSignatureForError ();
-                       if (suffix != null) {
-                               base_name += suffix;
-                               this_name += suffix;
-                       }
-
-                       Report.Error (507, loc, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
-                               this_name, ModifiersExtensions.GetDescription (ma), base_name);
+                       Report.SymbolRelatedToPreviousError (base_member);
+                       Report.Error (507, member.Location,
+                               "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
+                               member.GetSignatureForError (),
+                               ModifiersExtensions.AccessibilityName (base_member.Modifiers),
+                               base_member.GetSignatureForError ());
                }
 
-               protected static string Error722 {
-                       get {
-                               return "`{0}': static types cannot be used as return types";
-                       }
+               protected void Error_StaticReturnType ()
+               {
+                       Report.Error (722, Location,
+                               "`{0}': static types cannot be used as return types",
+                               MemberType.GetSignatureForError ());
                }
 
                /// <summary>
                /// Gets base method and its return type
                /// </summary>
-               protected abstract MethodInfo FindOutBaseMethod (ref Type base_ret_type);
+               protected virtual MemberSpec FindBaseMember (out MemberSpec bestCandidate)
+               {
+                       return MemberCache.FindBaseMember (this, out bestCandidate);
+               }
 
                //
                // The "short" name of this property / indexer / event.  This is the
                // name without the explicit interface.
                //
-               public string ShortName 
-               {
+               public string ShortName {
                        get { return MemberName.Name; }
                        set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
                }
@@ -3550,9 +3048,14 @@ namespace Mono.CSharp {
                // Returns full metadata method name
                //
                public string GetFullName (MemberName name)
+               {
+                       return GetFullName (name.Name);
+               }
+
+               public string GetFullName (string name)
                {
                        if (!IsExplicitImpl)
-                               return name.Name;
+                               return name;
 
                        //
                        // When dealing with explicit members a full interface type
@@ -3562,19 +3065,12 @@ namespace Mono.CSharp {
                        // replacing predefined names which saves some space and name
                        // is still unique
                        //
-                       return TypeManager.CSharpName (InterfaceType) + "." + name.Name;
+                       return TypeManager.CSharpName (InterfaceType) + "." + name;
                }
 
                protected override bool VerifyClsCompliance ()
                {
                        if (!base.VerifyClsCompliance ()) {
-                               if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
-                                       Report.Warning (3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
-                               }
-
-                               if ((ModFlags & Modifiers.ABSTRACT) != 0 && Parent.TypeBuilder.IsClass && IsExposedFromAssembly () && Parent.IsClsComplianceRequired ()) {
-                                       Report.Warning (3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
-                               }
                                return false;
                        }
 
@@ -3593,8 +3089,8 @@ namespace Mono.CSharp {
 
        public abstract class MemberBase : MemberCore
        {
-               protected FullNamedExpression type_name;
-               protected Type member_type;
+               protected FullNamedExpression type_expr;
+               protected TypeSpec member_type;
 
                public readonly DeclSpace ds;
                public readonly GenericMethod GenericMethod;
@@ -3605,7 +3101,7 @@ namespace Mono.CSharp {
                        : base (parent, name, attrs)
                {
                        this.ds = generic != null ? generic : (DeclSpace) parent;
-                       this.type_name = type;
+                       this.type_expr = type;
                        ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
                        GenericMethod = generic;
                        if (GenericMethod != null)
@@ -3698,7 +3194,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public Type MemberType {
+               public TypeSpec MemberType {
                        get { return member_type; }
                }
 
@@ -3707,14 +3203,14 @@ namespace Mono.CSharp {
                        if (member_type != null)
                                throw new InternalErrorException ("Multi-resolve");
 
-                       TypeExpr te = type_name.ResolveAsTypeTerminal (this, false);
+                       TypeExpr te = type_expr.ResolveAsTypeTerminal (this, false);
                        if (te == null)
                                return false;
                        
                        //
                        // Replace original type name, error reporting can use fully resolved name
                        //
-                       type_name = te;
+                       type_expr = te;
 
                        member_type = te.Type;
                        return true;
index badadb7c8944795bddad577886026f1d9fbb1ee1..d7c7233499ce1be5c8e656c96c8d2a4aeece2624 100644 (file)
@@ -246,20 +246,21 @@ namespace Mono.CSharp {
        /// </summary>
        public class EmitContext : BuilderContext
        {
+               // TODO: Has to be private
                public ILGenerator ig;
 
                /// <summary>
                ///   The value that is allowed to be returned or NULL if there is no
                ///   return type.
                /// </summary>
-               Type return_type;
+               TypeSpec return_type;
 
                /// <summary>
                ///   Keeps track of the Type to LocalBuilder temporary storage created
                ///   to store structures (used to compute the address of the structure
                ///   value on structure method invocations)
                /// </summary>
-               Dictionary<Type, object> temporary_storage;
+               Dictionary<TypeSpec, object> temporary_storage;
 
                /// <summary>
                ///   The location where we store the return value.
@@ -277,6 +278,22 @@ namespace Mono.CSharp {
                /// </summary>
                public bool HasReturnLabel;
 
+               /// <summary>
+               ///   Current loop begin and end labels.
+               /// </summary>
+               public Label LoopBegin, LoopEnd;
+
+               /// <summary>
+               ///   Default target in a switch statement.   Only valid if
+               ///   InSwitch is true
+               /// </summary>
+               public Label DefaultTarget;
+
+               /// <summary>
+               ///   If this is non-null, points to the current switch statement
+               /// </summary>
+               public Switch Switch;
+
                /// <summary>
                ///  Whether we are inside an anonymous method.
                /// </summary>
@@ -284,7 +301,7 @@ namespace Mono.CSharp {
                
                public readonly IMemberContext MemberContext;
 
-               public EmitContext (IMemberContext rc, ILGenerator ig, Type return_type)
+               public EmitContext (IMemberContext rc, ILGenerator ig, TypeSpec return_type)
                {
                        this.MemberContext = rc;
                        this.ig = ig;
@@ -292,7 +309,9 @@ namespace Mono.CSharp {
                        this.return_type = return_type;
                }
 
-               public Type CurrentType {
+#region Properties
+
+               public TypeSpec CurrentType {
                        get { return MemberContext.CurrentType; }
                }
 
@@ -300,24 +319,33 @@ namespace Mono.CSharp {
                        get { return MemberContext.CurrentTypeParameters; }
                }
 
-               public TypeContainer CurrentTypeDefinition {
-                       get { return MemberContext.CurrentTypeDefinition; }
+               public MemberCore CurrentTypeDefinition {
+                       get { return MemberContext.CurrentMemberDefinition; }
                }
 
                public bool IsStatic {
                        get { return MemberContext.IsStatic; }
                }
 
+               bool IsAnonymousStoreyMutateRequired {
+                       get {
+                               return CurrentAnonymousMethod != null &&
+                                       CurrentAnonymousMethod.Storey != null &&
+                                       CurrentAnonymousMethod.Storey.Mutator != null;
+                       }
+               }
+
                // Has to be used for emitter errors only
                public Report Report {
                        get { return MemberContext.Compiler.Report; }
                }
 
-               public Type ReturnType {
+               public TypeSpec ReturnType {
                        get {
                                return return_type;
                        }
                }
+#endregion
 
                /// <summary>
                ///   This is called immediately before emitting an IL opcode to tell the symbol
@@ -336,23 +364,398 @@ namespace Mono.CSharp {
                        SymbolWriter.DefineLocalVariable (name, builder);
                }
 
+               public void BeginCatchBlock (TypeSpec type)
+               {
+                       ig.BeginCatchBlock (type.GetMetaInfo ());
+               }
+
+               public void BeginExceptionBlock ()
+               {
+                       ig.BeginExceptionBlock ();
+               }
+
+               public void BeginFinallyBlock ()
+               {
+                       ig.BeginFinallyBlock ();
+               }
+
                public void BeginScope ()
                {
                        ig.BeginScope();
                        SymbolWriter.OpenScope(ig);
                }
 
+               public void EndExceptionBlock ()
+               {
+                       ig.EndExceptionBlock ();
+               }
+
                public void EndScope ()
                {
                        ig.EndScope();
                        SymbolWriter.CloseScope(ig);
                }
 
+               public LocalBuilder DeclareLocal (TypeSpec type, bool pinned)
+               {
+                       if (IsAnonymousStoreyMutateRequired)
+                               type = CurrentAnonymousMethod.Storey.Mutator.Mutate (type);
+
+                       return ig.DeclareLocal (type.GetMetaInfo (), pinned);
+               }
+
+               public Label DefineLabel ()
+               {
+                       return ig.DefineLabel ();
+               }
+
+               public void MarkLabel (Label label)
+               {
+                       ig.MarkLabel (label);
+               }
+
+               public void Emit (OpCode opcode)
+               {
+                       ig.Emit (opcode);
+               }
+
+               public void Emit (OpCode opcode, LocalBuilder local)
+               {
+                       ig.Emit (opcode, local);
+               }
+
+               public void Emit (OpCode opcode, string arg)
+               {
+                       ig.Emit (opcode, arg);
+               }
+
+               public void Emit (OpCode opcode, double arg)
+               {
+                       ig.Emit (opcode, arg);
+               }
+
+               public void Emit (OpCode opcode, float arg)
+               {
+                       ig.Emit (opcode, arg);
+               }
+
+               public void Emit (OpCode opcode, int arg)
+               {
+                       ig.Emit (opcode, arg);
+               }
+
+               public void Emit (OpCode opcode, byte arg)
+               {
+                       ig.Emit (opcode, arg);
+               }
+
+               public void Emit (OpCode opcode, Label label)
+               {
+                       ig.Emit (opcode, label);
+               }
+
+               public void Emit (OpCode opcode, Label[] labels)
+               {
+                       ig.Emit (opcode, labels);
+               }
+
+               public void Emit (OpCode opcode, TypeSpec type)
+               {
+                       if (IsAnonymousStoreyMutateRequired)
+                               type = CurrentAnonymousMethod.Storey.Mutator.Mutate (type);
+
+                       ig.Emit (opcode, type.GetMetaInfo ());
+               }
+
+               public void Emit (OpCode opcode, FieldSpec field)
+               {
+                       if (IsAnonymousStoreyMutateRequired)
+                               field = field.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+                       ig.Emit (opcode, field.GetMetaInfo ());
+               }
+
+               public void Emit (OpCode opcode, MethodSpec method)
+               {
+                       if (IsAnonymousStoreyMutateRequired)
+                               method = method.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+                       if (method.IsConstructor)
+                               ig.Emit (opcode, (ConstructorInfo) method.GetMetaInfo ());
+                       else
+                               ig.Emit (opcode, (MethodInfo) method.GetMetaInfo ());
+               }
+
+               // TODO: REMOVE breaks mutator
+               public void Emit (OpCode opcode, MethodInfo method)
+               {
+                       ig.Emit (opcode, method);
+               }
+
+               // TODO: REMOVE breaks mutator
+               public void Emit (OpCode opcode, FieldBuilder field)
+               {
+                       ig.Emit (opcode, field);
+               }
+
+               public void Emit (OpCode opcode, MethodSpec method, Type[] vargs)
+               {
+                       // TODO MemberCache: This should mutate too
+                       ig.EmitCall (opcode, (MethodInfo) method.GetMetaInfo (), vargs);
+               }
+
+               public void EmitArrayNew (ArrayContainer ac)
+               {
+                       if (ac.Rank == 1) {
+                               Emit (OpCodes.Newarr, ac.Element);
+                       } else {
+                               if (IsAnonymousStoreyMutateRequired)
+                                       ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+                               ig.Emit (OpCodes.Newobj, ac.GetConstructor ());
+                       }
+               }
+
+               //
+               // Emits the right opcode to load from an array
+               //
+               public void EmitArrayLoad (ArrayContainer ac)
+               {
+                       if (ac.Rank > 1) {
+                               if (IsAnonymousStoreyMutateRequired)
+                                       ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+                               ig.Emit (OpCodes.Call, ac.GetGetMethod ());
+                               return;
+                       }
+
+                       var type = ac.Element;
+                       if (TypeManager.IsEnumType (type))
+                               type = EnumSpec.GetUnderlyingType (type);
+
+                       if (type == TypeManager.byte_type || type == TypeManager.bool_type)
+                               Emit (OpCodes.Ldelem_U1);
+                       else if (type == TypeManager.sbyte_type)
+                               Emit (OpCodes.Ldelem_I1);
+                       else if (type == TypeManager.short_type)
+                               Emit (OpCodes.Ldelem_I2);
+                       else if (type == TypeManager.ushort_type || type == TypeManager.char_type)
+                               Emit (OpCodes.Ldelem_U2);
+                       else if (type == TypeManager.int32_type)
+                               Emit (OpCodes.Ldelem_I4);
+                       else if (type == TypeManager.uint32_type)
+                               Emit (OpCodes.Ldelem_U4);
+                       else if (type == TypeManager.uint64_type)
+                               Emit (OpCodes.Ldelem_I8);
+                       else if (type == TypeManager.int64_type)
+                               Emit (OpCodes.Ldelem_I8);
+                       else if (type == TypeManager.float_type)
+                               Emit (OpCodes.Ldelem_R4);
+                       else if (type == TypeManager.double_type)
+                               Emit (OpCodes.Ldelem_R8);
+                       else if (type == TypeManager.intptr_type)
+                               Emit (OpCodes.Ldelem_I);
+                       else if (TypeManager.IsStruct (type)) {
+                               Emit (OpCodes.Ldelema, type);
+                               Emit (OpCodes.Ldobj, type);
+                       } else if (type.IsGenericParameter) {
+                               Emit (OpCodes.Ldelem, type);
+                       } else if (type.IsPointer)
+                               Emit (OpCodes.Ldelem_I);
+                       else
+                               Emit (OpCodes.Ldelem_Ref);
+               }
+
+               //
+               // Emits the right opcode to store to an array
+               //
+               public void EmitArrayStore (ArrayContainer ac)
+               {
+                       if (ac.Rank > 1) {
+                               if (IsAnonymousStoreyMutateRequired)
+                                       ac = (ArrayContainer) ac.Mutate (CurrentAnonymousMethod.Storey.Mutator);
+
+                               ig.Emit (OpCodes.Call, ac.GetSetMethod ());
+                               return;
+                       }
+
+                       var type = ac.Element;
+
+                       if (type.IsEnum)
+                               type = EnumSpec.GetUnderlyingType (type);
+
+                       if (type == TypeManager.byte_type || type == TypeManager.sbyte_type || type == TypeManager.bool_type)
+                               Emit (OpCodes.Stelem_I1);
+                       else if (type == TypeManager.short_type || type == TypeManager.ushort_type || type == TypeManager.char_type)
+                               Emit (OpCodes.Stelem_I2);
+                       else if (type == TypeManager.int32_type || type == TypeManager.uint32_type)
+                               Emit (OpCodes.Stelem_I4);
+                       else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)
+                               Emit (OpCodes.Stelem_I8);
+                       else if (type == TypeManager.float_type)
+                               Emit (OpCodes.Stelem_R4);
+                       else if (type == TypeManager.double_type)
+                               Emit (OpCodes.Stelem_R8);
+                       else if (type == TypeManager.intptr_type)
+                               Emit (OpCodes.Stobj, type);
+                       else if (TypeManager.IsStruct (type))
+                               Emit (OpCodes.Stobj, type);
+                       else if (type.IsGenericParameter)
+                               Emit (OpCodes.Stelem, type);
+                       else if (type.IsPointer)
+                               Emit (OpCodes.Stelem_I);
+                       else
+                               Emit (OpCodes.Stelem_Ref);
+               }
+
+               public void EmitInt (int i)
+               {
+                       switch (i) {
+                       case -1:
+                               ig.Emit (OpCodes.Ldc_I4_M1);
+                               break;
+
+                       case 0:
+                               ig.Emit (OpCodes.Ldc_I4_0);
+                               break;
+
+                       case 1:
+                               ig.Emit (OpCodes.Ldc_I4_1);
+                               break;
+
+                       case 2:
+                               ig.Emit (OpCodes.Ldc_I4_2);
+                               break;
+
+                       case 3:
+                               ig.Emit (OpCodes.Ldc_I4_3);
+                               break;
+
+                       case 4:
+                               ig.Emit (OpCodes.Ldc_I4_4);
+                               break;
+
+                       case 5:
+                               ig.Emit (OpCodes.Ldc_I4_5);
+                               break;
+
+                       case 6:
+                               ig.Emit (OpCodes.Ldc_I4_6);
+                               break;
+
+                       case 7:
+                               ig.Emit (OpCodes.Ldc_I4_7);
+                               break;
+
+                       case 8:
+                               ig.Emit (OpCodes.Ldc_I4_8);
+                               break;
+
+                       default:
+                               if (i >= -128 && i <= 127) {
+                                       ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
+                               } else
+                                       ig.Emit (OpCodes.Ldc_I4, i);
+                               break;
+                       }
+               }
+
+               public void EmitLong (long l)
+               {
+                       if (l >= int.MinValue && l <= int.MaxValue) {
+                               EmitInt (unchecked ((int) l));
+                               ig.Emit (OpCodes.Conv_I8);
+                               return;
+                       }
+
+                       if (l >= 0 && l <= uint.MaxValue) {
+                               EmitInt (unchecked ((int) l));
+                               ig.Emit (OpCodes.Conv_U8);
+                               return;
+                       }
+
+                       ig.Emit (OpCodes.Ldc_I8, l);
+               }
+
+               //
+               // Load the object from the pointer.  
+               //
+               public void EmitLoadFromPtr (TypeSpec t)
+               {
+                       if (t == TypeManager.int32_type)
+                               ig.Emit (OpCodes.Ldind_I4);
+                       else if (t == TypeManager.uint32_type)
+                               ig.Emit (OpCodes.Ldind_U4);
+                       else if (t == TypeManager.short_type)
+                               ig.Emit (OpCodes.Ldind_I2);
+                       else if (t == TypeManager.ushort_type)
+                               ig.Emit (OpCodes.Ldind_U2);
+                       else if (t == TypeManager.char_type)
+                               ig.Emit (OpCodes.Ldind_U2);
+                       else if (t == TypeManager.byte_type)
+                               ig.Emit (OpCodes.Ldind_U1);
+                       else if (t == TypeManager.sbyte_type)
+                               ig.Emit (OpCodes.Ldind_I1);
+                       else if (t == TypeManager.uint64_type)
+                               ig.Emit (OpCodes.Ldind_I8);
+                       else if (t == TypeManager.int64_type)
+                               ig.Emit (OpCodes.Ldind_I8);
+                       else if (t == TypeManager.float_type)
+                               ig.Emit (OpCodes.Ldind_R4);
+                       else if (t == TypeManager.double_type)
+                               ig.Emit (OpCodes.Ldind_R8);
+                       else if (t == TypeManager.bool_type)
+                               ig.Emit (OpCodes.Ldind_I1);
+                       else if (t == TypeManager.intptr_type)
+                               ig.Emit (OpCodes.Ldind_I);
+                       else if (t.IsEnum) {
+                               if (t == TypeManager.enum_type)
+                                       ig.Emit (OpCodes.Ldind_Ref);
+                               else
+                                       EmitLoadFromPtr (EnumSpec.GetUnderlyingType (t));
+                       } else if (TypeManager.IsStruct (t) || TypeManager.IsGenericParameter (t))
+                               Emit (OpCodes.Ldobj, t);
+                       else if (t.IsPointer)
+                               ig.Emit (OpCodes.Ldind_I);
+                       else
+                               ig.Emit (OpCodes.Ldind_Ref);
+               }
+
+               //
+               // The stack contains the pointer and the value of type `type'
+               //
+               public void EmitStoreFromPtr (TypeSpec type)
+               {
+                       if (type.IsEnum)
+                               type = EnumSpec.GetUnderlyingType (type);
+
+                       if (type == TypeManager.int32_type || type == TypeManager.uint32_type)
+                               ig.Emit (OpCodes.Stind_I4);
+                       else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)
+                               ig.Emit (OpCodes.Stind_I8);
+                       else if (type == TypeManager.char_type || type == TypeManager.short_type ||
+                                type == TypeManager.ushort_type)
+                               ig.Emit (OpCodes.Stind_I2);
+                       else if (type == TypeManager.float_type)
+                               ig.Emit (OpCodes.Stind_R4);
+                       else if (type == TypeManager.double_type)
+                               ig.Emit (OpCodes.Stind_R8);
+                       else if (type == TypeManager.byte_type || type == TypeManager.sbyte_type ||
+                                type == TypeManager.bool_type)
+                               ig.Emit (OpCodes.Stind_I1);
+                       else if (type == TypeManager.intptr_type)
+                               ig.Emit (OpCodes.Stind_I);
+                       else if (TypeManager.IsStruct (type) || TypeManager.IsGenericParameter (type))
+                               ig.Emit (OpCodes.Stobj, type.GetMetaInfo ());
+                       else
+                               ig.Emit (OpCodes.Stind_Ref);
+               }
+
                /// <summary>
                ///   Returns a temporary storage for a variable of type t as 
                ///   a local variable in the current body.
                /// </summary>
-               public LocalBuilder GetTemporaryLocal (Type t)
+               public LocalBuilder GetTemporaryLocal (TypeSpec t)
                {
                        if (temporary_storage != null) {
                                object o;
@@ -367,13 +770,13 @@ namespace Mono.CSharp {
                                if (o != null)
                                        return (LocalBuilder) o;
                        }
-                       return ig.DeclareLocal (TypeManager.TypeToReflectionType (t));
+                       return DeclareLocal (t, false);
                }
 
-               public void FreeTemporaryLocal (LocalBuilder b, Type t)
+               public void FreeTemporaryLocal (LocalBuilder b, TypeSpec t)
                {
                        if (temporary_storage == null) {
-                               temporary_storage = new Dictionary<Type, object> (ReferenceEquality<Type>.Default);
+                               temporary_storage = new Dictionary<TypeSpec, object> (ReferenceEquality<TypeSpec>.Default);
                                temporary_storage.Add (t, b);
                                return;
                        }
@@ -392,22 +795,6 @@ namespace Mono.CSharp {
                        s.Push (b);
                }
 
-               /// <summary>
-               ///   Current loop begin and end labels.
-               /// </summary>
-               public Label LoopBegin, LoopEnd;
-
-               /// <summary>
-               ///   Default target in a switch statement.   Only valid if
-               ///   InSwitch is true
-               /// </summary>
-               public Label DefaultTarget;
-
-               /// <summary>
-               ///   If this is non-null, points to the current switch statement
-               /// </summary>
-               public Switch Switch;
-
                /// <summary>
                ///   ReturnValue creates on demand the LocalBuilder for the
                ///   return value from the function.  By default this is not
@@ -423,9 +810,9 @@ namespace Mono.CSharp {
                public LocalBuilder TemporaryReturn ()
                {
                        if (return_value == null){
-                               return_value = ig.DeclareLocal (return_type);
+                               return_value = DeclareLocal (return_type, false);
                                if (!HasReturnLabel){
-                                       ReturnLabel = ig.DefineLabel ();
+                                       ReturnLabel = DefineLabel ();
                                        HasReturnLabel = true;
                                }
                        }
@@ -471,7 +858,7 @@ namespace Mono.CSharp {
                        get { return RootContext.ToplevelTypes.Compiler; }
                }
 
-               public Type CurrentType {
+               public TypeSpec CurrentType {
                        get { return null; }
                }
 
@@ -479,7 +866,7 @@ namespace Mono.CSharp {
                        get { return null; }
                }
 
-               public TypeContainer CurrentTypeDefinition {
+               public MemberCore CurrentMemberDefinition {
                        get { return RootContext.ToplevelTypes; }
                }
 
@@ -488,6 +875,10 @@ namespace Mono.CSharp {
                        return "<module>";
                }
 
+               public bool HasUnresolvedConstraints {
+                       get { return false; }
+               }
+
                public bool IsObsolete {
                        get { return false; }
                }
@@ -500,14 +891,14 @@ namespace Mono.CSharp {
                        get { return false; }
                }
 
-               public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+               public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
                {
                        throw new NotImplementedException ();
                }
 
-               public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
                {
-                       return RootContext.ToplevelTypes.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                       return RootContext.ToplevelTypes.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
                }
 
                public FullNamedExpression LookupNamespaceAlias (string name)
@@ -530,7 +921,7 @@ namespace Mono.CSharp {
                bool has_extension_method;              
                public AssemblyName Name;
                MethodInfo add_type_forwarder;
-               Dictionary<Type, Attribute> emitted_forwarders;
+               Dictionary<ITypeDefinition, Attribute> emitted_forwarders;
 
                // Module is here just because of error messages
                static string[] attribute_targets = new string [] { "assembly", "module" };
@@ -823,7 +1214,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.IsValidSecurityAttribute ()) {
                                if (declarative_security == null)
@@ -861,32 +1252,31 @@ namespace Mono.CSharp {
                                return;
 
                        if (a.Type == pa.TypeForwarder) {
-                               Type t = a.GetArgumentType ();
+                               TypeSpec t = a.GetArgumentType ();
                                if (t == null || TypeManager.HasElementType (t)) {
                                        Report.Error (735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute");
                                        return;
                                }
 
-                               t = TypeManager.DropGenericTypeArguments (t);
                                if (emitted_forwarders == null) {
-                                       emitted_forwarders = new Dictionary<Type, Attribute>  ();
-                               } else if (emitted_forwarders.ContainsKey (t)) {
-                                       Report.SymbolRelatedToPreviousError(emitted_forwarders[t].Location, null);
+                                       emitted_forwarders = new Dictionary<ITypeDefinition, Attribute>  ();
+                               } else if (emitted_forwarders.ContainsKey (t.MemberDefinition)) {
+                                       Report.SymbolRelatedToPreviousError(emitted_forwarders[t.MemberDefinition].Location, null);
                                        Report.Error(739, a.Location, "A duplicate type forward of type `{0}'",
                                                TypeManager.CSharpName(t));
                                        return;
                                }
 
-                               emitted_forwarders.Add(t, a);
+                               emitted_forwarders.Add(t.MemberDefinition, a);
 
-                               if (TypeManager.LookupDeclSpace (t) != null) {
+                               if (t.Assembly == Builder) {
                                        Report.SymbolRelatedToPreviousError (t);
                                        Report.Error (729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly",
                                                TypeManager.CSharpName (t));
                                        return;
                                }
 
-                               if (t.DeclaringType != null) {
+                               if (t.IsNested) {
                                        Report.Error (730, a.Location, "Cannot forward type `{0}' because it is a nested type",
                                                TypeManager.CSharpName (t));
                                        return;
@@ -902,7 +1292,7 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               add_type_forwarder.Invoke (Builder, new object[] { t });
+                               add_type_forwarder.Invoke (Builder, new object[] { t.GetMetaInfo () });
                                return;
                        }
                        
@@ -911,7 +1301,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       Builder.SetCustomAttribute (ctor, cdata);
+                       Builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
                public override void Emit (TypeContainer tc)
@@ -924,14 +1314,13 @@ namespace Mono.CSharp {
                        // FIXME: Does this belong inside SRE.AssemblyBuilder instead?
                        PredefinedAttribute pa = PredefinedAttributes.Get.RuntimeCompatibility;
                        if (pa.IsDefined && (OptAttributes == null || !OptAttributes.Contains (pa))) {
-                               ConstructorInfo ci = TypeManager.GetPredefinedConstructor (
-                                       pa.Type, Location.Null, Type.EmptyTypes);
+                               var ci = TypeManager.GetPredefinedConstructor (pa.Type, Location.Null, TypeSpec.EmptyTypes);
                                PropertyInfo [] pis = new PropertyInfo [1];
                                pis [0] = TypeManager.GetPredefinedProperty (pa.Type,
                                        "WrapNonExceptionThrows", Location.Null, TypeManager.bool_type).MetaInfo;
                                object [] pargs = new object [1];
                                pargs [0] = true;
-                               Builder.SetCustomAttribute (new CustomAttributeBuilder (ci, new object [0], pis, pargs));
+                               Builder.SetCustomAttribute (new CustomAttributeBuilder ((ConstructorInfo) ci.GetMetaInfo (), new object[0], pis, pargs));
                        }
 
                        if (declarative_security != null) {
@@ -942,7 +1331,7 @@ namespace Mono.CSharp {
                                try {
                                        // Microsoft runtime hacking
                                        if (add_permission == null) {
-                                               Type assembly_builder = typeof (AssemblyBuilder).Assembly.GetType ("System.Reflection.Emit.AssemblyBuilderData");
+                                               var assembly_builder = typeof (AssemblyBuilder).Assembly.GetType ("System.Reflection.Emit.AssemblyBuilderData");
                                                add_permission = assembly_builder.GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic);
 
                                                FieldInfo fi = typeof (AssemblyBuilder).GetField ("m_assemblyData", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
index 36de138c0a78371cb67f92c1908e6576b3bae976..ed2f1ba2a6d369a3e3c6f499b22598285460e034 100644 (file)
@@ -19,6 +19,7 @@ using System.Reflection;
 using System.Reflection.Emit;
 using System.Text;
 using Mono.CSharp.Linq;
+using System.Linq;
 
 namespace Mono.CSharp {
 
@@ -26,7 +27,27 @@ namespace Mono.CSharp {
        // A common base class for Completing expressions, it
        // is just a very simple ExpressionStatement
        //
-       public abstract class CompletingExpression : ExpressionStatement {
+       public abstract class CompletingExpression : ExpressionStatement
+       {
+               public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
+               {
+                       foreach (string name in names) {
+                               if (name == null || prefix == null)
+                                       continue;
+
+                               if (!name.StartsWith (prefix))
+                                       continue;
+
+                               if (results.Contains (name))
+                                       continue;
+
+                               if (prefix != null)
+                                       results.Add (name.Substring (prefix.Length));
+                               else
+                                       results.Add (name);
+                       }
+               }
+
                public override void EmitStatement (EmitContext ec)
                {
                        // Do nothing
@@ -51,33 +72,13 @@ namespace Mono.CSharp {
                        this.loc = l;
                        this.Prefix = prefix;
                }
-
-               public static void AppendResults (List<string> results, string prefix, IEnumerable<string> names)
-               {
-                       foreach (string name in names){
-                               if (name == null || prefix == null)
-                                       continue;
-
-                               if (!name.StartsWith (prefix))
-                                       continue;
-
-                               if (results.Contains (name))
-                                       continue;
-
-                               if (prefix != null)
-                                       results.Add (name.Substring (prefix.Length));
-                               else
-                                       results.Add (name);
-                       }
-
-               }
                
                protected override Expression DoResolve (ResolveContext ec)
                {
                        var results = new List<string> ();
 
                        AppendResults (results, Prefix, Evaluator.GetVarNames ());
-                       AppendResults (results, Prefix, ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (Prefix));
+                       AppendResults (results, Prefix, ec.CurrentMemberDefinition.Parent.NamespaceEntry.CompletionGetTypesStartingWith (Prefix));
                        AppendResults (results, Prefix, Evaluator.GetUsingList ());
                        
                        throw new CompletionResult (Prefix, results.ToArray ());
@@ -93,30 +94,6 @@ namespace Mono.CSharp {
                Expression expr;
                string partial_name;
                TypeArguments targs;
-
-               internal static MemberFilter CollectingFilter = new MemberFilter (Match);
-
-               static bool Match (MemberInfo m, object filter_criteria)
-               {
-                       if (m is FieldInfo){
-                               if (((FieldInfo) m).IsSpecialName)
-                                       return false;
-                               
-                       }
-                       if (m is MethodInfo){
-                               if (((MethodInfo) m).IsSpecialName)
-                                       return false;
-                       }
-
-                       if (filter_criteria == null)
-                               return true;
-                       
-                       string n = (string) filter_criteria;
-                       if (m.Name.StartsWith (n))
-                               return true;
-                       
-                       return false;
-               }
                
                public CompletionMemberAccess (Expression e, string partial_name, Location l)
                {
@@ -142,7 +119,7 @@ namespace Mono.CSharp {
                        if (expr_resolved == null)
                                return null;
 
-                       Type expr_type = expr_resolved.Type;
+                       TypeSpec expr_type = expr_resolved.Type;
                        if (expr_type.IsPointer || expr_type == TypeManager.void_type || expr_type == TypeManager.null_type || expr_type == InternalType.AnonymousMethod) {
                                Unary.Error_OperatorCannotBeApplied (ec, loc, ".", expr_type);
                                return null;
@@ -173,28 +150,10 @@ namespace Mono.CSharp {
                                CompletionSimpleName.AppendResults (
                                        results,
                                        partial_name, 
-                                       ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (namespaced_partial));
+                                       ec.CurrentMemberDefinition.Parent.NamespaceEntry.CompletionGetTypesStartingWith (namespaced_partial));
                        } else {
-                               MemberInfo [] result = expr_type.FindMembers (
-                                       MemberTypes.All, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public,
-                                       CollectingFilter, partial_name);
-
-                               foreach (MemberInfo r in result){
-                                       string name;
-                                       
-                                       MethodBase rasb = r as MethodBase;
-                                       if (rasb != null && rasb.IsSpecialName)
-                                               continue;
-                                       
-                                       if (partial_name == null)
-                                               name = r.Name;
-                                       else 
-                                               name = r.Name.Substring (partial_name.Length);
-                                       
-                                       if (results.Contains (name))
-                                               continue;
-                                       results.Add (name);
-                               }
+                               var r = MemberCache.GetCompletitionMembers (expr_type, partial_name).Select (l => l.Name);
+                               AppendResults (results, partial_name, r);
                        }
 
                        throw new CompletionResult (partial_name == null ? "" : partial_name, results.ToArray ());
@@ -222,29 +181,20 @@ namespace Mono.CSharp {
                
                protected override Expression DoResolve (ResolveContext ec)
                {
-                       MemberList members = TypeManager.FindMembers (
-                               ec.CurrentInitializerVariable.Type,
-                               MemberTypes.Field | MemberTypes.Property,
-                               BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public,
-                               CompletionMemberAccess.CollectingFilter, partial_name);
+                       var members = MemberCache.GetCompletitionMembers (ec.CurrentInitializerVariable.Type, partial_name);
 
-                       string [] result = new string [members.Count];
-                       int i = 0;
-                       foreach (MemberInfo mi in members){
-                               string name;
-                               
-                               if (partial_name == null)
-                                       name = mi.Name;
-                               else
-                                       name = mi.Name.Substring (partial_name.Length);
-                               
-                               result [i++] = name;
+// TODO: Does this mean exact match only ?
+//                     if (partial_name != null && results.Count > 0 && result [0] == "")
+//                             throw new CompletionResult ("", new string [] { "=" });
+
+                       var results = members.Where (l => (l.Kind & (MemberKind.Field | MemberKind.Property)) != 0).Select (l => l.Name).ToList ();
+                       if (partial_name != null) {
+                               var temp = new List<string> ();
+                               AppendResults (temp, partial_name, results);
+                               results = temp;
                        }
 
-                       if (partial_name != null && i > 0 && result [0] == "")
-                               throw new CompletionResult ("", new string [] { "=" });
-                       
-                       throw new CompletionResult (partial_name == null ? "" : partial_name, result);
+                       throw new CompletionResult (partial_name == null ? "" : partial_name, results.ToArray ());
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
index f25e56843da5450537ad30fd6f56b044ad265b0f..6b502c04f2b2986eb189a973afd4b72362c157ae 100644 (file)
@@ -17,7 +17,7 @@ namespace Mono.CSharp {
 
        public class Const : FieldBase
        {
-               bool define_called;
+               Constant value;
 
                public const Modifiers AllowedModifiers =
                        Modifiers.NEW |
@@ -37,34 +37,16 @@ namespace Mono.CSharp {
                        ModFlags |= Modifiers.STATIC;
                }
 
-               protected override bool CheckBase ()
-               {
-                       // Constant.Define can be called when the parent type hasn't yet been populated
-                       // and it's base types need not have been populated.  So, we defer this check
-                       // to the second time Define () is called on this member.
-                       if (Parent.PartialContainer.BaseCache == null)
-                               return true;
-                       return base.CheckBase ();
-               }
-
                /// <summary>
                ///   Defines the constant in the @parent
                /// </summary>
                public override bool Define ()
                {
-                       // Because constant define can be called from other class
-                       if (define_called) {
-                               CheckBase ();
-                               return FieldBuilder != null;
-                       }
-
-                       define_called = true;
-
                        if (!base.Define ())
                                return false;
 
-                       Type ttype = MemberType;
-                       if (!IsConstantTypeValid (ttype)) {
+                       TypeSpec ttype = MemberType;
+                       if (!ttype.IsConstantCompatible) {
                                Error_InvalidConstantType (ttype, Location, Report);
                        }
 
@@ -76,11 +58,10 @@ namespace Mono.CSharp {
                                field_attr |= FieldAttributes.Literal;
                        }
 
-                       FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, field_attr);
-                       spec = new ConstSpec (this, FieldBuilder, ModFlags, initializer);
+                       FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType.GetMetaInfo (), field_attr);
+                       spec = new ConstSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags, initializer);
 
-                       TypeManager.RegisterConstant (FieldBuilder, (ConstSpec) spec);
-                       Parent.MemberCache.AddMember (FieldBuilder, spec);
+                       Parent.MemberCache.AddMember (spec);
 
                        if ((field_attr & FieldAttributes.InitOnly) != 0)
                                Parent.PartialContainer.RegisterFieldForInitialization (this,
@@ -89,15 +70,12 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public static bool IsConstantTypeValid (Type t)
+               public Constant DefineValue ()
                {
-                       if (TypeManager.IsBuiltinOrEnum (t))
-                               return true;
-
-                       if (TypeManager.IsGenericParameter (t) || t.IsPointer)
-                               return false;
+                       if (value == null)
+                               value = initializer.Resolve (new ResolveContext (this)) as Constant;
 
-                       return TypeManager.IsReferenceType (t);
+                       return value;
                }
 
                /// <summary>
@@ -105,10 +83,6 @@ namespace Mono.CSharp {
                /// </summary>
                public override void Emit ()
                {
-                       var value = initializer.Resolve (new ResolveContext (this)) as Constant;
-                       if (value == null || FieldBuilder == null)
-                               return;
-
                        if (value.Type == TypeManager.decimal_type) {
                                FieldBuilder.SetCustomAttribute (CreateDecimalConstantAttribute (value));
                        } else{
@@ -137,9 +111,9 @@ namespace Mono.CSharp {
                        return new CustomAttributeBuilder (pa.Constructor, args);
                }
 
-               public static void Error_InvalidConstantType (Type t, Location loc, Report Report)
+               public static void Error_InvalidConstantType (TypeSpec t, Location loc, Report Report)
                {
-                       if (TypeManager.IsGenericParameter (t)) {
+                       if (t.IsGenericParameter) {
                                Report.Error (1959, loc,
                                        "Type parameter `{0}' cannot be declared const", TypeManager.CSharpName (t));
                        } else {
@@ -153,8 +127,8 @@ namespace Mono.CSharp {
        {
                Expression value;
 
-               public ConstSpec (IMemberDefinition definition, FieldInfo fi, Modifiers mod, Expression value)
-                       : base (definition, fi, mod)
+               public ConstSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo fi, Modifiers mod, Expression value)
+                       : base (declaringType, definition, memberType, fi, mod)
                {
                        this.value = value;
                }
@@ -163,7 +137,7 @@ namespace Mono.CSharp {
                        get {
                                return value;
                        }
-                       set {
+                       private set {
                                this.value = value;
                        }
                }
@@ -242,7 +216,6 @@ namespace Mono.CSharp {
                                expr = expr.Resolve (rc);
                        }
 
-
                        return expr;
                }
        }
index b046f5579f7116c481639f5436125eff27453c18..63fe0146a54054d68946e0816d63b52f8529eda4 100644 (file)
@@ -50,7 +50,7 @@ namespace Mono.CSharp {
                        return GetValue ();
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
                {
                        if (!expl && IsLiteral && 
                                (TypeManager.IsPrimitiveType (target) || type == TypeManager.decimal_type) &&
@@ -62,7 +62,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public Constant ImplicitConversionRequired (ResolveContext ec, Type type, Location loc)
+               public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc)
                {
                        Constant c = ConvertImplicitly (ec, type);
                        if (c == null)
@@ -71,7 +71,7 @@ namespace Mono.CSharp {
                        return c;
                }
 
-               public virtual Constant ConvertImplicitly (ResolveContext rc, Type type)
+               public virtual Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
                {
                        if (this.type == type)
                                return this;
@@ -96,12 +96,12 @@ namespace Mono.CSharp {
                //
                //  Returns a constant instance based on Type
                //
-               public static Constant CreateConstant (ResolveContext rc, Type t, object v, Location loc)
+               public static Constant CreateConstant (ResolveContext rc, TypeSpec t, object v, Location loc)
                {
                        return CreateConstantFromValue (t, v, loc).Resolve (rc);
                }
 
-               public static Constant CreateConstantFromValue (Type t, object v, Location loc)
+               public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
                {
                        if (t == TypeManager.int32_type)
                                return new IntConstant ((int) v, loc);
@@ -132,7 +132,7 @@ namespace Mono.CSharp {
                        if (t == TypeManager.decimal_type)
                                return new DecimalConstant ((decimal) v, loc);
                        if (TypeManager.IsEnumType (t)) {
-                               Type real_type = TypeManager.GetEnumUnderlyingType (t);
+                               var real_type = EnumSpec.GetUnderlyingType (t);
                                return new EnumConstant (CreateConstantFromValue (real_type, v, loc).Resolve (null), t);
                        }
                        if (v == null) {
@@ -162,12 +162,12 @@ namespace Mono.CSharp {
                /// It throws OverflowException 
                /// </summary>
                // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
-               public abstract Constant ConvertExplicitly (bool in_checked_context, Type target_type);
+               public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
 
                /// <summary>
                ///   Attempts to do a compile-time folding of a constant cast.
                /// </summary>
-               public Constant TryReduce (ResolveContext ec, Type target_type, Location loc)
+               public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
                {
                        try {
                                return TryReduce (ec, target_type);
@@ -184,14 +184,14 @@ namespace Mono.CSharp {
                        }
                }
 
-               Constant TryReduce (ResolveContext ec, Type target_type)
+               Constant TryReduce (ResolveContext ec, TypeSpec target_type)
                {
                        if (Type == target_type)
                                return this;
 
                        Constant c;
                        if (TypeManager.IsEnumType (target_type)) {
-                               c = TryReduce (ec, TypeManager.GetEnumUnderlyingType (target_type));
+                               c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
                                if (c == null)
                                        return null;
 
@@ -209,7 +209,7 @@ namespace Mono.CSharp {
                /// Need to pass type as the constant can require a boxing
                /// and in such case no optimization is possible
                /// </summary>
-               public bool IsDefaultInitializer (Type type)
+               public bool IsDefaultInitializer (TypeSpec type)
                {
                        if (type == Type)
                                return IsDefaultValue;
@@ -256,12 +256,7 @@ namespace Mono.CSharp {
 
                public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
                {
-                       return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       // A constant cannot be of generic type
+                       return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
                }
 
                public new Constant Resolve (ResolveContext rc)
@@ -292,7 +287,7 @@ namespace Mono.CSharp {
                {
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
                {
                        try {
                                ConvertExplicitly (true, target);
@@ -334,7 +329,7 @@ namespace Mono.CSharp {
                        return (object) Value;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
@@ -342,9 +337,9 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        if (Value)
-                               ec.ig.Emit (OpCodes.Ldc_I4_1);
+                               ec.Emit (OpCodes.Ldc_I4_1);
                        else
-                               ec.ig.Emit (OpCodes.Ldc_I4_0);
+                               ec.Emit (OpCodes.Ldc_I4_0);
                }
 
                public override bool IsDefaultValue {
@@ -363,7 +358,7 @@ namespace Mono.CSharp {
                        get { return Value == false; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        return null;
                }
@@ -379,14 +374,14 @@ namespace Mono.CSharp {
                        Value = v;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       IntLiteral.EmitInt (ec.ig, Value);
+                       ec.EmitInt (Value);
                }
 
                public override string AsString ()
@@ -433,7 +428,7 @@ namespace Mono.CSharp {
                        get { return Value == 0; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.sbyte_type) {
                                if (in_checked_context){
@@ -484,14 +479,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write ((ushort) Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       IntLiteral.EmitInt (ec.ig, Value);
+                       ec.EmitInt (Value);
                }
 
                static string descape (char c)
@@ -549,7 +544,7 @@ namespace Mono.CSharp {
                        get { return Value == '\0'; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context){
@@ -608,14 +603,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       IntLiteral.EmitInt (ec.ig, Value);
+                       ec.EmitInt (Value);
                }
 
                public override string AsString ()
@@ -655,7 +650,7 @@ namespace Mono.CSharp {
                        get { return Value == 0; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context && Value < 0)
@@ -714,14 +709,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       IntLiteral.EmitInt (ec.ig, Value);
+                       ec.EmitInt (Value);
                }
 
                public override string AsString ()
@@ -761,7 +756,7 @@ namespace Mono.CSharp {
                        }
                }               
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context){
@@ -832,14 +827,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       IntLiteral.EmitInt (ec.ig, Value);
+                       ec.EmitInt (Value);
                }
 
                public override string AsString ()
@@ -879,7 +874,7 @@ namespace Mono.CSharp {
                        get { return Value == 0; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context){
@@ -944,66 +939,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               static public void EmitInt (ILGenerator ig, int i)
-               {
-                       switch (i){
-                       case -1:
-                               ig.Emit (OpCodes.Ldc_I4_M1);
-                               break;
-                               
-                       case 0:
-                               ig.Emit (OpCodes.Ldc_I4_0);
-                               break;
-                               
-                       case 1:
-                               ig.Emit (OpCodes.Ldc_I4_1);
-                               break;
-                               
-                       case 2:
-                               ig.Emit (OpCodes.Ldc_I4_2);
-                               break;
-                               
-                       case 3:
-                               ig.Emit (OpCodes.Ldc_I4_3);
-                               break;
-                               
-                       case 4:
-                               ig.Emit (OpCodes.Ldc_I4_4);
-                               break;
-                               
-                       case 5:
-                               ig.Emit (OpCodes.Ldc_I4_5);
-                               break;
-                               
-                       case 6:
-                               ig.Emit (OpCodes.Ldc_I4_6);
-                               break;
-                               
-                       case 7:
-                               ig.Emit (OpCodes.Ldc_I4_7);
-                               break;
-                               
-                       case 8:
-                               ig.Emit (OpCodes.Ldc_I4_8);
-                               break;
-
-                       default:
-                               if (i >= -128 && i <= 127){
-                                       ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
-                               } else
-                                       ig.Emit (OpCodes.Ldc_I4, i);
-                               break;
-                       }
-               }
-
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       EmitInt (ec.ig, Value);
+                       ec.EmitInt (Value);
                }
 
                public override string AsString ()
@@ -1043,7 +986,7 @@ namespace Mono.CSharp {
                        get { return Value == 0; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context){
@@ -1104,7 +1047,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public override Constant ConvertImplicitly (ResolveContext rc, Type type)
+               public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
                {
                        if (this.type == type)
                                return this;
@@ -1121,7 +1064,7 @@ namespace Mono.CSharp {
                ///   into a different data type using casts (See Implicit Constant
                ///   Expression Conversions)
                /// </summary>
-               Constant TryImplicitIntConversion (Type target_type)
+               Constant TryImplicitIntConversion (TypeSpec target_type)
                {
                        if (target_type == TypeManager.sbyte_type) {
                                if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
@@ -1177,14 +1120,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       IntLiteral.EmitInt (ec.ig, unchecked ((int) Value));
+                       ec.EmitInt (unchecked ((int) Value));
                }
 
                public override string AsString ()
@@ -1224,7 +1167,7 @@ namespace Mono.CSharp {
                        get { return Value == 0; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context){
@@ -1300,31 +1243,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       EmitLong (ec.ig, Value);
-               }
-
-               static public void EmitLong (ILGenerator ig, long l)
-               {
-                       if (l >= int.MinValue && l <= int.MaxValue) {
-                               IntLiteral.EmitInt (ig, unchecked ((int) l));
-                               ig.Emit (OpCodes.Conv_I8);
-                               return;
-                       }
-
-                       if (l >= 0 && l <= uint.MaxValue) {
-                               IntLiteral.EmitInt (ig, unchecked ((int) l));
-                               ig.Emit (OpCodes.Conv_U8);
-                               return;
-                       }
-                       
-                       ig.Emit (OpCodes.Ldc_I8, l);
+                       ec.EmitLong (Value);
                }
 
                public override string AsString ()
@@ -1364,7 +1290,7 @@ namespace Mono.CSharp {
                        get { return Value == 0; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context){
@@ -1430,7 +1356,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public override Constant ConvertImplicitly (ResolveContext rc, Type type)
+               public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
                {
                        if (Value >= 0 && type == TypeManager.uint64_type) {
                                return new ULongConstant ((ulong) Value, loc).Resolve (rc);
@@ -1456,16 +1382,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
-                       LongLiteral.EmitLong (ig, unchecked ((long) Value));
+                       ec.EmitLong (unchecked ((long) Value));
                }
 
                public override string AsString ()
@@ -1505,7 +1429,7 @@ namespace Mono.CSharp {
                        get { return Value == 0; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context && Value > Byte.MaxValue)
@@ -1575,14 +1499,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldc_R4, Value);
+                       ec.Emit (OpCodes.Ldc_R4, Value);
                }
 
                public override string AsString ()
@@ -1607,7 +1531,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context){
@@ -1698,14 +1622,14 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Stream.Write (Value);
                }
 
                public override void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldc_R8, Value);
+                       ec.Emit (OpCodes.Ldc_R8, Value);
                }
 
                public override string AsString ()
@@ -1730,7 +1654,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.byte_type) {
                                if (in_checked_context){
@@ -1833,8 +1757,6 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        int [] words = decimal.GetBits (Value);
                        int power = (words [3] >> 16) & 0xff;
 
@@ -1848,8 +1770,8 @@ namespace Mono.CSharp {
                                                        return;
                                        }
 
-                                       IntConstant.EmitInt (ig, (int) Value);
-                                       ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
+                                       ec.EmitInt ((int) Value);
+                                       ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
                                        return;
                                }
 
@@ -1862,21 +1784,21 @@ namespace Mono.CSharp {
                                                        return;
                                        }
 
-                                       LongConstant.EmitLong (ig, (long) Value);
-                                       ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_long_arg);
+                                       ec.EmitLong ((long) Value);
+                                       ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_long_arg);
                                        return;
                                }
                        }
 
-                       IntConstant.EmitInt (ig, words [0]);
-                       IntConstant.EmitInt (ig, words [1]);
-                       IntConstant.EmitInt (ig, words [2]);
+                       ec.EmitInt (words [0]);
+                       ec.EmitInt (words [1]);
+                       ec.EmitInt (words [2]);
 
                        // sign
-                       IntConstant.EmitInt (ig, words [3] >> 31);
+                       ec.EmitInt (words [3] >> 31);
 
                        // power
-                       IntConstant.EmitInt (ig, power);
+                       ec.EmitInt (power);
 
                        if (TypeManager.void_decimal_ctor_five_args == null) {
                                TypeManager.void_decimal_ctor_five_args = TypeManager.GetPredefinedConstructor (
@@ -1887,7 +1809,7 @@ namespace Mono.CSharp {
                                        return;
                        }
 
-                       ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
+                       ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
                }
 
                public override bool IsDefaultValue {
@@ -1902,7 +1824,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (target_type == TypeManager.sbyte_type)
                                return new SByteConstant ((sbyte)Value, loc);
@@ -1962,7 +1884,7 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        if (Value == null) {
-                               ec.ig.Emit (OpCodes.Ldnull);
+                               ec.Emit (OpCodes.Ldnull);
                                return;
                        }
 
@@ -1972,18 +1894,18 @@ namespace Mono.CSharp {
                        //
                        if (Value.Length == 0 && RootContext.Optimize && !TypeManager.IsEqual (ec.CurrentType, TypeManager.string_type)) {
                                if (TypeManager.string_empty == null)
-                                       TypeManager.string_empty = TypeManager.GetPredefinedField (TypeManager.string_type, "Empty", loc);
+                                       TypeManager.string_empty = TypeManager.GetPredefinedField (TypeManager.string_type, "Empty", loc, TypeManager.string_type);
 
                                if (TypeManager.string_empty != null) {
-                                       ec.ig.Emit (OpCodes.Ldsfld, TypeManager.string_empty);
+                                       ec.Emit (OpCodes.Ldsfld, TypeManager.string_empty);
                                        return;
                                }
                        }
 
-                       ec.ig.Emit (OpCodes.Ldstr, Value);
+                       ec.Emit (OpCodes.Ldstr, Value);
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        // cast to object
                        if (type != targetType)
@@ -2010,7 +1932,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        return null;
                }
@@ -2021,7 +1943,7 @@ namespace Mono.CSharp {
        //
        public class NullConstant : Constant
        {
-               public NullConstant (Type type, Location loc)
+               public NullConstant (TypeSpec type, Location loc)
                        : base (loc)
                {
                        eclass = ExprClass.Value;
@@ -2038,14 +1960,15 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        // Type it as string cast
                        if (targetType == TypeManager.object_type || targetType == TypeManager.null_type)
                                enc.Encode (TypeManager.string_type);
 
-                       if (targetType.IsArray) {
-                               if (targetType.GetArrayRank () != 1)
+                       var ac = targetType as ArrayContainer;
+                       if (ac != null) {
+                               if (ac.Rank != 1)
                                        base.EncodeAttributeValue (rc, enc, targetType);
                                else
                                        enc.Stream.Write (uint.MaxValue);
@@ -2056,11 +1979,11 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldnull);
+                       ec.Emit (OpCodes.Ldnull);
 
                        // Only to make verifier happy
                        if (TypeManager.IsGenericParameter (type))
-                               ec.ig.Emit (OpCodes.Unbox_Any, type);
+                               ec.Emit (OpCodes.Unbox_Any, type);
                }
 
                public override string ExprClassName {
@@ -2074,7 +1997,7 @@ namespace Mono.CSharp {
                        return "null";
                }
 
-               public override Constant ConvertExplicitly (bool inCheckedContext, Type targetType)
+               public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
                {
                        if (targetType.IsPointer) {
                                if (IsLiteral || this is NullPointer)
@@ -2099,7 +2022,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public override Constant ConvertImplicitly (ResolveContext rc, Type targetType)
+               public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec targetType)
                {
                        return ConvertExplicitly (false, targetType);
                }
@@ -2124,11 +2047,6 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return true; }
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-               }
        }
 
        /// <summary>
@@ -2191,7 +2109,7 @@ namespace Mono.CSharp {
                        get { return value.IsZeroInteger; }
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
                        return new_value == null ? null : new SideEffectConstant (new_value, side_effect, new_value.Location);
index 8a56cdcfb4953552dea7e1a60947d7206f286eb0..006c66cb60cf72a175c595df8cc7b8486bf82c41 100644 (file)
@@ -24,7 +24,7 @@ namespace Mono.CSharp
                //
                // A scope type context, it can be inflated for generic types
                //
-               Type CurrentType { get; }
+               TypeSpec CurrentType { get; }
 
                //
                // A scope type parameters either VAR or MVAR
@@ -32,21 +32,20 @@ namespace Mono.CSharp
                TypeParameter[] CurrentTypeParameters { get; }
 
                //
-               // A type definition of the type context. For partial types definition use
+               // A member definition of the context. For partial types definition use
                // CurrentTypeDefinition.PartialContainer otherwise the context is local
                //
-               // TODO: CurrentType.Definition
-               //
-               TypeContainer CurrentTypeDefinition { get; }
+               MemberCore CurrentMemberDefinition { get; }
 
                bool IsObsolete { get; }
                bool IsUnsafe { get; }
                bool IsStatic { get; }
+               bool HasUnresolvedConstraints { get; }
 
                string GetSignatureForError ();
 
-               ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc);
-               FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104);
+               ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc);
+               FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104);
                FullNamedExpression LookupNamespaceAlias (string name);
 
                CompilerContext Compiler { get; }
@@ -61,7 +60,7 @@ namespace Mono.CSharp
 
                public TypeInferenceContext ReturnTypeInference;
 
-               Type return_type;
+               TypeSpec return_type;
 
                /// <summary>
                ///   The location where return has to jump to return the
@@ -74,7 +73,7 @@ namespace Mono.CSharp
                /// </summary>
                public bool HasReturnLabel;
 
-               public BlockContext (IMemberContext mc, ExplicitBlock block, Type returnType)
+               public BlockContext (IMemberContext mc, ExplicitBlock block, TypeSpec returnType)
                        : base (mc)
                {
                        if (returnType == null)
@@ -180,7 +179,7 @@ namespace Mono.CSharp
                                HasReturnLabel = true;
                }
 
-               public Type ReturnType {
+               public TypeSpec ReturnType {
                        get { return return_type; }
                }
        }
@@ -362,7 +361,7 @@ namespace Mono.CSharp
                        get { return CurrentAnonymousMethod as Iterator; }
                }
 
-               public Type CurrentType {
+               public TypeSpec CurrentType {
                        get { return MemberContext.CurrentType; }
                }
 
@@ -370,8 +369,8 @@ namespace Mono.CSharp
                        get { return MemberContext.CurrentTypeParameters; }
                }
 
-               public TypeContainer CurrentTypeDefinition {
-                       get { return MemberContext.CurrentTypeDefinition; }
+               public MemberCore CurrentMemberDefinition {
+                       get { return MemberContext.CurrentMemberDefinition; }
                }
 
                public bool ConstantCheckState {
@@ -382,6 +381,10 @@ namespace Mono.CSharp
                        get { return (flags & Options.DoFlowAnalysis) != 0; }
                }
 
+               public bool HasUnresolvedConstraints {
+                       get { return false; }
+               }
+
                public bool IsInProbingMode {
                        get { return (flags & Options.ProbingMode) != 0; }
                }
@@ -473,14 +476,14 @@ namespace Mono.CSharp
                        get { return HasSet (Options.UnsafeScope) || MemberContext.IsUnsafe; }
                }
 
-               public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+               public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
                {
-                       return MemberContext.LookupExtensionMethod (extensionType, name, loc);
+                       return MemberContext.LookupExtensionMethod (extensionType, name, arity, loc);
                }
 
-               public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
                {
-                       return MemberContext.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                       return MemberContext.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
                }
 
                public FullNamedExpression LookupNamespaceAlias (string name)
index 533f828c4ff0711e234d29a9ec36e87322642295..e719336077543bbb5f3b09b09feb327f50e3bb8d 100644 (file)
@@ -39,184 +39,119 @@ namespace Mono.CSharp {
                        implicit_conv = new DoubleHash (100);
                }
                
-               static Type TypeParam_EffectiveBaseType (GenericConstraints gc)
-               {
-                       var list = new List<Type> ();
-                       list.Add (gc.EffectiveBaseClass);
-                       foreach (Type t in gc.InterfaceConstraints) {
-                               if (!TypeManager.IsGenericParameter (t))
-                                       continue;
-
-                               GenericConstraints new_gc = TypeManager.GetTypeParameterConstraints (t);
-                               if (new_gc != null)
-                                       list.Add (TypeParam_EffectiveBaseType (new_gc));
-                       }
-                       return FindMostEncompassedType (list);
-               }
-
                //
                // From a one-dimensional array-type S[] to System.Collections.IList<T> and base
                // interfaces of this interface, provided there is an implicit reference conversion
                // from S to T.
                //
-               static bool Array_To_IList (Type array, Type list, bool isExplicit)
+               static bool ArrayToIList (ArrayContainer array, TypeSpec list, bool isExplicit)
                {
-                       if ((array.GetArrayRank () != 1) || !TypeManager.IsGenericType (list))
+                       if (array.Rank != 1 || !list.IsGeneric)
                                return false;
 
-                       Type gt = TypeManager.DropGenericTypeArguments (list);
-                       if ((gt != TypeManager.generic_ilist_type) &&
-                           (gt != TypeManager.generic_icollection_type) &&
-                           (gt != TypeManager.generic_ienumerable_type))
+                       var open_version = list.GetDefinition ();
+                       if ((open_version != TypeManager.generic_ilist_type) &&
+                               (open_version != TypeManager.generic_icollection_type) &&
+                               (open_version != TypeManager.generic_ienumerable_type))
                                return false;
 
-                       Type element_type = TypeManager.GetElementType (array);
-                       Type arg_type = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (list) [0]);
-
-                       if (element_type == arg_type)
+                       var arg_type = list.TypeArguments[0];
+                       if (array.Element == arg_type)
                                return true;
 
                        if (isExplicit)
-                               return ExplicitReferenceConversionExists (element_type, arg_type);
+                               return ExplicitReferenceConversionExists (array.Element, arg_type);
 
-                       Type t = TypeManager.GetElementType (array);
                        if (MyEmptyExpr == null)
-                               MyEmptyExpr = new EmptyExpression (t);
+                               MyEmptyExpr = new EmptyExpression (array.Element);
                        else
-                               MyEmptyExpr.SetType (t);
+                               MyEmptyExpr.SetType (array.Element);
 
                        return ImplicitReferenceConversionExists (MyEmptyExpr, arg_type);
                }
                
-               static bool IList_To_Array(Type list, Type array)
+               static bool IList_To_Array(TypeSpec list, ArrayContainer array)
                {
-                       if (!TypeManager.IsGenericType (list) || !array.IsArray || array.GetArrayRank() != 1)
+                       if (array.Rank != 1 || !list.IsGeneric)
                                return false;
-                       
-                       Type gt = TypeManager.DropGenericTypeArguments (list);
-                       if (gt != TypeManager.generic_ilist_type &&
-                               gt != TypeManager.generic_icollection_type &&
-                               gt != TypeManager.generic_ienumerable_type)
+
+                       var open_version = list.GetDefinition ();
+                       if ((open_version != TypeManager.generic_ilist_type) &&
+                               (open_version != TypeManager.generic_icollection_type) &&
+                               (open_version != TypeManager.generic_ienumerable_type))
                                return false;
-                       
-                       Type arg_type = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments(list)[0]);
-                       Type element_type = TypeManager.GetElementType(array);
-                       
-                       if (element_type == arg_type)
+
+                       var arg_type = list.TypeArguments[0];
+                       if (array.Element == arg_type)
                                return true;
                        
                        if (MyEmptyExpr == null)
-                               MyEmptyExpr = new EmptyExpression(element_type);
+                               MyEmptyExpr = new EmptyExpression (array.Element);
                        else
-                               MyEmptyExpr.SetType(element_type);
-                               
-                       return ImplicitReferenceConversionExists(MyEmptyExpr, arg_type) || ExplicitReferenceConversionExists(element_type, arg_type);
+                               MyEmptyExpr.SetType (array.Element);
+
+                       return ImplicitReferenceConversionExists (MyEmptyExpr, arg_type) || ExplicitReferenceConversionExists (array.Element, arg_type);
                }
 
-               static Expression ImplicitTypeParameterConversion (Expression expr,
-                                                                  Type target_type)
+               static Expression ImplicitTypeParameterConversion (Expression expr, TypeSpec target_type)
                {
-                       Type expr_type = expr.Type;
-
-                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (expr_type);
-
-                       if (gc == null) {
-                               if (target_type == TypeManager.object_type)
+                       var expr_type = (TypeParameterSpec) expr.Type;
+                       //
+                       // From T to a type parameter U
+                       //
+                       var ttype = target_type as TypeParameterSpec;
+                       if (ttype != null) {
+                               if (expr_type.IsReferenceType && !ttype.IsReferenceType)
                                        return new BoxedCast (expr, target_type);
 
-                               return null;
-                       }
-
-                       // We're converting from a type parameter which is known to be a reference type.
-                       Type base_type = TypeParam_EffectiveBaseType (gc);
-
-                       if (TypeManager.IsSubclassOf (base_type, target_type))
                                return new ClassCast (expr, target_type);
-
-                       if (target_type.IsInterface) {
-                               if (TypeManager.ImplementsInterface (base_type, target_type))
-                                       return new ClassCast (expr, target_type);
-
-                               foreach (Type t in gc.InterfaceConstraints) {
-                                       if (TypeManager.IsSubclassOf (t, target_type))
-                                               return new ClassCast (expr, target_type);
-                                       if (TypeManager.ImplementsInterface (t, target_type))
-                                               return new ClassCast (expr, target_type);
-                               }
                        }
 
-                       foreach (Type t in gc.InterfaceConstraints) {
-                               if (!TypeManager.IsGenericParameter (t))
-                                       continue;
-                               if (TypeManager.IsSubclassOf (t, target_type))
-                                       return new ClassCast (expr, target_type);
-                               if (TypeManager.ImplementsInterface (t, target_type))
+                       //
+                       // From T to its effective base class C
+                       // From T to any base class of C
+                       // From T to any interface implemented by C
+                       //
+                       var base_type = expr_type.BaseType;
+                       if (base_type == target_type || TypeManager.IsSubclassOf (base_type, target_type) || base_type.ImplementsInterface (target_type)) {
+                               if (expr_type.IsReferenceType)
                                        return new ClassCast (expr, target_type);
-                       }
-
-                       return null;
-               }
-
-               static bool ImplicitTypeParameterBoxingConversion (Type expr_type, Type target_type,
-                                                                  out bool use_class_cast)
-               {
-                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (expr_type);
 
-                       if (gc == null) {
-                               use_class_cast = false;
-                               return target_type == TypeManager.object_type;
+                               return new BoxedCast (expr, target_type);
                        }
 
-                       use_class_cast = true;
-
-                       if (!gc.HasReferenceTypeConstraint)
-                               return false;
-
-                       // We're converting from a type parameter which is known to be a reference type.
-                       Type base_type = TypeParam_EffectiveBaseType (gc);
-
-                       if (TypeManager.IsSubclassOf (base_type, target_type))
-                               return true;
+                       base_type = expr_type.GetEffectiveBase ();
 
-                       if (target_type.IsInterface) {
-                               if (TypeManager.ImplementsInterface (base_type, target_type))
-                                       return true;
+                       var effective_ifaces = expr_type.Interfaces;
+                       if (effective_ifaces != null) {
+                               foreach (var t in effective_ifaces) {
+                                       if (t == target_type || t.ImplementsInterface (target_type)) {
+                                               if (expr_type.IsReferenceType)
+                                                       return new ClassCast (expr, target_type);
 
-                               foreach (Type t in gc.InterfaceConstraints) {
-                                       if (TypeManager.IsSubclassOf (t, target_type))
-                                               return true;
-                                       if (TypeManager.ImplementsInterface (t, target_type))
-                                               return true;
+                                               return new BoxedCast (expr, target_type);
+                                       }
                                }
                        }
 
-                       foreach (Type t in gc.InterfaceConstraints) {
-                               if (!TypeManager.IsGenericParameter (t))
-                                       continue;
-                               if (TypeManager.IsSubclassOf (t, target_type))
-                                       return true;
-                               if (TypeManager.ImplementsInterface (t, target_type))
-                                       return true;
-                       }
-
-                       use_class_cast = false;
-                       return false;
+                       return null;
                }
 
-               static Expression ExplicitTypeParameterConversion (Expression source, Type source_type, Type target_type)
+               static Expression ExplicitTypeParameterConversion (Expression source, TypeSpec source_type, TypeSpec target_type)
                {
-                       if (TypeManager.IsGenericParameter (target_type)) {
-                               GenericConstraints gc = TypeManager.GetTypeParameterConstraints (target_type);
-                               if (gc == null)
-                                       return null;
-
-                               foreach (Type iface in gc.InterfaceConstraints) {
-                                       if (!TypeManager.IsGenericParameter (iface))
-                                               continue;
+                       var target_tp = target_type as TypeParameterSpec;
+                       if (target_tp != null) {
+                               if (target_tp.Interfaces != null) {
+                                       foreach (TypeSpec iface in target_tp.Interfaces) {
+                                               if (!TypeManager.IsGenericParameter (iface))
+                                                       continue;
 
-                                       if (TypeManager.IsSubclassOf (source_type, iface))
-                                               return source == null ? EmptyExpression.Null : new ClassCast (source, target_type, true);
+                                               if (TypeManager.IsSubclassOf (source_type, iface))
+                                                       return source == null ? EmptyExpression.Null : new ClassCast (source, target_type, true);
+                                       }
                                }
+
+                               return null;
                        }
 
                        if (target_type.IsInterface)
@@ -225,9 +160,9 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               static Expression ImplicitReferenceConversion (Expression expr, Type target_type, bool explicit_cast)
+               static Expression ImplicitReferenceConversion (Expression expr, TypeSpec target_type, bool explicit_cast)
                {
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
 
                        if (expr_type == null && expr.eclass == ExprClass.MethodGroup){
                                // if we are a method group, emit a warning
@@ -238,7 +173,7 @@ namespace Mono.CSharp {
                        if (expr_type == TypeManager.void_type)
                                return null;
 
-                       if (TypeManager.IsGenericParameter (expr_type))
+                       if (expr_type.Kind == MemberKind.TypeParameter)
                                return ImplicitTypeParameterConversion (expr, target_type);
 
                        //
@@ -273,12 +208,12 @@ namespace Mono.CSharp {
                //
                // 6.1.6 Implicit reference conversions
                //
-               public static bool ImplicitReferenceConversionExists (Expression expr, Type target_type)
+               public static bool ImplicitReferenceConversionExists (Expression expr, TypeSpec target_type)
                {
                        if (TypeManager.IsStruct (target_type))
                                return false;
 
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
 
                        // from the null type to any reference-type.
                        if (expr_type == TypeManager.null_type)
@@ -287,11 +222,23 @@ namespace Mono.CSharp {
                        if (TypeManager.IsGenericParameter (expr_type))
                                return ImplicitTypeParameterConversion (expr, target_type) != null;
 
+                       // This code is kind of mirrored inside ImplicitStandardConversionExists
+                       // with the small distinction that we only probe there
+                       //
+                       // Always ensure that the code here and there is in sync
+
+                       // from any class-type S to any interface-type T.
+                       if (target_type.IsInterface) {
+                               if (expr_type.ImplementsInterface (target_type)){
+                                       return !TypeManager.IsValueType (expr_type);
+                               }
+                       }
+
                        //
                        // notice that it is possible to write "ValueType v = 1", the ValueType here
                        // is an abstract class, and not really a value type, so we apply the same rules.
                        //
-                       if (target_type == TypeManager.object_type || TypeManager.IsDynamicType (target_type)) {
+                       if (target_type == TypeManager.object_type || target_type == InternalType.Dynamic) {
                                //
                                // A pointer type cannot be converted to object
                                //
@@ -301,11 +248,19 @@ namespace Mono.CSharp {
                                if (TypeManager.IsValueType (expr_type))
                                        return false;
 
-                               if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type){
+                               if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type || expr_type.IsDelegate) {
                                        // No mcs internal types are convertible
-                                       return expr_type.Module != typeof (Convert).Module;
+                                       return true; // expr_type.MetaInfo.Module != typeof (Convert).Module;
                                }
 
+                               // From anything to dynamic
+                               if (target_type == InternalType.Dynamic)
+                                       return true;
+
+                               // From dynamic to object
+                               if (expr_type == InternalType.Dynamic)
+                                       return true;
+
                                return false;
                        } else if (target_type == TypeManager.value_type) {
                                return expr_type == TypeManager.enum_type;
@@ -317,35 +272,31 @@ namespace Mono.CSharp {
                                //
                                if (target_type == TypeManager.enum_type || TypeManager.IsGenericParameter (expr_type))
                                        return false;
-                               
-                               return true;
-                       }
 
-                       // This code is kind of mirrored inside ImplicitStandardConversionExists
-                       // with the small distinction that we only probe there
-                       //
-                       // Always ensure that the code here and there is in sync
+                               if (TypeManager.IsValueType (expr_type))
+                                       return false;
 
-                       // from any class-type S to any interface-type T.
-                       if (target_type.IsInterface) {
-                               if (TypeManager.ImplementsInterface (expr_type, target_type)){
-                                       return !TypeManager.IsGenericParameter (expr_type) &&
-                                               !TypeManager.IsValueType (expr_type);
-                               }
+                               // Array type variance conversion
+                               //if (target_type.IsArray != expr_type.IsArray)
+                               //      return false;
+
+                               return true;
                        }
 
-                       if (expr_type.IsArray) {
+                       var expr_type_array = expr_type as ArrayContainer;
+                       if (expr_type_array != null) {
+                               var target_type_array = target_type as ArrayContainer;
                                // from an array-type S to an array-type of type T
-                               if (target_type.IsArray && expr_type.GetArrayRank () == target_type.GetArrayRank ()) {
+                               if (target_type_array != null && expr_type_array.Rank == target_type_array.Rank) {
 
                                        //
                                        // Both SE and TE are reference-types
                                        //
-                                       Type expr_element_type = TypeManager.GetElementType (expr_type);
+                                       TypeSpec expr_element_type = expr_type_array.Element;
                                        if (!TypeManager.IsReferenceType (expr_element_type))
                                                return false;
 
-                                       Type target_element_type = TypeManager.GetElementType (target_type);
+                                       TypeSpec target_element_type = target_type_array.Element;
                                        if (!TypeManager.IsReferenceType (target_element_type))
                                                return false;
 
@@ -362,23 +313,23 @@ namespace Mono.CSharp {
                                        return true;
 
                                // from an array-type of type T to IList<T>
-                               if (Array_To_IList (expr_type, target_type, false))
+                               if (ArrayToIList (expr_type_array, target_type, false))
                                        return true;
 
                                return false;
                        }
 
-                       if (TypeManager.IsVariantOf (expr_type, target_type))
+                       if (TypeSpecComparer.Variant.IsEqual (expr_type, target_type))
                                return true;
 
                        // from any interface type S to interface-type T.
                        if (expr_type.IsInterface && target_type.IsInterface) {
-                               return TypeManager.ImplementsInterface (expr_type, target_type);
+                               return expr_type.ImplementsInterface (target_type);
                        }
 
                        // from any delegate type to System.Delegate
                        if (target_type == TypeManager.delegate_type &&
-                               (expr_type == TypeManager.delegate_type || TypeManager.IsDelegateType (expr_type)))
+                               (expr_type == TypeManager.delegate_type || expr_type.IsDelegate))
                                return true;
 
                        if (TypeManager.IsEqual (expr_type, target_type))
@@ -387,16 +338,16 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public static bool ImplicitBoxingConversionExists (Expression expr, Type target_type,
+               public static bool ImplicitBoxingConversionExists (Expression expr, TypeSpec target_type,
                                                                   out bool use_class_cast)
                {
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
                        use_class_cast = false;
                        
                        //
                        // From any value-type to the type object.
                        //
-                       if (target_type == TypeManager.object_type || TypeManager.IsDynamicType (target_type)) {
+                       if (target_type == TypeManager.object_type || target_type == InternalType.Dynamic) {
                                //
                                // A pointer type cannot be converted to object
                                //
@@ -422,7 +373,7 @@ namespace Mono.CSharp {
                                // From any nullable-type with an underlying enum-type to the type System.Enum
                                //
                                if (TypeManager.IsNullableType (expr_type))
-                                       return TypeManager.IsEnumType (TypeManager.GetTypeArguments (expr_type) [0]);
+                                       return TypeManager.IsEnumType (Nullable.NullableInfo.GetUnderlyingType (expr_type));
                        }
 
                        if (TypeManager.IsSubclassOf (expr_type, target_type)) {
@@ -442,21 +393,23 @@ namespace Mono.CSharp {
 
                        // from any class-type S to any interface-type T.
                        if (target_type.IsInterface) {
-                               if (TypeManager.ImplementsInterface (expr_type, target_type))
+                               if (expr_type.ImplementsInterface (target_type))
                                        return TypeManager.IsGenericParameter (expr_type) ||
                                                TypeManager.IsValueType (expr_type);
                        }
 
-                       if (TypeManager.IsGenericParameter (expr_type))
-                               return ImplicitTypeParameterBoxingConversion (
-                                       expr_type, target_type, out use_class_cast);
+                       if (TypeManager.IsGenericParameter (expr_type)) {
+                               return ImplicitTypeParameterConversion (expr, target_type) != null;
+//                             return ImplicitTypeParameterBoxingConversion (
+//                                     expr_type, target_type, out use_class_cast);
+                       }
 
                        return false;
                }
 
-               public static Expression ImplicitNulableConversion (ResolveContext ec, Expression expr, Type target_type)
+               public static Expression ImplicitNulableConversion (ResolveContext ec, Expression expr, TypeSpec target_type)
                {
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
 
                        //
                        // From null to any nullable type
@@ -465,11 +418,11 @@ namespace Mono.CSharp {
                                return ec == null ? EmptyExpression.Null : Nullable.LiftedNull.Create (target_type, expr.Location);
 
                        // S -> T?
-                       Type t_el = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (target_type)[0]);
+                       TypeSpec t_el = TypeManager.GetTypeArguments (target_type)[0];
 
                        // S? -> T?
                        if (TypeManager.IsNullableType (expr_type))
-                               expr_type = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (expr_type)[0]);
+                               expr_type = TypeManager.GetTypeArguments (expr_type)[0];
 
                        //
                        // Predefined implicit identity or implicit numeric conversion
@@ -510,12 +463,12 @@ namespace Mono.CSharp {
                ///   expr is the expression to convert, returns a new expression of type
                ///   target_type or null if an implicit conversion is not possible.
                /// </summary>
-               public static Expression ImplicitNumericConversion (Expression expr, Type target_type)
+               public static Expression ImplicitNumericConversion (Expression expr, TypeSpec target_type)
                {
                        return ImplicitNumericConversion (expr, expr.Type, target_type);
                }
 
-               static Expression ImplicitNumericConversion (Expression expr, Type expr_type, Type target_type)
+               static Expression ImplicitNumericConversion (Expression expr, TypeSpec expr_type, TypeSpec target_type)
                {
                        if (expr_type == TypeManager.sbyte_type){
                                //
@@ -663,14 +616,13 @@ namespace Mono.CSharp {
                ///  Same as ImplicitStandardConversionExists except that it also looks at
                ///  implicit user defined conversions - needed for overload resolution
                /// </summary>
-               public static bool ImplicitConversionExists (ResolveContext ec, Expression expr, Type target_type)
+               public static bool ImplicitConversionExists (ResolveContext ec, Expression expr, TypeSpec target_type)
                {
                        if (ImplicitStandardConversionExists (expr, target_type))
                                return true;
 
                        if (expr.Type == InternalType.AnonymousMethod) {
-                               if (!TypeManager.IsDelegateType (target_type) &&
-                                       TypeManager.DropGenericTypeArguments (target_type) != TypeManager.expression_type)
+                               if (!TypeManager.IsDelegateType (target_type) && target_type.GetDefinition () != TypeManager.expression_type)
                                        return false;
 
                                AnonymousMethodExpression ame = (AnonymousMethodExpression) expr;
@@ -678,7 +630,7 @@ namespace Mono.CSharp {
                        }
                        
                        if (expr.eclass == ExprClass.MethodGroup) {
-                               if (TypeManager.IsDelegateType (target_type) && RootContext.Version != LanguageVersion.ISO_1) {
+                               if (target_type.IsDelegate && RootContext.Version != LanguageVersion.ISO_1) {
                                        MethodGroupExpr mg = expr as MethodGroupExpr;
                                        if (mg != null)
                                                return DelegateCreation.ImplicitStandardConversionExists (ec, mg, target_type);
@@ -696,9 +648,9 @@ namespace Mono.CSharp {
                ///
                ///  ec should point to a real EmitContext if expr.Type is TypeManager.anonymous_method_type.
                /// </summary>
-               public static bool ImplicitStandardConversionExists (Expression expr, Type target_type)
+               public static bool ImplicitStandardConversionExists (Expression expr, TypeSpec target_type)
                {
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
 
                        if (expr_type == TypeManager.null_type) {
                                NullLiteral nl = expr as NullLiteral;
@@ -758,7 +710,7 @@ namespace Mono.CSharp {
                                                return true;
                                }
 
-                               if (value == 0 && TypeManager.IsEnumType (target_type))
+                               if (value == 0 && target_type.IsEnum)
                                        return true;
                        }
 
@@ -777,7 +729,7 @@ namespace Mono.CSharp {
                        // If `expr_type' implements `target_type' (which is an iface)
                        // see TryImplicitIntConversion
                        //
-                       if (target_type.IsInterface && TypeManager.ImplementsInterface (expr_type, target_type))
+                       if (target_type.IsInterface && expr_type.ImplementsInterface (target_type))
                                return true;
 
                        if (target_type == TypeManager.void_ptr_type && expr_type.IsPointer)
@@ -794,19 +746,12 @@ namespace Mono.CSharp {
                ///  Finds "most encompassed type" according to the spec (13.4.2)
                ///  amongst the methods in the MethodGroupExpr
                /// </summary>
-               static Type FindMostEncompassedType (IList<Type> types)
+               public static TypeSpec FindMostEncompassedType (IEnumerable<TypeSpec> types)
                {
-                       Type best = null;
-
-                       if (types.Count == 0)
-                               return null;
-
-                       if (types.Count == 1)
-                               return (Type) types [0];
-
+                       TypeSpec best = null;
                        EmptyExpression expr = EmptyExpression.Grab ();
 
-                       foreach (Type t in types) {
+                       foreach (TypeSpec t in types) {
                                if (best == null) {
                                        best = t;
                                        continue;
@@ -818,7 +763,7 @@ namespace Mono.CSharp {
                        }
 
                        expr.SetType (best);
-                       foreach (Type t in types) {
+                       foreach (TypeSpec t in types) {
                                if (best == t)
                                        continue;
                                if (!ImplicitStandardConversionExists (expr, t)) {
@@ -836,9 +781,9 @@ namespace Mono.CSharp {
                ///  Finds "most encompassing type" according to the spec (13.4.2)
                ///  amongst the types in the given set
                /// </summary>
-               static Type FindMostEncompassingType (IList<Type> types)
+               static TypeSpec FindMostEncompassingType (IList<TypeSpec> types)
                {
-                       Type best = null;
+                       TypeSpec best = null;
 
                        if (types.Count == 0)
                                return null;
@@ -848,7 +793,7 @@ namespace Mono.CSharp {
 
                        EmptyExpression expr = EmptyExpression.Grab ();
 
-                       foreach (Type t in types) {
+                       foreach (TypeSpec t in types) {
                                if (best == null) {
                                        best = t;
                                        continue;
@@ -859,7 +804,7 @@ namespace Mono.CSharp {
                                        best = t;
                        }
 
-                       foreach (Type t in types) {
+                       foreach (TypeSpec t in types) {
                                if (best == t)
                                        continue;
                                expr.SetType (t);
@@ -879,17 +824,17 @@ namespace Mono.CSharp {
                ///   by making use of FindMostEncomp* methods. Applies the correct rules separately
                ///   for explicit and implicit conversion operators.
                /// </summary>
-               static public Type FindMostSpecificSource (IList<MethodSpec> list,
+               static public TypeSpec FindMostSpecificSource (IList<MethodSpec> list,
                                                           Expression source, bool apply_explicit_conv_rules)
                {
-                       var src_types_set = new List<Type> ();
+                       var src_types_set = new List<TypeSpec> ();
 
                        //
                        // If any operator converts from S then Sx = S
                        //
-                       Type source_type = source.Type;
+                       TypeSpec source_type = source.Type;
                        foreach (var mb in list){
-                               Type param_type = mb.Parameters.Types [0];
+                               TypeSpec param_type = mb.Parameters.Types [0];
 
                                if (param_type == source_type)
                                        return param_type;
@@ -901,9 +846,9 @@ namespace Mono.CSharp {
                        // Explicit Conv rules
                        //
                        if (apply_explicit_conv_rules) {
-                               var candidate_set = new List<Type> ();
+                               var candidate_set = new List<TypeSpec> ();
 
-                               foreach (Type param_type in src_types_set){
+                               foreach (TypeSpec param_type in src_types_set){
                                        if (ImplicitStandardConversionExists (source, param_type))
                                                candidate_set.Add (param_type);
                                }
@@ -924,16 +869,16 @@ namespace Mono.CSharp {
                /// <summary>
                ///  Finds the most specific target Tx according to section 13.4.4
                /// </summary>
-               static public Type FindMostSpecificTarget (IList<MethodSpec> list,
-                                                          Type target, bool apply_explicit_conv_rules)
+               static public TypeSpec FindMostSpecificTarget (IList<MethodSpec> list,
+                                                          TypeSpec target, bool apply_explicit_conv_rules)
                {
-                       var tgt_types_set = new List<Type> ();
+                       var tgt_types_set = new List<TypeSpec> ();
 
                        //
                        // If any operator converts to T then Tx = T
                        //
                        foreach (var mi in list){
-                               Type ret_type = TypeManager.TypeToCoreType (mi.ReturnType);
+                               TypeSpec ret_type = mi.ReturnType;
                                if (ret_type == target)
                                        return ret_type;
 
@@ -944,11 +889,11 @@ namespace Mono.CSharp {
                        // Explicit conv rules
                        //
                        if (apply_explicit_conv_rules) {
-                               var candidate_set = new List<Type> ();
+                               var candidate_set = new List<TypeSpec> ();
 
                                EmptyExpression expr = EmptyExpression.Grab ();
 
-                               foreach (Type ret_type in tgt_types_set){
+                               foreach (TypeSpec ret_type in tgt_types_set){
                                        expr.SetType (ret_type);
 
                                        if (ImplicitStandardConversionExists (expr, target))
@@ -974,7 +919,7 @@ namespace Mono.CSharp {
                ///  User-defined Implicit conversions
                /// </summary>
                static public Expression ImplicitUserConversion (ResolveContext ec, Expression source,
-                                                                Type target, Location loc)
+                                                                TypeSpec target, Location loc)
                {
                        return UserDefinedConversion (ec, source, target, loc, false, true);
                }
@@ -983,20 +928,20 @@ namespace Mono.CSharp {
                ///  User-defined Explicit conversions
                /// </summary>
                static Expression ExplicitUserConversion (ResolveContext ec, Expression source,
-                                                                Type target, Location loc)
+                                                                TypeSpec target, Location loc)
                {
                        return UserDefinedConversion (ec, source, target, loc, true, true);
                }
 
                static void AddConversionOperators (List<MethodSpec> list,
-                                                   Expression source, Type target_type,
+                                                   Expression source, TypeSpec target_type,
                                                    bool look_for_explicit,
                                                    MethodGroupExpr mg)
                {
                        if (mg == null)
                                return;
 
-                       Type source_type = source.Type;
+                       TypeSpec source_type = source.Type;
                        EmptyExpression expr = EmptyExpression.Grab ();
 
                        //
@@ -1012,10 +957,10 @@ namespace Mono.CSharp {
                                        target_type = TypeManager.uint64_type;
                        }
 
-                       foreach (var m in mg.Methods) {
+                       foreach (MethodSpec m in mg.Methods) {
                                AParametersCollection pd = m.Parameters;
-                               Type return_type = TypeManager.TypeToCoreType (m.ReturnType);
-                               Type arg_type = pd.Types [0];
+                               TypeSpec return_type = m.ReturnType;
+                               TypeSpec arg_type = pd.Types [0];
 
                                if (source_type != arg_type) {
                                        if (!ImplicitStandardConversionExists (source, arg_type)) {
@@ -1052,47 +997,47 @@ namespace Mono.CSharp {
                ///   Compute the user-defined conversion operator from source_type to target_type.
                ///   `look_for_explicit' controls whether we should also include the list of explicit operators
                /// </summary>
-               static MethodSpec GetConversionOperator (CompilerContext ctx, Type container_type, Expression source, Type target_type, bool look_for_explicit)
+               static MethodSpec GetConversionOperator (CompilerContext ctx, TypeSpec container_type, Expression source, TypeSpec target_type, bool look_for_explicit)
                {
                        var ops = new List<MethodSpec> (4);
 
-                       Type source_type = source.Type;
+                       TypeSpec source_type = source.Type;
 
                        if (source_type != TypeManager.decimal_type) {
                                AddConversionOperators (ops, source, target_type, look_for_explicit,
-                                       Expression.MethodLookup (ctx, container_type, source_type, "op_Implicit", Location.Null) as MethodGroupExpr);
+                                       Expression.MethodLookup (ctx, container_type, source_type, MemberKind.Operator, "op_Implicit", 0, Location.Null));
                                if (look_for_explicit) {
                                        AddConversionOperators (ops, source, target_type, look_for_explicit,
                                                Expression.MethodLookup (ctx,
-                                                       container_type, source_type, "op_Explicit", Location.Null) as MethodGroupExpr);
+                                                       container_type, source_type, MemberKind.Operator, "op_Explicit", 0, Location.Null));
                                }
                        }
 
                        if (target_type != TypeManager.decimal_type) {
                                AddConversionOperators (ops, source, target_type, look_for_explicit,
-                                       Expression.MethodLookup (ctx, container_type, target_type, "op_Implicit", Location.Null) as MethodGroupExpr);
+                                       Expression.MethodLookup (ctx, container_type, target_type, MemberKind.Operator, "op_Implicit", 0, Location.Null));
                                if (look_for_explicit) {
                                        AddConversionOperators (ops, source, target_type, look_for_explicit,
                                                Expression.MethodLookup (ctx,
-                                                       container_type, target_type, "op_Explicit", Location.Null) as MethodGroupExpr);
+                                                       container_type, target_type, MemberKind.Operator, "op_Explicit", 0, Location.Null));
                                }
                        }
 
                        if (ops.Count == 0)
                                return null;
 
-                       Type most_specific_source = FindMostSpecificSource (ops, source, look_for_explicit);
+                       TypeSpec most_specific_source = FindMostSpecificSource (ops, source, look_for_explicit);
                        if (most_specific_source == null)
                                return null;
 
-                       Type most_specific_target = FindMostSpecificTarget (ops, target_type, look_for_explicit);
+                       TypeSpec most_specific_target = FindMostSpecificTarget (ops, target_type, look_for_explicit);
                        if (most_specific_target == null)
                                return null;
 
                        MethodSpec method = null;
 
                        foreach (var m in ops) {
-                               if (TypeManager.TypeToCoreType (m.ReturnType) != most_specific_target)
+                               if (m.ReturnType != most_specific_target)
                                        continue;
                                if (m.Parameters.Types [0] != most_specific_source)
                                        continue;
@@ -1109,10 +1054,10 @@ namespace Mono.CSharp {
                ///   User-defined conversions
                /// </summary>
                public static Expression UserDefinedConversion (ResolveContext ec, Expression source,
-                                                               Type target, Location loc,
+                                                               TypeSpec target, Location loc,
                                                                bool look_for_explicit, bool return_convert)
                {
-                       Type source_type = source.Type;
+                       TypeSpec source_type = source.Type;
                        MethodSpec method = null;
                        Expression expr = null;
 
@@ -1131,14 +1076,14 @@ namespace Mono.CSharp {
                        if (!(source is Constant) && hash.Lookup (source_type, target, out o)) {
                                method = (MethodSpec) o;
                        } else {
-                               if (TypeManager.IsDynamicType (source_type))
+                               if (source_type == InternalType.Dynamic)
                                        return null;
 
                                method = GetConversionOperator (ec.Compiler, null, source, target, look_for_explicit);
                        }
 
                        if (method != null) {
-                               Type most_specific_source = method.Parameters.Types[0];
+                               TypeSpec most_specific_source = method.Parameters.Types[0];
 
                                //
                                // This will do the conversion to the best match that we
@@ -1171,7 +1116,7 @@ namespace Mono.CSharp {
                                        nullable = true;
                                }
 
-                               Type target_underlying;
+                               TypeSpec target_underlying;
                                if (TypeManager.IsNullableType (target)) {
                                        target_underlying = TypeManager.GetTypeArguments (target)[0];
                                        nullable = true;
@@ -1216,7 +1161,7 @@ namespace Mono.CSharp {
                ///   in a context that expects a `target_type'.
                /// </summary>
                static public Expression ImplicitConversion (ResolveContext ec, Expression expr,
-                                                            Type target_type, Location loc)
+                                                            TypeSpec target_type, Location loc)
                {
                        Expression e;
 
@@ -1246,12 +1191,12 @@ namespace Mono.CSharp {
                ///   user defined implicit conversions are excluded.
                /// </summary>
                static public Expression ImplicitConversionStandard (ResolveContext ec, Expression expr,
-                                                                    Type target_type, Location loc)
+                                                                    TypeSpec target_type, Location loc)
                {
                        return ImplicitConversionStandard (ec, expr, target_type, loc, false);
                }
 
-               static Expression ImplicitConversionStandard (ResolveContext ec, Expression expr, Type target_type, Location loc, bool explicit_cast)
+               static Expression ImplicitConversionStandard (ResolveContext ec, Expression expr, TypeSpec target_type, Location loc, bool explicit_cast)
                {
                        if (expr.eclass == ExprClass.MethodGroup){
                                if (!TypeManager.IsDelegateType (target_type)){
@@ -1269,7 +1214,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
                        Expression e;
 
                        if (expr_type.Equals (target_type)) {
@@ -1278,7 +1223,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (TypeManager.IsVariantOf (expr_type, target_type)) {
+                       if (TypeSpecComparer.Variant.IsEqual (expr_type, target_type)) {
                                return expr;
                        }
 
@@ -1361,13 +1306,13 @@ namespace Mono.CSharp {
                ///   an error is signaled
                /// </summary>
                static public Expression ImplicitConversionRequired (ResolveContext ec, Expression source,
-                                                                    Type target_type, Location loc)
+                                                                    TypeSpec target_type, Location loc)
                {
                        Expression e = ImplicitConversion (ec, source, target_type, loc);
                        if (e != null)
                                return e;
 
-                       if (TypeManager.IsDynamicType (source.Type)) {
+                       if (source.Type == InternalType.Dynamic) {
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (source));
                                return new DynamicConversion (target_type, 0, args, loc).Resolve (ec);
@@ -1398,10 +1343,10 @@ namespace Mono.CSharp {
                ///   Int16->UIntPtr
                ///
                /// </summary>
-               public static Expression ExplicitNumericConversion (Expression expr, Type target_type)
+               public static Expression ExplicitNumericConversion (Expression expr, TypeSpec target_type)
                {
-                       Type expr_type = expr.Type;
-                       Type real_target_type = target_type;
+                       TypeSpec expr_type = expr.Type;
+                       TypeSpec real_target_type = target_type;
 
                        if (expr_type == TypeManager.sbyte_type){
                                //
@@ -1651,7 +1596,7 @@ namespace Mono.CSharp {
                ///  Returns whether an explicit reference conversion can be performed
                ///  from source_type to target_type
                /// </summary>
-               public static bool ExplicitReferenceConversionExists (Type source_type, Type target_type)
+               public static bool ExplicitReferenceConversionExists (TypeSpec source_type, TypeSpec target_type)
                {
                        Expression e = ExplicitReferenceConversion (null, source_type, target_type);
                        if (e == null)
@@ -1666,7 +1611,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Implements Explicit Reference conversions
                /// </summary>
-               static Expression ExplicitReferenceConversion (Expression source, Type source_type, Type target_type)
+               static Expression ExplicitReferenceConversion (Expression source, TypeSpec source_type, TypeSpec target_type)
                {
                        bool target_is_value_type = TypeManager.IsStruct (target_type);
 
@@ -1701,21 +1646,12 @@ namespace Mono.CSharp {
                        if (TypeManager.IsSubclassOf (target_type, source_type))
                                return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
 
-                       //
-                       // From any class type S to any interface T, provides S is not sealed
-                       // and provided S does not implement T.
-                       //
-                       if (target_type.IsInterface && !source_type.IsSealed &&
-                               !TypeManager.ImplementsInterface (source_type, target_type)) {
-                               return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
-                       }
-
                        //
                        // From any interface-type S to to any class type T, provided T is not
                        // sealed, or provided T implements S.
                        //
                        if (source_type.IsInterface) {
-                               if (!target_type.IsSealed || TypeManager.ImplementsInterface (target_type, source_type)) {
+                               if (!target_type.IsSealed || target_type.ImplementsInterface (source_type)) {
                                        if (target_type.IsClass)
                                                return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
 
@@ -1727,17 +1663,20 @@ namespace Mono.CSharp {
                                }
 
                                //
-                               // From System.Collecitons.Generic.IList<T> and its base interfaces to a one-dimensional
+                               // From System.Collections.Generic.IList<T> and its base interfaces to a one-dimensional
                                // array type S[], provided there is an implicit or explicit reference conversion from S to T.
                                //
-                               if (IList_To_Array (source_type, target_type))
+                               var target_array = target_type as ArrayContainer;
+                               if (target_array != null && IList_To_Array (source_type, target_array))
                                        return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
 
                                return null;
                        }
 
-                       if (source_type.IsArray) {
-                               if (target_type.IsArray) {
+                       var source_array = source_type as ArrayContainer;
+                       if (source_array != null) {
+                               var target_array = target_type as ArrayContainer;
+                               if (target_array != null) {
                                        //
                                        // From System.Array to any array-type
                                        //
@@ -1752,17 +1691,17 @@ namespace Mono.CSharp {
                                        //     * Both Se and Te are reference types
                                        //     * An explicit reference conversions exist from Se to Te
                                        //
-                                       if (source_type.GetArrayRank () == target_type.GetArrayRank ()) {
+                                       if (source_array.Rank == target_array.Rank) {
 
-                                               source_type = TypeManager.GetElementType (source_type);
+                                               source_type = source_array.Element;
                                                if (!TypeManager.IsReferenceType (source_type))
                                                        return null;
 
-                                               Type target_type_element = TypeManager.GetElementType (target_type);
-                                               if (!TypeManager.IsReferenceType (target_type_element))
+                                               var target_element = target_array.Element;
+                                               if (!TypeManager.IsReferenceType (target_element))
                                                        return null;
 
-                                               if (ExplicitReferenceConversionExists (source_type, target_type_element))
+                                               if (ExplicitReferenceConversionExists (source_type, target_element))
                                                        return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
                                                        
                                                return null;
@@ -1773,12 +1712,20 @@ namespace Mono.CSharp {
                                // From a single-dimensional array type S[] to System.Collections.Generic.IList<T> and its base interfaces, 
                                // provided that there is an explicit reference conversion from S to T
                                //
-                               if (Array_To_IList (source_type, target_type, true))
+                               if (ArrayToIList (source_array, target_type, true))
                                        return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
 
                                return null;
                        }
 
+                       //
+                       // From any class type S to any interface T, provides S is not sealed
+                       // and provided S does not implement T.
+                       //
+                       if (target_type.IsInterface && !source_type.IsSealed && !source_type.ImplementsInterface (target_type)) {
+                               return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);
+                       }
+
                        //
                        // From System delegate to any delegate-type
                        //
@@ -1793,9 +1740,9 @@ namespace Mono.CSharp {
                ///   type is expr.Type to `target_type'.
                /// </summary>
                static public Expression ExplicitConversionCore (ResolveContext ec, Expression expr,
-                                                                Type target_type, Location loc)
+                                                                TypeSpec target_type, Location loc)
                {
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
 
                        // Explicit conversion includes implicit conversion and it used for enum underlying types too
                        Expression ne = ImplicitConversionStandard (ec, expr, target_type, loc, true);
@@ -1803,7 +1750,7 @@ namespace Mono.CSharp {
                                return ne;
 
                        if (TypeManager.IsEnumType (expr_type)) {
-                               Expression underlying = EmptyCast.Create (expr, TypeManager.GetEnumUnderlyingType (expr_type));
+                               Expression underlying = EmptyCast.Create (expr, EnumSpec.GetUnderlyingType (expr_type));
                                expr = ExplicitConversionCore (ec, underlying, target_type, loc);
                                if (expr != null)
                                        return expr;
@@ -1818,7 +1765,7 @@ namespace Mono.CSharp {
                                if (expr_type == TypeManager.enum_type)
                                        return new UnboxCast (expr, target_type);
 
-                               Expression ce = ExplicitConversionCore (ec, expr, TypeManager.GetEnumUnderlyingType (target_type), loc);
+                               Expression ce = ExplicitConversionCore (ec, expr, EnumSpec.GetUnderlyingType (target_type), loc);
                                if (ce != null)
                                        return EmptyCast.Create (ce, target_type);
                                
@@ -1826,7 +1773,7 @@ namespace Mono.CSharp {
                                // LAMESPEC: IntPtr and UIntPtr conversion to any Enum is allowed
                                //
                                if (expr_type == TypeManager.intptr_type || expr_type == TypeManager.uintptr_type) {
-                                       ne = ExplicitUserConversion (ec, expr, TypeManager.GetEnumUnderlyingType (target_type), loc);
+                                       ne = ExplicitUserConversion (ec, expr, EnumSpec.GetUnderlyingType (target_type), loc);
                                        if (ne != null)
                                                return ExplicitConversionCore (ec, ne, target_type, loc);
                                }
@@ -1858,9 +1805,9 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public static Expression ExplicitUnsafe (Expression expr, Type target_type)
+               public static Expression ExplicitUnsafe (Expression expr, TypeSpec target_type)
                {
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
 
                        if (target_type.IsPointer){
                                if (expr_type.IsPointer)
@@ -1908,7 +1855,7 @@ namespace Mono.CSharp {
                ///   Same as ExplicitConversion, only it doesn't include user defined conversions
                /// </summary>
                static public Expression ExplicitConversionStandard (ResolveContext ec, Expression expr,
-                                                                    Type target_type, Location l)
+                                                                    TypeSpec target_type, Location l)
                {
                        int errors = ec.Report.Errors;
                        Expression ne = ImplicitConversionStandard (ec, expr, target_type, l);
@@ -1938,7 +1885,7 @@ namespace Mono.CSharp {
                ///   type is expr.Type to `target_type'.
                /// </summary>
                static public Expression ExplicitConversion (ResolveContext ec, Expression expr,
-                       Type target_type, Location loc)
+                       TypeSpec target_type, Location loc)
                {
                        Expression e = ExplicitConversionCore (ec, expr, target_type, loc);
                        if (e != null) {
@@ -1956,10 +1903,10 @@ namespace Mono.CSharp {
                                return e;
                        }
 
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
                        if (TypeManager.IsNullableType (target_type)) {
                                if (TypeManager.IsNullableType (expr_type)) {
-                                       Type target = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (target_type)[0]);
+                                       TypeSpec target = TypeManager.GetTypeArguments (target_type)[0];
                                        Expression unwrap = Nullable.Unwrap.Create (expr);
                                        e = ExplicitConversion (ec, unwrap, target, expr.Location);
                                        if (e == null)
@@ -1969,7 +1916,7 @@ namespace Mono.CSharp {
                                } else if (expr_type == TypeManager.object_type) {
                                        return new UnboxCast (expr, target_type);
                                } else {
-                                       Type target = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (target_type) [0]);
+                                       TypeSpec target = TypeManager.GetTypeArguments (target_type) [0];
 
                                        e = ExplicitConversionCore (ec, expr, target, loc);
                                        if (e != null)
index 51b50955b8083df4e559667e9005fb243fa1d8fe..b983dacf0582917c8d058ded794924aa4803c7a8 100644 (file)
@@ -3008,7 +3008,7 @@ primary_expression_no_array_creation
        | IDENTIFIER opt_type_argument_list
          {
                var lt = (Tokenizer.LocatedToken) $1;
-               $$ = new SimpleName (MemberName.MakeName (lt.Value, (TypeArguments)$2), (TypeArguments)$2, lt.Location);          
+               $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);   
          }
        | IDENTIFIER GENERATE_COMPLETION {
                var lt = (Tokenizer.LocatedToken) $1;
@@ -3554,7 +3554,7 @@ rank_specifiers
        : rank_specifier
        | rank_specifier rank_specifiers
          {
-               $$ = (string) $2 + (string) $1;
+               $$ = (string) $1 + (string) $2;
          }
        ;
 
@@ -3658,14 +3658,14 @@ unbound_type_name
          {  
                var lt = (Tokenizer.LocatedToken) $1;
 
-               $$ = new SimpleName (MemberName.MakeName (lt.Value, (int)$2), lt.Location);
+               $$ = new SimpleName (lt.Value, (int) $2, lt.Location);
          }
        | qualified_alias_member IDENTIFIER generic_dimension
          {
                var lt1 = (Tokenizer.LocatedToken) $1;
                var lt2 = (Tokenizer.LocatedToken) $2;
 
-               $$ = new QualifiedAliasMember (lt1.Value, MemberName.MakeName (lt2.Value, (int) $3), lt1.Location);
+               $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
          }
        | unbound_type_name DOT IDENTIFIER
          {
@@ -3677,14 +3677,14 @@ unbound_type_name
          {
                var lt = (Tokenizer.LocatedToken) $3;
                
-               $$ = new MemberAccess ((Expression) $1, MemberName.MakeName (lt.Value, (int) $4), lt.Location);         
+               $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);               
          }
        | namespace_or_type_name DOT IDENTIFIER generic_dimension
          {
                var lt = (Tokenizer.LocatedToken) $3;
                MemberName name = (MemberName) $1;
 
-               $$ = new MemberAccess (name.GetTypeExpression (), MemberName.MakeName (lt.Value, (int) $4), lt.Location);               
+               $$ = new MemberAccess (name.GetTypeExpression (), lt.Value, (int) $4, lt.Location);             
          }
        ;
 
index 8a3dbae5d2bff827e6e734778a7cf64cb359dc99..cba83b950b9d5e66604335b5a4cd69ee7f06458e 100644 (file)
@@ -103,6 +103,12 @@ namespace Mono.CSharp {
                        return GetName (false);
                }
 
+               public int Arity {
+                       get {
+                               return TypeArguments == null ? 0 : TypeArguments.Count;
+                       }
+               }
+
                public bool IsGeneric {
                        get {
                                if (TypeArguments != null)
@@ -127,7 +133,7 @@ namespace Mono.CSharp {
                {
                        if (Left == null) {
                                if (TypeArguments != null)
-                                       return new SimpleName (Basename, TypeArguments, Location);
+                                       return new SimpleName (Name, TypeArguments, Location);
                                
                                return new SimpleName (Name, Location);
                        }
@@ -247,6 +253,7 @@ namespace Mono.CSharp {
        ///   Base representation for members.  This is used to keep track
        ///   of Name, Location and Modifier flags, and handling Attributes.
        /// </summary>
+       [System.Diagnostics.DebuggerDisplay ("{GetSignatureForError()}")]
        public abstract class MemberCore : Attributable, IMemberContext, IMemberDefinition
        {
                /// <summary>
@@ -263,6 +270,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               string IMemberDefinition.Name {
+                       get {
+                               return member_name.Name;
+                       }
+               }
+
                 // Is not readonly because of IndexerName attribute
                private MemberName member_name;
                public MemberName MemberName {
@@ -284,7 +297,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public /*readonly*/ DeclSpace Parent;
+               public /*readonly*/ TypeContainer Parent;
 
                /// <summary>
                ///   Location where this declaration happens
@@ -313,7 +326,7 @@ namespace Mono.CSharp {
                        CloseTypeCreated = 1 << 4,              // Tracks whether we have Closed the type
                        HasCompliantAttribute_Undetected = 1 << 5,      // Presence of CLSCompliantAttribute has not been detected
                        HasClsCompliantAttribute = 1 << 6,                      // Type has CLSCompliantAttribute
-                       ClsCompliantAttributeTrue = 1 << 7,                     // Type has CLSCompliant (true)
+                       ClsCompliantAttributeFalse = 1 << 7,                    // Member has CLSCompliant(false)
                        Excluded_Undetected = 1 << 8,           // Conditional attribute has not been detected yet
                        Excluded = 1 << 9,                                      // Method is conditional
                        MethodOverloadsExist = 1 << 10,         // Test for duplication must be performed
@@ -331,12 +344,16 @@ namespace Mono.CSharp {
 
                public MemberCore (DeclSpace parent, MemberName name, Attributes attrs)
                {
-                       this.Parent = parent;
+                       this.Parent = parent as TypeContainer;
                        member_name = name;
                        caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected;
                        AddAttributes (attrs, this);
                }
 
+               public virtual Assembly Assembly {
+                       get { return Parent.Module.Assembly; }
+               }
+
                protected virtual void SetMemberName (MemberName new_name)
                {
                        member_name = new_name;
@@ -439,8 +456,7 @@ namespace Mono.CSharp {
                        if (!RootContext.VerifyClsCompliance)
                                return;
 
-                       if (Report.WarningLevel > 0)
-                               VerifyClsCompliance ();
+                       VerifyClsCompliance ();
                }
 
                public bool IsCompilerGenerated {
@@ -452,6 +468,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool IsImported {
+                       get {
+                               return false;
+                       }
+               }
+
                public virtual bool IsUsed {
                        get { return (caching_flags & Flags.IsUsed) != 0; }
                }
@@ -467,10 +489,15 @@ namespace Mono.CSharp {
                        caching_flags |= Flags.IsUsed;
                }
 
+               public void SetIsAssigned ()
+               {
+                       caching_flags |= Flags.IsAssigned;
+               }
+
                /// <summary>
                /// Returns instance of ObsoleteAttribute for this MemberCore
                /// </summary>
-               public virtual ObsoleteAttribute GetObsoleteAttribute ()
+               public virtual ObsoleteAttribute GetAttributeObsolete ()
                {
                        if ((caching_flags & (Flags.Obsolete_Undetected | Flags.Obsolete)) == 0)
                                return null;
@@ -498,44 +525,15 @@ namespace Mono.CSharp {
                /// </summary>
                public virtual void CheckObsoleteness (Location loc)
                {
-                       ObsoleteAttribute oa = GetObsoleteAttribute ();
+                       ObsoleteAttribute oa = GetAttributeObsolete ();
                        if (oa != null)
                                AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, Report);
                }
 
-               //
-               // Returns the access level for type `t'
-               //
-               static Modifiers GetAccessLevelFromType (Type type)
-               {
-                       var ma = type.Attributes;
-                       Modifiers mod;
-                       switch (ma & TypeAttributes.VisibilityMask) {
-                       case TypeAttributes.Public:
-                       case TypeAttributes.NestedPublic:
-                               mod = Modifiers.PUBLIC;
-                               break;
-                       case TypeAttributes.NestedPrivate:
-                               mod = Modifiers.PRIVATE;
-                               break;
-                       case TypeAttributes.NestedFamily:
-                               mod = Modifiers.PROTECTED;
-                               break;
-                       case TypeAttributes.NestedFamORAssem:
-                               mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
-                               break;
-                       default:
-                               mod = Modifiers.INTERNAL;
-                               break;
-                       }
-
-                       return mod;
-               }
-
                //
                // Checks whether the type P is as accessible as this member
                //
-               public bool IsAccessibleAs (Type p)
+               public bool IsAccessibleAs (TypeSpec p)
                {
                        //
                        // if M is private, its accessibility is the same as this declspace.
@@ -548,19 +546,20 @@ namespace Mono.CSharp {
                        while (TypeManager.HasElementType (p))
                                p = TypeManager.GetElementType (p);
 
-                       if (TypeManager.IsGenericParameter (p))
+                       if (p.IsGenericParameter)
                                return true;
 
-                       if (TypeManager.IsGenericType (p)) {
-                               foreach (Type t in TypeManager.GetTypeArguments (p)) {
-                                       if (!IsAccessibleAs (t))
-                                               return false;
+                       for (TypeSpec p_parent; p != null; p = p_parent) {
+                               p_parent = p.DeclaringType;
+
+                               if (p.IsGeneric) {
+                                       foreach (TypeSpec t in p.TypeArguments) {
+                                               if (!IsAccessibleAs (t))
+                                                       return false;
+                                       }
                                }
-                       }
 
-                       for (Type p_parent = null; p != null; p = p_parent) {
-                               p_parent = p.DeclaringType;
-                               var pAccess = GetAccessLevelFromType (p);
+                               var pAccess = p.Modifiers & Modifiers.AccessibilityMask;
                                if (pAccess == Modifiers.PUBLIC)
                                        continue;
 
@@ -576,7 +575,7 @@ namespace Mono.CSharp {
 
                                        case Modifiers.PROTECTED:
                                                if (al == Modifiers.PROTECTED) {
-                                                       same_access_restrictions = mc.Parent.IsBaseType (p_parent);
+                                                       same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent);
                                                        break;
                                                }
 
@@ -586,7 +585,7 @@ namespace Mono.CSharp {
                                                        // protected type then the type is accessible
                                                        //
                                                        while (mc.Parent != null) {
-                                                               if (mc.Parent.IsBaseType (p_parent))
+                                                               if (mc.Parent.IsBaseTypeDefinition (p_parent))
                                                                        same_access_restrictions = true;
                                                                mc = mc.Parent; 
                                                        }
@@ -598,9 +597,9 @@ namespace Mono.CSharp {
                                                if (al == Modifiers.INTERNAL)
                                                        same_access_restrictions = TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, p.Assembly);
                                                else if (al == Modifiers.PROTECTED)
-                                                       same_access_restrictions = mc.Parent.IsBaseType (p_parent);
+                                                       same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent);
                                                else if (al == (Modifiers.PROTECTED | Modifiers.INTERNAL))
-                                                       same_access_restrictions = mc.Parent.IsBaseType (p_parent) &&
+                                                       same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent) &&
                                                                TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, p.Assembly);
                                                break;
 
@@ -611,7 +610,7 @@ namespace Mono.CSharp {
                                                if (al == Modifiers.PRIVATE) {
                                                        var decl = mc.Parent;
                                                        do {
-                                                               same_access_restrictions = TypeManager.IsEqual (decl.TypeBuilder, p_parent);
+                                                               same_access_restrictions = decl.CurrentType == p_parent;
                                                        } while (!same_access_restrictions && !decl.IsTopLevel && (decl = decl.Parent) != null);
                                                }
                                                
@@ -637,16 +636,29 @@ namespace Mono.CSharp {
                        if ((caching_flags & Flags.ClsCompliance_Undetected) == 0)
                                return (caching_flags & Flags.ClsCompliant) != 0;
 
-                       if (GetClsCompliantAttributeValue () && IsExposedFromAssembly ()) {
-                               caching_flags &= ~Flags.ClsCompliance_Undetected;
+                       caching_flags &= ~Flags.ClsCompliance_Undetected;
+
+                       if (HasClsCompliantAttribute) {
+                               if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0)
+                                       return false;
+
+                               caching_flags |= Flags.ClsCompliant;
+                               return true;
+                       }
+
+                       if (Parent.PartialContainer.IsClsComplianceRequired ()) {
                                caching_flags |= Flags.ClsCompliant;
                                return true;
                        }
 
-                       caching_flags &= ~Flags.ClsCompliance_Undetected;
                        return false;
                }
 
+               public virtual string[] ConditionalConditions ()
+               {
+                       return null;
+               }
+
                /// <summary>
                /// Returns true when MemberCore is exposed from assembly.
                /// </summary>
@@ -664,9 +676,9 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public virtual ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+               public virtual ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
                {
-                       return Parent.LookupExtensionMethod (extensionType, name, loc);
+                       return Parent.LookupExtensionMethod (extensionType, name, arity, loc);
                }
 
                public virtual FullNamedExpression LookupNamespaceAlias (string name)
@@ -674,42 +686,34 @@ namespace Mono.CSharp {
                        return Parent.NamespaceEntry.LookupNamespaceAlias (name);
                }
 
-               public virtual FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               public virtual FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
                {
-                       return Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                       return Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
                }
 
                /// <summary>
                /// Goes through class hierarchy and gets value of first found CLSCompliantAttribute.
                /// If no is attribute exists then assembly CLSCompliantAttribute is returned.
                /// </summary>
-               public virtual bool GetClsCompliantAttributeValue ()
+               public bool IsNotCLSCompliant ()
                {
                        if ((caching_flags & Flags.HasCompliantAttribute_Undetected) == 0)
-                               return (caching_flags & Flags.ClsCompliantAttributeTrue) != 0;
+                               return (caching_flags & Flags.ClsCompliantAttributeFalse) != 0;
 
                        caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
 
                        if (OptAttributes != null) {
-                               Attribute cls_attribute = OptAttributes.Search (
-                                       PredefinedAttributes.Get.CLSCompliant);
+                               Attribute cls_attribute = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
                                if (cls_attribute != null) {
                                        caching_flags |= Flags.HasClsCompliantAttribute;
-                                       bool value = cls_attribute.GetClsCompliantAttributeValue ();
-                                       if (value)
-                                               caching_flags |= Flags.ClsCompliantAttributeTrue;
-                                       return value;
+                                       if (cls_attribute.GetClsCompliantAttributeValue ())
+                                               return false;
+
+                                       caching_flags |= Flags.ClsCompliantAttributeFalse;
+                                       return true;
                                }
                        }
-                       
-                       // It's null for TypeParameter
-                       if (Parent == null)
-                               return false;                   
 
-                       if (Parent.GetClsCompliantAttributeValue ()) {
-                               caching_flags |= Flags.ClsCompliantAttributeTrue;
-                               return true;
-                       }
                        return false;
                }
 
@@ -719,7 +723,7 @@ namespace Mono.CSharp {
                protected bool HasClsCompliantAttribute {
                        get {
                                if ((caching_flags & Flags.HasCompliantAttribute_Undetected) != 0)
-                                       GetClsCompliantAttributeValue ();
+                                       IsNotCLSCompliant ();
                                
                                return (caching_flags & Flags.HasClsCompliantAttribute) != 0;
                        }
@@ -741,41 +745,55 @@ namespace Mono.CSharp {
                /// </summary>
                protected virtual bool VerifyClsCompliance ()
                {
-                       if (!IsClsComplianceRequired ()) {
-                               if (HasClsCompliantAttribute && Report.WarningLevel >= 2) {
-                                       if (!IsExposedFromAssembly ()) {
-                                               Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
-                                               Report.Warning (3019, 2, a.Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ());
-                                       }
-
-                                       if (!CodeGen.Assembly.IsClsCompliant) {
-                                               Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
-                                               Report.Warning (3021, 2, a.Location, "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant", GetSignatureForError ());
+                       if (HasClsCompliantAttribute) {
+                               if (CodeGen.Assembly.ClsCompliantAttribute == null) {
+                                       Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
+                                       if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) {
+                                               Report.Warning (3021, 2, a.Location,
+                                                       "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant",
+                                                       GetSignatureForError ());
+                                       } else {
+                                               Report.Warning (3014, 1, a.Location,
+                                                       "`{0}' cannot be marked as CLS-compliant because the assembly is not marked as CLS-compliant",
+                                                       GetSignatureForError ());
                                        }
+                                       return false;
                                }
-                               return false;
-                       }
 
-                       if (HasClsCompliantAttribute) {
-                               if (CodeGen.Assembly.ClsCompliantAttribute == null && !CodeGen.Assembly.IsClsCompliant) {
+                               if (!IsExposedFromAssembly ()) {
                                        Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
-                                       Report.Warning (3014, 1, a.Location,
-                                               "`{0}' cannot be marked as CLS-compliant because the assembly is not marked as CLS-compliant",
-                                               GetSignatureForError ());
+                                       Report.Warning (3019, 2, a.Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ());
+                                       return false;
+                               }
+
+                               if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) {
+                                       if (Parent.Kind == MemberKind.Interface && Parent.IsClsComplianceRequired ()) {
+                                               Report.Warning (3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
+                                       } else if (Parent.Kind == MemberKind.Class && (ModFlags & Modifiers.ABSTRACT) != 0 && Parent.IsClsComplianceRequired ()) {
+                                               Report.Warning (3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
+                                       }
+
                                        return false;
                                }
 
-                               if (!Parent.IsClsComplianceRequired ()) {
+                               if (Parent.Parent != null && !Parent.IsClsComplianceRequired ()) {
                                        Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant);
-                                       Report.Warning (3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'", 
+                                       Report.Warning (3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'",
                                                GetSignatureForError (), Parent.GetSignatureForError ());
                                        return false;
                                }
+                       } else {
+                               if (!IsExposedFromAssembly ())
+                                       return false;
+
+                               if (!Parent.PartialContainer.IsClsComplianceRequired ())
+                                       return false;
                        }
 
                        if (member_name.Name [0] == '_') {
                                Report.Warning (3008, 1, Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError () );
                        }
+
                        return true;
                }
 
@@ -815,24 +833,28 @@ namespace Mono.CSharp {
                #region IMemberContext Members
 
                public virtual CompilerContext Compiler {
-                       get { return Parent.Module.Compiler; }
+                       get { return Parent.Compiler; }
                }
 
-               public virtual Type CurrentType {
+               public virtual TypeSpec CurrentType {
                        get { return Parent.CurrentType; }
                }
 
-               public virtual TypeContainer CurrentTypeDefinition {
-                       get { return Parent.CurrentTypeDefinition; }
+               public MemberCore CurrentMemberDefinition {
+                       get { return this; }
                }
 
                public virtual TypeParameter[] CurrentTypeParameters {
                        get { return null; }
                }
 
+               public virtual bool HasUnresolvedConstraints {
+                       get { return false; }
+               }
+
                public bool IsObsolete {
                        get {
-                               if (GetObsoleteAttribute () != null)
+                               if (GetAttributeObsolete () != null)
                                        return true;
 
                                return Parent == null ? false : Parent.IsObsolete;
@@ -849,7 +871,9 @@ namespace Mono.CSharp {
                }
 
                public bool IsStatic {
-                       get { return (ModFlags & Modifiers.STATIC) != 0; }
+                       get {
+                               return (ModFlags & Modifiers.STATIC) != 0;
+                       }
                }
 
                #endregion
@@ -865,54 +889,210 @@ namespace Mono.CSharp {
                protected enum StateFlags
                {
                        Obsolete_Undetected = 1,        // Obsolete attribute has not been detected yet
-                       Obsolete = 1 << 1                       // Member has obsolete attribute
+                       Obsolete = 1 << 1,                      // Member has obsolete attribute
+                       CLSCompliant_Undetected = 1 << 3,       // CLSCompliant attribute has not been detected yet
+                       CLSCompliant = 1 << 4,          // Member is CLS Compliant
+
+                       IsAccessor = 1 << 9,            // Method is an accessor
+                       IsGeneric = 1 << 10,            // Member contains type arguments
+
+                       PendingMetaInflate = 1 << 12,
+                       PendingMakeMethod = 1 << 13,
+                       PendingMemberCacheMembers = 1 << 14,
+                       PendingBaseTypeInflate = 1 << 15,
+                       InterfacesExpanded = 1 << 16,
+                       IsNotRealProperty = 1 << 17,
                }
 
-               readonly Modifiers modifiers;
-               readonly string name;
+               protected Modifiers modifiers;
                protected StateFlags state;
                protected IMemberDefinition definition;
                public readonly MemberKind Kind;
+               protected TypeSpec declaringType;
+
+#if DEBUG
+               static int counter;
+               public int ID = counter++;
+#endif
 
-               protected MemberSpec (MemberKind kind, IMemberDefinition definition, string name, Modifiers modifiers)
+               protected MemberSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition definition, Modifiers modifiers)
                {
+                       this.Kind = kind;
+                       this.declaringType = declaringType;
                        this.definition = definition;
-                       this.name = name;
                        this.modifiers = modifiers;
 
-                       state = StateFlags.Obsolete_Undetected;
+                       state = StateFlags.Obsolete_Undetected | StateFlags.CLSCompliant_Undetected;
+               }
+
+               #region Properties
+
+               public Assembly Assembly {
+                       get {
+                               return definition.Assembly;
+                       }
+               }
+
+               public virtual int Arity {
+                       get {
+                               return 0;
+                       }
+               }
+
+               public TypeSpec DeclaringType {
+                       get {
+                               return declaringType;
+                       }
+                       set {
+                               declaringType = value;
+                       }
+               }
+
+               public IMemberDefinition MemberDefinition {
+                       get {
+                               return definition;
+                       }
+               }
+
+               public Modifiers Modifiers {
+                       get {
+                               return modifiers;
+                       }
+                       set {
+                               modifiers = value;
+                       }
+               }
+               
+               public virtual string Name {
+                       get {
+                               return definition.Name;
+                       }
+               }
+
+               public bool IsAbstract {
+                       get { return (modifiers & Modifiers.ABSTRACT) != 0; }
+               }
+
+               public bool IsAccessor {
+                       get {
+                               return (state & StateFlags.IsAccessor) != 0;
+                       }
+                       set {
+                               state = value ? state | StateFlags.IsAccessor : state & ~StateFlags.IsAccessor;
+                       }
+               }
+
+               //
+               // Return true when this member is a generic in C# terms
+               // therefore nested non-generic type of generic type will
+               // return false
+               //
+               public bool IsGeneric {
+                       get {
+                               return (state & StateFlags.IsGeneric) != 0;
+                       }
+                       set {
+                               state = value ? state | StateFlags.IsGeneric : state & ~StateFlags.IsGeneric;
+                       }
+               }
+
+               public bool IsPrivate {
+                       get { return (modifiers & Modifiers.PRIVATE) != 0; }
+               }
+
+               public bool IsStatic {
+                       get { 
+                               return (modifiers & Modifiers.STATIC) != 0;
+                       }
                }
 
-               public abstract Type DeclaringType { get; }
+               #endregion
 
-               public ObsoleteAttribute GetObsoleteAttribute ()
+               public virtual ObsoleteAttribute GetAttributeObsolete ()
                {
                        if ((state & (StateFlags.Obsolete | StateFlags.Obsolete_Undetected)) == 0)
                                return null;
 
                        state &= ~StateFlags.Obsolete_Undetected;
 
-                       var oa = definition.GetObsoleteAttribute ();
+                       var oa = definition.GetAttributeObsolete ();
                        if (oa != null)
                                state |= StateFlags.Obsolete;
 
                        return oa;
                }
 
-               public IMemberDefinition MemberDefinition {
-                       get { return definition; }
+               protected virtual bool IsNotCLSCompliant ()
+               {
+                       return MemberDefinition.IsNotCLSCompliant ();
                }
 
-               public Modifiers Modifiers {
-                       get { return modifiers; }
+               public virtual string GetSignatureForError ()
+               {
+                       var bf = MemberDefinition as Property.BackingField;
+                       var name = bf == null ? Name : bf.OriginalName;
+                       return DeclaringType.GetSignatureForError () + "." + name;
                }
-               
-               public string Name {
-                       get { return name; }
+
+               public virtual MemberSpec InflateMember (TypeParameterInflator inflator)
+               {
+                       var inflated = (MemberSpec) MemberwiseClone ();
+                       inflated.declaringType = inflator.TypeInstance;
+                       inflated.state |= StateFlags.PendingMetaInflate;
+                       return inflated;
                }
 
-               public bool IsStatic {
-                       get { return (modifiers & Modifiers.STATIC) != 0; }
+               //
+               // Returns member CLS compliance based on full member hierarchy
+               //
+               public bool IsCLSCompliant ()
+               {
+                       if ((state & StateFlags.CLSCompliant_Undetected) != 0) {
+                               state &= ~StateFlags.CLSCompliant_Undetected;
+
+                               if (IsNotCLSCompliant ())
+                                       return false;
+
+                               bool compliant;
+                               if (DeclaringType != null) {
+                                       compliant = DeclaringType.IsCLSCompliant ();
+                               } else {
+                                       // TODO: NEED AssemblySpec
+                                       if (MemberDefinition.IsImported) {
+                                               var attr = MemberDefinition.Assembly.GetCustomAttributes (typeof (CLSCompliantAttribute), false);
+                                               compliant = attr.Length > 0 && ((CLSCompliantAttribute) attr[0]).IsCompliant;
+                                       } else {
+                                               compliant = CodeGen.Assembly.IsClsCompliant;
+                                       }
+                               }
+
+                               if (compliant)
+                                       state |= StateFlags.CLSCompliant;
+                       }
+
+                       return (state & StateFlags.CLSCompliant) != 0;
+               }
+
+               public bool IsConditionallyExcluded (Location loc)
+               {
+                       if ((Kind & (MemberKind.Class | MemberKind.Method)) == 0)
+                               return false;
+
+                       var conditions = MemberDefinition.ConditionalConditions ();
+                       if (conditions == null)
+                               return false;
+
+                       foreach (var condition in conditions) {
+                               if (loc.CompilationUnit.IsConditionalDefined (condition))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               public override string ToString ()
+               {
+                       return GetSignatureForError ();
                }
        }
 
@@ -922,18 +1102,32 @@ namespace Mono.CSharp {
        //
        public interface IMemberDefinition
        {
-               ObsoleteAttribute GetObsoleteAttribute ();
+               Assembly Assembly { get; }
+               string Name { get; }
+               bool IsImported { get; }
+
+               string[] ConditionalConditions ();
+               ObsoleteAttribute GetAttributeObsolete ();
+               bool IsNotCLSCompliant ();
+               void SetIsAssigned ();
                void SetIsUsed ();
        }
 
-       /// <summary>
-       ///   Base class for structs, classes, enumerations and interfaces.  
-       /// </summary>
-       /// <remarks>
-       ///   They all create new declaration spaces.  This
-       ///   provides the common foundation for managing those name
-       ///   spaces.
-       /// </remarks>
+       public interface IParametersMember : IInterfaceMemberSpec
+       {
+               AParametersCollection Parameters { get; }
+       }
+
+       public interface IInterfaceMemberSpec
+       {
+               TypeSpec MemberType { get; }
+       }
+
+       //
+       // Base type container declaration. It exists to handle partial types
+       // which share same definition (PartialContainer) but have different
+       // resolve scopes
+       //
        public abstract class DeclSpace : MemberCore {
                /// <summary>
                ///   This points to the actual definition that is being
@@ -941,13 +1135,6 @@ namespace Mono.CSharp {
                /// </summary>
                public TypeBuilder TypeBuilder;
 
-               /// <summary>
-               ///   If we are a generic type, this is the type we are
-               ///   currently defining.  We need to lookup members on this
-               ///   instead of the TypeBuilder.
-               /// </summary>
-               protected Type currentType;
-
                //
                // This is the namespace in which this typecontainer
                // was declared.  We use this to resolve names.
@@ -1058,11 +1245,7 @@ namespace Mono.CSharp {
                        defined_names.TryGetValue (name, out mc);
                        return mc;
                }
-
-               public bool IsStaticClass {
-                       get { return (ModFlags & Modifiers.STATIC) != 0; }
-               }
-               
+       
                // 
                // root_types contains all the types.  All TopLevel types
                // hence have a parent that points to `root_types', that is
@@ -1077,27 +1260,6 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public virtual void CloseType ()
-               {
-                       if ((caching_flags & Flags.CloseTypeCreated) == 0){
-                               try {
-                                       TypeBuilder.CreateType ();
-                               } catch {
-                                       //
-                                       // The try/catch is needed because
-                                       // nested enumerations fail to load when they
-                                       // are defined.
-                                       //
-                                       // Even if this is the right order (enumerations
-                                       // declared after types).
-                                       //
-                                       // Note that this still creates the type and
-                                       // it is possible to save it
-                               }
-                               caching_flags |= Flags.CloseTypeCreated;
-                       }
-               }
-
                protected virtual TypeAttributes TypeAttr {
                        get { return Module.DefaultCharSetType; }
                }
@@ -1114,157 +1276,71 @@ namespace Mono.CSharp {
                                type.GetSignatureForError ());
                }
 
-               public override void Emit ()
-               {
-                       if (type_params != null) {
-                               int offset = count_type_params - type_params.Length;
-                               for (int i = offset; i < type_params.Length; i++)
-                                       CurrentTypeParameters [i - offset].Emit ();
-                       }
-
-                       if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
-                               PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (TypeBuilder);
-
-                       base.Emit ();
-               }
-
                public override string GetSignatureForError ()
-               {       
+               {
                        return MemberName.GetSignatureForError ();
                }
                
-               public bool CheckAccessLevel (Type check_type)
+               public bool CheckAccessLevel (TypeSpec check_type)
                {
-                       Type tb = TypeBuilder;
+                       TypeSpec tb = PartialContainer.Definition;
+                       check_type = check_type.GetDefinition ();
 
-                       if (this is GenericMethod) {
-                               tb = Parent.TypeBuilder;
-
-                               // FIXME: Generic container does not work with nested generic
-                               // anonymous method stories
-                               if (TypeBuilder == null)
-                                       return true;
-                       }
-
-                       check_type = TypeManager.DropGenericTypeArguments (check_type);
-                       if (check_type == tb)
-                               return true;
-
-                       // TODO: When called from LocalUsingAliasEntry tb is null
-                       // because we are in RootDeclSpace
-                       if (tb == null)
-                               tb = typeof (RootDeclSpace);
-
-                       //
-                       // Broken Microsoft runtime, return public for arrays, no matter what 
-                       // the accessibility is for their underlying class, and they return 
-                       // NonPublic visibility for pointers
-                       //
-                       if (TypeManager.HasElementType (check_type))
-                               return CheckAccessLevel (TypeManager.GetElementType (check_type));
-
-                       if (TypeManager.IsGenericParameter (check_type))
-                               return true;
-
-                       TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
+                       var check_attr = check_type.Modifiers & Modifiers.AccessibilityMask;
 
                        switch (check_attr){
-                       case TypeAttributes.Public:
+                       case Modifiers.PUBLIC:
                                return true;
 
-                       case TypeAttributes.NotPublic:
-                               return TypeManager.IsThisOrFriendAssembly (Module.Assembly, check_type.Assembly);
+                       case Modifiers.INTERNAL:
+                               return TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly);
                                
-                       case TypeAttributes.NestedPublic:
-                               return CheckAccessLevel (check_type.DeclaringType);
+                       case Modifiers.PRIVATE:
+                               TypeSpec declaring = check_type.DeclaringType;
+                               return tb == declaring.GetDefinition () || TypeManager.IsNestedChildOf (tb, declaring); 
 
-                       case TypeAttributes.NestedPrivate:
-                               Type declaring = check_type.DeclaringType;
-                               return tb == declaring || TypeManager.IsNestedChildOf (tb, declaring);  
-
-                       case TypeAttributes.NestedFamily:
+                       case Modifiers.PROTECTED:
                                //
                                // Only accessible to methods in current type or any subtypes
                                //
-                               return FamilyAccessible (tb, check_type);
-
-                       case TypeAttributes.NestedFamANDAssem:
-                               return TypeManager.IsThisOrFriendAssembly (Module.Assembly, check_type.Assembly) && 
-                                       FamilyAccessible (tb, check_type);
+                               return TypeManager.IsNestedFamilyAccessible (tb, check_type.DeclaringType);
 
-                       case TypeAttributes.NestedFamORAssem:
-                               return FamilyAccessible (tb, check_type) ||
-                                       TypeManager.IsThisOrFriendAssembly (Module.Assembly, check_type.Assembly);
+                       case Modifiers.PROTECTED | Modifiers.INTERNAL:
+                               if (TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly))
+                                       return true;
 
-                       case TypeAttributes.NestedAssembly:
-                               return TypeManager.IsThisOrFriendAssembly (Module.Assembly, check_type.Assembly);
+                               goto case Modifiers.PROTECTED;
                        }
 
                        throw new NotImplementedException (check_attr.ToString ());
                }
 
-               static bool FamilyAccessible (Type tb, Type check_type)
-               {
-                       Type declaring = check_type.DeclaringType;
-                       return TypeManager.IsNestedFamilyAccessible (tb, declaring);
-               }
-
-               public bool IsBaseType (Type baseType)
+               private TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
                {
-                       // We are called from RootDeclspace
-                       if (TypeBuilder == null)
-                               return false;
-
-                       return TypeManager.IsSubclassOf (TypeBuilder, baseType);
-               }
-
-               private Type LookupNestedTypeInHierarchy (string name)
-               {
-                       Type t = null;
-                       // if the member cache has been created, lets use it.
-                       // the member cache is MUCH faster.
-                       if (MemberCache != null) {
-                               t = MemberCache.FindNestedType (name);
-                               if (t == null)
-                                       return null;
-                       }
-
-                       //
-                       // FIXME: This hack is needed because member cache does not work
-                       // with nested base generic types, it does only type name copy and
-                       // not type construction
-                       //
+                       // TODO: GenericMethod only
+                       if (PartialContainer == null)
+                               return null;
 
-                       // no member cache. Do it the hard way -- reflection
-                       for (Type current_type = TypeBuilder;
-                            current_type != null && current_type != TypeManager.object_type;
-                            current_type = current_type.BaseType) {
-
-                               Type ct = TypeManager.DropGenericTypeArguments (current_type);
-                               if (ct is TypeBuilder) {
-                                       TypeContainer tc = ct == TypeBuilder
-                                               ? PartialContainer : TypeManager.LookupTypeContainer (ct);
-                                       if (tc != null)
-                                               t = tc.FindNestedType (name);
-                               } else {
-                                       t = TypeManager.GetNestedType (ct, name);
-                               }
+                       // Has any nested type
+                       // Does not work, because base type can have
+                       //if (PartialContainer.Types == null)
+                       //      return null;
 
-                               if ((t == null) || !CheckAccessLevel (t))
-                                       continue;
+                       var container = PartialContainer.CurrentType;
 
-                               if (!TypeManager.IsGenericType (current_type))
-                                       return t;
+                       // Is not Root container
+                       if (container == null)
+                               return null;
 
-                               Type[] args = TypeManager.GetTypeArguments (current_type);
-                               Type[] targs = TypeManager.GetTypeArguments (t);
-                               for (int i = 0; i < args.Length; i++)
-                                       targs [i] = TypeManager.TypeToCoreType (args [i]);
+                       var     t = MemberCache.FindNestedType (container, name, arity);
+                       if (t == null)
+                               return null;
 
-                               return t.MakeGenericType (targs);
-                       }
+                       // FIXME: Breaks error reporting
+                       if (!CheckAccessLevel (t))
+                               return null;
 
-                       return null;
+                       return t;
                }
 
                //
@@ -1274,74 +1350,50 @@ namespace Mono.CSharp {
                //
                // Returns: Type or null if they type can not be found.
                //
-               public override FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               public override FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
                {
                        FullNamedExpression e;
-                       if (Cache.TryGetValue (name, out e))
+                       if (arity == 0 && Cache.TryGetValue (name, out e))
                                return e;
 
                        e = null;
                        int errors = Report.Errors;
 
-                       TypeParameter[] tp = CurrentTypeParameters;
-                       if (tp != null) {
-                               TypeParameter tparam = TypeParameter.FindTypeParameter (tp, name);
-                               if (tparam != null)
-                                       e = new TypeParameterExpr (tparam, Location.Null);
+                       if (arity == 0) {
+                               TypeParameter[] tp = CurrentTypeParameters;
+                               if (tp != null) {
+                                       TypeParameter tparam = TypeParameter.FindTypeParameter (tp, name);
+                                       if (tparam != null)
+                                               e = new TypeParameterExpr (tparam, Location.Null);
+                               }
                        }
 
                        if (e == null) {
-                               Type t = LookupNestedTypeInHierarchy (name);
+                               TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
 
                                if (t != null)
                                        e = new TypeExpression (t, Location.Null);
                                else if (Parent != null)
-                                       e = Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                                       e = Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
                                else
-                                       e = NamespaceEntry.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                                       e = NamespaceEntry.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
                        }
 
-                       if (errors == Report.Errors)
+                       // TODO MemberCache: How to cache arity stuff ?
+                       if (errors == Report.Errors && arity == 0)
                                Cache [name] = e;
                        
                        return e;
                }
 
-               /// <remarks>
-               ///   This function is broken and not what you're looking for.  It should only
-               ///   be used while the type is still being created since it doesn't use the cache
-               ///   and relies on the filter doing the member name check.
-               /// </remarks>
-               ///
-               // [Obsolete ("Only MemberCache approach should be used")]
-               public virtual MemberList FindMembers (MemberTypes mt, BindingFlags bf,
-                                                       MemberFilter filter, object criteria)
-               {
-                       throw new NotSupportedException ();
-               }
-
-               /// <remarks>
-               ///   If we have a MemberCache, return it.  This property may return null if the
-               ///   class doesn't have a member cache or while it's still being created.
-               /// </remarks>
-               public abstract MemberCache MemberCache {
-                       get;
+               public override Assembly Assembly {
+                       get { return Module.Assembly; }
                }
 
                public virtual ModuleContainer Module {
                        get { return Parent.Module; }
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
-               {
-                       if (a.Type == pa.Required) {
-                               Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
-                               return;
-                       }
-
-                       TypeBuilder.SetCustomAttribute (ctor, cdata);
-               }
-
                TypeParameter[] initialize_type_params ()
                {
                        if (type_param_list != null)
@@ -1427,7 +1479,7 @@ namespace Mono.CSharp {
                                }
 
                                type_params [i] = new TypeParameter (
-                                       Parent, this, name.Name, constraints, name.OptAttributes, variance, Location);
+                                       Parent, i, new MemberName (name.Name, Location), constraints, name.OptAttributes, variance);
 
                                AddToContainer (type_params [i], name.Name);
                        }
@@ -1440,7 +1492,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public TypeParameter[] TypeParameters {
+               protected TypeParameter[] TypeParameters {
                        get {
                                if (!IsGeneric)
                                        throw new InvalidOperationException ();
@@ -1453,26 +1505,12 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Type CurrentType {
-                       get { return currentType != null ? currentType : TypeBuilder; }
-               }
-
-               public override TypeContainer CurrentTypeDefinition {
-                       get { return PartialContainer; }
-               }
-
                public int CountTypeParameters {
                        get {
                                return count_type_params;
                        }
                }
 
-               // Used for error reporting only
-               public virtual Type LookupAnyGeneric (string typeName)
-               {
-                       return NamespaceEntry.NS.LookForAnyGenericType (typeName);
-               }
-
                public override string[] ValidAttributeTargets {
                        get { return attribute_targets; }
                }
@@ -1485,35 +1523,10 @@ namespace Mono.CSharp {
 
                        if (type_params != null) {
                                foreach (TypeParameter tp in type_params) {
-                                       if (tp.Constraints == null)
-                                               continue;
-
-                                       tp.Constraints.VerifyClsCompliance (Report);
+                                       tp.VerifyClsCompliance ();
                                }
                        }
 
-                       var cache = TypeManager.AllClsTopLevelTypes;
-                       if (cache == null)
-                               return true;
-
-                       string lcase = Name.ToLower (System.Globalization.CultureInfo.InvariantCulture);
-                       if (!cache.ContainsKey (lcase)) {
-                               cache.Add (lcase, this);
-                               return true;
-                       }
-
-                       object val = cache [lcase];
-                       if (val == null) {
-                               Type t = AttributeTester.GetImportedIgnoreCaseClsType (lcase);
-                               if (t == null)
-                                       return true;
-                               Report.SymbolRelatedToPreviousError (t);
-                       }
-                       else {
-                               Report.SymbolRelatedToPreviousError ((DeclSpace)val);
-                       }
-
-                       Report.Warning (3005, 1, Location, "Identifier `{0}' differing only in case is not CLS-compliant", GetSignatureForError ());
                        return true;
                }
        }
index c878066f9f94ee143ecd2b4193eeaa922ba081fb..58bc40b01952a42691ad8e37191f6c265f664d48 100644 (file)
@@ -15,6 +15,7 @@
 using System;
 using System.Reflection;
 using System.Reflection.Emit;
+using System.Collections.Generic;
 
 namespace Mono.CSharp {
 
@@ -24,9 +25,8 @@ namespace Mono.CSharp {
        public class Delegate : TypeContainer
        {
                FullNamedExpression ReturnType;
-               public readonly AParametersCollection Parameters;
+               public readonly ParametersCompiled Parameters;
 
-               // TODO: Maybe I can keep member cache only and not the builders
                Constructor Constructor;
                Method InvokeBuilder;
                Method BeginInvokeBuilder;
@@ -60,9 +60,10 @@ namespace Mono.CSharp {
                                                           IsTopLevel ? Modifiers.INTERNAL :
                                                           Modifiers.PRIVATE, name.Location, Report);
                        Parameters      = param_list;
+                       spec = new TypeSpec (Kind, null, this, null, ModFlags | Modifiers.SEALED);
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Target == AttributeTargets.ReturnValue) {
                                if (return_attributes == null)
@@ -81,7 +82,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected override Type BaseType {
+               public override TypeSpec BaseType {
                        get {
                                return TypeManager.multicast_delegate_type;
                        }
@@ -89,20 +90,6 @@ namespace Mono.CSharp {
 
                protected override bool DoDefineMembers ()
                {
-                       if (IsGeneric) {
-                               foreach (TypeParameter type_param in TypeParameters) {
-                                       if (!type_param.Resolve (this))
-                                               return false;
-                               }
-
-                               foreach (TypeParameter type_param in TypeParameters) {
-                                       if (!type_param.DefineType (this))
-                                               return false;
-                               }
-                       }
-
-                       member_cache = new MemberCache (BaseType, this);
-
                        var ctor_parameters = ParametersCompiled.CreateFullyResolved (
                                new [] {
                                        new Parameter (new TypeExpression (TypeManager.object_type, Location), "object", Parameter.Modifier.NONE, null, Location),
@@ -124,7 +111,7 @@ namespace Mono.CSharp {
                        // First, call the `out of band' special method for
                        // defining recursively any types we need:
                        //
-                       var p = Parameters.AsCompiled;
+                       var p = Parameters;
 
                        if (!p.Resolve (this))
                                return false;
@@ -231,12 +218,12 @@ namespace Mono.CSharp {
                        }
 
                        if (out_params > 0) {
-                               var end_param_types = new Type [out_params];
+                               var end_param_types = new TypeSpec [out_params];
                                Parameter[] end_params = new Parameter[out_params];
 
                                int param = 0;
                                for (int i = 0; i < Parameters.FixedParameters.Length; ++i) {
-                                       Parameter p = Parameters.AsCompiled [i];
+                                       Parameter p = Parameters [i];
                                        if ((p.ModFlags & Parameter.Modifier.ISBYREF) == 0)
                                                continue;
 
@@ -262,16 +249,24 @@ namespace Mono.CSharp {
                        EndInvokeBuilder.Define ();
                }
 
-               public override void Emit ()
+               public override void DefineConstants ()
+               {
+                       if (!Parameters.IsEmpty && Parameters[Parameters.Count - 1].HasDefaultValue) {
+                               var rc = new ResolveContext (this);
+                               Parameters.ResolveDefaultValues (rc);
+                       }
+               }
+
+               public override void EmitType ()
                {
-                       if (TypeManager.IsDynamicType (ReturnType.Type)) {
+                       if (ReturnType.Type == InternalType.Dynamic) {
                                return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
                        } else {
                                var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType.Type);
                                if (trans_flags != null) {
                                        var pa = PredefinedAttributes.Get.DynamicTransform;
-                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
                                                return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
                                                return_attributes.Builder.SetCustomAttribute (
                                                        new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
@@ -279,13 +274,13 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       Parameters.AsCompiled.ApplyAttributes (InvokeBuilder.MethodBuilder);
+                       Parameters.ApplyAttributes (InvokeBuilder.MethodBuilder);
                        
                        Constructor.ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
                        InvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
 
                        if (BeginInvokeBuilder != null) {
-                               BeginInvokeBuilder.Parameters.ApplyAttributes (BeginInvokeBuilder.MethodBuilder);
+                               BeginInvokeBuilder.ParameterInfo.ApplyAttributes (BeginInvokeBuilder.MethodBuilder);
 
                                BeginInvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
                                EndInvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
@@ -319,9 +314,9 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       Parameters.AsCompiled.VerifyClsCompliance (this);
+                       Parameters.VerifyClsCompliance (this);
 
-                       if (!AttributeTester.IsClsCompliant (ReturnType.Type)) {
+                       if (!ReturnType.Type.IsCLSCompliant ()) {
                                Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
                                        GetSignatureForError ());
                        }
@@ -329,92 +324,34 @@ namespace Mono.CSharp {
                }
 
 
-               public static MethodSpec GetConstructor (CompilerContext ctx, Type container_type, Type delegate_type)
+               public static MethodSpec GetConstructor (CompilerContext ctx, TypeSpec container_type, TypeSpec delType)
                {
-                       Type dt = delegate_type;
-                       Type[] g_args = null;
-                       if (TypeManager.IsGenericType (delegate_type)) {
-                               g_args = TypeManager.GetTypeArguments (delegate_type);
-                               delegate_type = TypeManager.DropGenericTypeArguments (delegate_type);
-                       }
-
-                       Delegate d = TypeManager.LookupDelegate (delegate_type);
-                       if (d != null) {
-                               if (g_args != null)
-                                       return Import.CreateMethod (TypeBuilder.GetConstructor (dt, d.Constructor.ConstructorBuilder));
-
-                               return d.Constructor.Spec;
-                       }
-
-                       Expression ml = Expression.MemberLookup (ctx, container_type,
-                               null, dt, ConstructorInfo.ConstructorName, MemberTypes.Constructor,
-                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, Location.Null);
-
-                       MethodGroupExpr mg = ml as MethodGroupExpr;
-                       if (mg == null) {
-                               ctx.Report.Error (-100, Location.Null, "Internal error: could not find delegate constructor!");
-                               // FIXME: null will cause a crash later
-                               return null;
-                       }
-
-                       return mg.Methods[0];
+                       var ctor = MemberCache.FindMember (delType, MemberFilter.Constructor (null), BindingRestriction.DeclaredOnly);
+                       return (MethodSpec) ctor;
                }
 
                //
-               // Returns the MethodBase for "Invoke" from a delegate type, this is used
-               // to extract the signature of a delegate.
+               // Returns the "Invoke" from a delegate type
                //
-               public static MethodSpec GetInvokeMethod (CompilerContext ctx, Type container_type, Type delegate_type)
+               public static MethodSpec GetInvokeMethod (CompilerContext ctx, TypeSpec delType)
                {
-                       Type dt = delegate_type;
-
-                       Type[] g_args = null;
-                       if (TypeManager.IsGenericType (delegate_type)) {
-                               g_args = TypeManager.GetTypeArguments (delegate_type);
-                               delegate_type = TypeManager.DropGenericTypeArguments (delegate_type);
-                       }
-
-                       Delegate d = TypeManager.LookupDelegate (delegate_type);
-                       MethodSpec invoke;
-                       if (d != null) {
-                               if (g_args != null) {
-                                       invoke = Import.CreateMethod (TypeBuilder.GetMethod (dt, d.InvokeBuilder.MethodBuilder));
-#if MS_COMPATIBLE
-//                                     ParametersCompiled p = (ParametersCompiled) d.Parameters.InflateTypes (g_args, g_args);
-//                                     TypeManager.RegisterMethod (invoke, p);
-#endif
-                                       return invoke;
-                               }
-                               return d.InvokeBuilder.Spec;
-                       }
-
-                       Expression ml = Expression.MemberLookup (ctx, container_type, null, dt,
-                               "Invoke", Location.Null);
-
-                       MethodGroupExpr mg = ml as MethodGroupExpr;
-                       if (mg == null) {
-                               ctx.Report.Error (-100, Location.Null, "Internal error: could not find Invoke method!");
-                               // FIXME: null will cause a crash later
-                               return null;
-                       }
+                       var invoke = MemberCache.FindMember (delType,
+                               MemberFilter.Method (InvokeMethodName, 0, null, null),
+                               BindingRestriction.DeclaredOnly);
 
-                       invoke = mg.Methods[0];
-#if MS_COMPATIBLE
-//                     if (g_args != null) {
-//                             AParametersCollection p = TypeManager.GetParameterData (invoke);
-//                             p = p.InflateTypes (g_args, g_args);
-//                             TypeManager.RegisterMethod (invoke, p);
-//                             return invoke;
-//                     }
-#endif
+                       return (MethodSpec) invoke;
+               }
 
-                       return invoke;
+               public static AParametersCollection GetParameters (CompilerContext ctx, TypeSpec delType)
+               {
+                       var invoke_mb = GetInvokeMethod (ctx, delType);
+                       return invoke_mb.Parameters;
                }
 
                //
                // 15.2 Delegate compatibility
                //
-               public static bool IsTypeCovariant (Expression a, Type b)
+               public static bool IsTypeCovariant (Expression a, TypeSpec b)
                {
                        //
                        // For each value parameter (a parameter with no ref or out modifier), an 
@@ -432,7 +369,7 @@ namespace Mono.CSharp {
 
                public static string FullDelegateDesc (MethodSpec invoke_method)
                {
-                       return TypeManager.GetFullNameSignature (invoke_method.MetaInfo).Replace (".Invoke", "");
+                       return TypeManager.GetFullNameSignature (invoke_method).Replace (".Invoke", "");
                }
                
                public Expression InstanceExpression {
@@ -462,7 +399,7 @@ namespace Mono.CSharp {
                        Arguments delegate_arguments = new Arguments (pd.Count);
                        for (int i = 0; i < pd.Count; ++i) {
                                Argument.AType atype_modifier;
-                               Type atype = pd.Types [i];
+                               TypeSpec atype = pd.Types [i];
                                switch (pd.FixedParameters [i].ModFlags) {
                                case Parameter.Modifier.REF:
                                        atype_modifier = Argument.AType.Ref;
@@ -504,7 +441,7 @@ namespace Mono.CSharp {
                {
                        constructor_method = Delegate.GetConstructor (ec.Compiler, ec.CurrentType, type);
 
-                       var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, type);
+                       var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, type);
                        method_group.DelegateType = type;
                        method_group.CustomErrorHandler = this;
 
@@ -517,7 +454,7 @@ namespace Mono.CSharp {
                        
                        if (TypeManager.IsNullableType (delegate_method.DeclaringType)) {
                                ec.Report.Error (1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type",
-                                       TypeManager.GetFullNameSignature (delegate_method.MetaInfo));
+                                       TypeManager.GetFullNameSignature (delegate_method));
                                return null;
                        }               
                        
@@ -526,28 +463,28 @@ namespace Mono.CSharp {
                        ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr;
                        if (emg != null) {
                                delegate_instance_expression = emg.ExtensionExpression;
-                               Type e_type = delegate_instance_expression.Type;
+                               TypeSpec e_type = delegate_instance_expression.Type;
                                if (TypeManager.IsValueType (e_type)) {
                                        ec.Report.Error (1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates",
-                                               TypeManager.CSharpSignature (delegate_method.MetaInfo), TypeManager.CSharpName (e_type));
+                                               delegate_method.GetSignatureForError (), TypeManager.CSharpName (e_type));
                                }
                        }
 
-                       Type rt = TypeManager.TypeToCoreType (delegate_method.ReturnType);
+                       TypeSpec rt = delegate_method.ReturnType;
                        Expression ret_expr = new TypeExpression (rt, loc);
-                       if (!Delegate.IsTypeCovariant (ret_expr, (TypeManager.TypeToCoreType (invoke_method.ReturnType)))) {
+                       if (!Delegate.IsTypeCovariant (ret_expr, invoke_method.ReturnType)) {
                                Error_ConversionFailed (ec, delegate_method, ret_expr);
                        }
 
-                       if (Invocation.IsMethodExcluded (delegate_method, loc)) {
-                               ec.Report.SymbolRelatedToPreviousError (delegate_method.MetaInfo);
-                               MethodOrOperator m = TypeManager.GetMethod (delegate_method.MetaInfo) as MethodOrOperator;
+                       if (delegate_method.IsConditionallyExcluded (loc)) {
+                               ec.Report.SymbolRelatedToPreviousError (delegate_method);
+                               MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator;
                                if (m != null && m.IsPartialDefinition) {
                                        ec.Report.Error (762, loc, "Cannot create delegate from partial method declaration `{0}'",
-                                               TypeManager.CSharpSignature (delegate_method.MetaInfo));
+                                               delegate_method.GetSignatureForError ());
                                } else {
                                        ec.Report.Error (1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute",
-                                               TypeManager.CSharpSignature (delegate_method.MetaInfo));
+                                               TypeManager.CSharpSignature (delegate_method));
                                }
                        }
 
@@ -572,7 +509,7 @@ namespace Mono.CSharp {
                        Expression instance = method_group.InstanceExpression;
                        if (instance != null && instance != EmptyExpression.Null) {
                                delegate_instance_expression = instance;
-                               Type instance_type = delegate_instance_expression.Type;
+                               TypeSpec instance_type = delegate_instance_expression.Type;
                                if (TypeManager.IsValueType (instance_type) || TypeManager.IsGenericParameter (instance_type)) {
                                        delegate_instance_expression = new BoxedCast (
                                                delegate_instance_expression, TypeManager.object_type);
@@ -585,29 +522,30 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        if (delegate_instance_expression == null)
-                               ec.ig.Emit (OpCodes.Ldnull);
+                               ec.Emit (OpCodes.Ldnull);
                        else
                                delegate_instance_expression.Emit (ec);
 
-                       if (!delegate_method.DeclaringType.IsSealed && delegate_method.IsVirtual && !method_group.IsBase) {
-                               ec.ig.Emit (OpCodes.Dup);
-                               ec.ig.Emit (OpCodes.Ldvirtftn, (MethodInfo) delegate_method.MetaInfo);
+                       // Any delegate must be sealed
+                       if (!delegate_method.DeclaringType.IsDelegate && delegate_method.IsVirtual && !method_group.IsBase) {
+                               ec.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Ldvirtftn, delegate_method);
                        } else {
-                               ec.ig.Emit (OpCodes.Ldftn, (MethodInfo) delegate_method.MetaInfo);
+                               ec.Emit (OpCodes.Ldftn, delegate_method);
                        }
 
-                       ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) constructor_method.MetaInfo);
+                       ec.Emit (OpCodes.Newobj, constructor_method);
                }
 
                void Error_ConversionFailed (ResolveContext ec, MethodSpec method, Expression return_type)
                {
-                       var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, type);
+                       var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, type);
                        string member_name = delegate_instance_expression != null ?
                                Delegate.FullDelegateDesc (method) :
-                               TypeManager.GetFullNameSignature (method.MetaInfo);
+                               TypeManager.GetFullNameSignature (method);
 
                        ec.Report.SymbolRelatedToPreviousError (type);
-                       ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+                       ec.Report.SymbolRelatedToPreviousError (method);
                        if (RootContext.Version == LanguageVersion.ISO_1) {
                                ec.Report.Error (410, loc, "A method or delegate `{0} {1}' parameters and return type must be same as delegate `{2} {3}' parameters and return type",
                                        TypeManager.CSharpName (method.ReturnType), member_name,
@@ -625,32 +563,23 @@ namespace Mono.CSharp {
                                TypeManager.CSharpName (invoke_method.ReturnType), Delegate.FullDelegateDesc (invoke_method));
                }
 
-               public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, Type target_type)
+               public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, TypeSpec target_type)
                {
                        if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type)
                                return false;
 
                        mg.DelegateType = target_type;
-                       var invoke = Delegate.GetInvokeMethod (ec.Compiler, null, target_type);
+                       var invoke = Delegate.GetInvokeMethod (ec.Compiler, target_type);
 
                        Arguments arguments = CreateDelegateMethodArguments (invoke.Parameters, mg.Location);
                        return mg.OverloadResolve (ec, ref arguments, true, mg.Location) != null;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (delegate_instance_expression != null)
-                               delegate_instance_expression.MutateHoistedGenericType (storey);
-
-                       storey.MutateGenericMethod (delegate_method);
-                       storey.MutateConstructor (constructor_method);
-               }
-
                #region IErrorHandler Members
 
                public bool NoExactMatch (ResolveContext ec, MethodSpec method)
                {
-                       if (method.IsGenericMethod)
+                       if (method.IsGeneric)
                                return false;
 
                        Error_ConversionFailed (ec, method, null);
@@ -670,7 +599,7 @@ namespace Mono.CSharp {
        //
        public class ImplicitDelegateCreation : DelegateCreation
        {
-               ImplicitDelegateCreation (Type t, MethodGroupExpr mg, Location l)
+               ImplicitDelegateCreation (TypeSpec t, MethodGroupExpr mg, Location l)
                {
                        type = t;
                        this.method_group = mg;
@@ -678,7 +607,7 @@ namespace Mono.CSharp {
                }
 
                static public Expression Create (ResolveContext ec, MethodGroupExpr mge,
-                                                Type target_type, Location loc)
+                                                TypeSpec target_type, Location loc)
                {
                        ImplicitDelegateCreation d = new ImplicitDelegateCreation (target_type, mge, loc);
                        return d.DoResolve (ec);
@@ -695,7 +624,7 @@ namespace Mono.CSharp {
                //
                // This constructor is invoked from the `New' expression
                //
-               public NewDelegate (Type type, Arguments Arguments, Location loc)
+               public NewDelegate (TypeSpec type, Arguments Arguments, Location loc)
                {
                        this.type = type;
                        this.Arguments = Arguments;
@@ -726,9 +655,9 @@ namespace Mono.CSharp {
 
                        method_group = e as MethodGroupExpr;
                        if (method_group == null) {
-                               if (TypeManager.IsDynamicType (e.Type)) {
+                               if (e.Type == InternalType.Dynamic) {
                                        e = Convert.ImplicitConversionRequired (ec, e, type, loc);
-                               } else if (!TypeManager.IsDelegateType (e.Type)) {
+                               } else if (!e.Type.IsDelegate) {
                                        e.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup | ResolveFlags.Type, loc);
                                        return null;
                                }
@@ -737,8 +666,7 @@ namespace Mono.CSharp {
                                // An argument is not a method but another delegate
                                //
                                delegate_instance_expression = e;
-                               method_group = new MethodGroupExpr (new [] { 
-                                       Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, e.Type) }, e.Type, loc);
+                               method_group = new MethodGroupExpr (Delegate.GetInvokeMethod (ec.Compiler, e.Type), e.Type, loc);
                        }
 
                        return base.DoResolve (ec);
@@ -776,13 +704,13 @@ namespace Mono.CSharp {
                                return null;
                        }
                        
-                       Type del_type = InstanceExpr.Type;
+                       TypeSpec del_type = InstanceExpr.Type;
                        if (del_type == null)
                                return null;
                        
-                       method = Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, del_type);
+                       method = Delegate.GetInvokeMethod (ec.Compiler, del_type);
                        var mb = method;
-                       var me = new MethodGroupExpr (new [] { mb }, del_type, loc);
+                       var me = new MethodGroupExpr (mb, del_type, loc);
                        me.InstanceExpression = InstanceExpr;
 
                        AParametersCollection pd = mb.Parameters;
@@ -804,7 +732,7 @@ namespace Mono.CSharp {
                                        is_params_applicable || (!is_applicable && params_method), false, loc);
                        }
 
-                       type = TypeManager.TypeToCoreType (method.ReturnType);
+                       type = method.ReturnType;
                        eclass = ExprClass.Value;
                        return this;
                }
@@ -825,23 +753,12 @@ namespace Mono.CSharp {
                        // Pop the return value if there is one
                        //
                        if (type != TypeManager.void_type)
-                               ec.ig.Emit (OpCodes.Pop);
+                               ec.Emit (OpCodes.Pop);
                }
 
                public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
                {
                        return Invocation.MakeExpression (ctx, InstanceExpr, method, arguments);
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       storey.MutateGenericMethod (method);
-                       type = storey.MutateType (type);
-
-                       if (arguments != null)
-                               arguments.MutateHoistedGenericType (storey);
-
-                       InstanceExpr.MutateHoistedGenericType (storey);
-               }
        }
 }
index 2eb06b554237663998241f48097da9017a656b39..8b8dfeecc8b370a395d21887919c7685440ce554 100644 (file)
@@ -21,6 +21,7 @@ using System.Security;
 using System.Security.Permissions;
 using System.Text;
 using System.Xml;
+using System.Linq;
 
 using Mono.CompilerServices.SymbolWriter;
 
@@ -53,10 +54,6 @@ namespace Mono.CSharp {
                                foreach (TypeContainer tc in t.Types)
                                        tc.GenerateDocComment (t);
 
-                       if (t.Delegates != null)
-                               foreach (Delegate de in t.Delegates)
-                                       de.GenerateDocComment (t);
-
                        if (t.Constants != null)
                                foreach (Const c in t.Constants)
                                        c.GenerateDocComment (t);
@@ -261,7 +258,7 @@ namespace Mono.CSharp {
                // returns a full runtime type name from a name which might
                // be C# specific type name.
                //
-               private static Type FindDocumentedType (MemberCore mc, string name, DeclSpace ds, string cref, Report r)
+               private static TypeSpec FindDocumentedType (MemberCore mc, string name, DeclSpace ds, string cref, Report r)
                {
                        bool is_array = false;
                        string identifier = name;
@@ -272,13 +269,13 @@ namespace Mono.CSharp {
                                        is_array = true;
                                }
                        }
-                       Type t = FindDocumentedTypeNonArray (mc, identifier, ds, cref, r);
+                       TypeSpec t = FindDocumentedTypeNonArray (mc, identifier, ds, cref, r);
                        if (t != null && is_array)
-                               t = Array.CreateInstance (t, 0).GetType ();
+                               t = Import.ImportType (Array.CreateInstance (t.GetMetaInfo (), 0).GetType ());
                        return t;
                }
 
-               private static Type FindDocumentedTypeNonArray (MemberCore mc, 
+               private static TypeSpec FindDocumentedTypeNonArray (MemberCore mc, 
                        string identifier, DeclSpace ds, string cref, Report r)
                {
                        switch (identifier) {
@@ -315,7 +312,7 @@ namespace Mono.CSharp {
                        case "void":
                                return TypeManager.void_type;;
                        }
-                       FullNamedExpression e = ds.LookupNamespaceOrType (identifier, mc.Location, false);
+                       FullNamedExpression e = ds.LookupNamespaceOrType (identifier, 0, mc.Location, false);
                        if (e != null) {
                                if (!(e is TypeExpr))
                                        return null;
@@ -325,152 +322,67 @@ namespace Mono.CSharp {
                        if (index < 0)
                                return null;
                        int warn;
-                       Type parent = FindDocumentedType (mc, identifier.Substring (0, index), ds, cref, r);
+                       TypeSpec parent = FindDocumentedType (mc, identifier.Substring (0, index), ds, cref, r);
                        if (parent == null)
                                return null;
                        // no need to detect warning 419 here
-                       return FindDocumentedMember (mc, parent,
+                       var ts = FindDocumentedMember (mc, parent,
                                identifier.Substring (index + 1),
-                               null, ds, out warn, cref, false, null, r).Member as Type;
-               }
-
-               private static MemberInfo [] empty_member_infos =
-                       new MemberInfo [0];
-
-               private static MemberInfo [] FindMethodBase (Type type,
-                       BindingFlags binding_flags, MethodSignature signature)
-               {
-                       MemberList ml = TypeManager.FindMembers (
-                               type,
-                               MemberTypes.Constructor | MemberTypes.Method | MemberTypes.Property | MemberTypes.Custom,
-                               binding_flags,
-                               MethodSignature.method_signature_filter,
-                               signature);
-                       if (ml == null)
-                               return empty_member_infos;
-
-                       return FilterOverridenMembersOut ((MemberInfo []) ml);
-               }
-
-               static bool IsOverride (PropertyInfo deriv_prop, PropertyInfo base_prop)
-               {
-                       if (!MethodGroupExpr.IsAncestralType (base_prop.DeclaringType, deriv_prop.DeclaringType))
-                               return false;
-
-                       Type [] deriv_pd = TypeManager.GetParameterData (deriv_prop).Types;
-                       Type [] base_pd = TypeManager.GetParameterData (base_prop).Types;
-               
-                       if (deriv_pd.Length != base_pd.Length)
-                               return false;
-
-                       for (int j = 0; j < deriv_pd.Length; ++j) {
-                               if (deriv_pd [j] != base_pd [j])
-                                       return false;
-                               Type ct = TypeManager.TypeToCoreType (deriv_pd [j]);
-                               Type bt = TypeManager.TypeToCoreType (base_pd [j]);
-
-                               if (ct != bt)
-                                       return false;
-                       }
-
-                       return true;
-               }
-
-               private static MemberInfo [] FilterOverridenMembersOut (
-                       MemberInfo [] ml)
-               {
-                       if (ml == null)
-                               return empty_member_infos;
-
-                       var al = new List<MemberInfo> (ml.Length);
-                       for (int i = 0; i < ml.Length; i++) {
-                               MethodBase mx = ml [i] as MethodBase;
-                               PropertyInfo px = ml [i] as PropertyInfo;
-                               if (mx != null || px != null) {
-                                       bool overriden = false;
-                                       for (int j = 0; j < ml.Length; j++) {
-                                               if (j == i)
-                                                       continue;
-                                               MethodBase my = ml [j] as MethodBase;
-                                               if (mx != null && my != null &&
-                                                       MethodGroupExpr.IsOverride (my, mx)) {
-                                                       overriden = true;
-                                                       break;
-                                               }
-                                               else if (mx != null)
-                                                       continue;
-                                               PropertyInfo py = ml [j] as PropertyInfo;
-                                               if (px != null && py != null &&
-                                                       IsOverride (py, px)) {
-                                                       overriden = true;
-                                                       break;
-                                               }
-                                       }
-                                       if (overriden)
-                                               continue;
-                               }
-                               al.Add (ml [i]);
-                       }
-                       return al.ToArray ();
-               }
-
-               struct FoundMember
-               {
-                       public static FoundMember Empty = new FoundMember (true);
-
-                       public bool IsEmpty;
-                       public readonly MemberInfo Member;
-                       public readonly Type Type;
-
-                       public FoundMember (bool regardless_of_this_value_its_empty)
-                       {
-                               IsEmpty = true;
-                               Member = null;
-                               Type = null;
-                       }
-
-                       public FoundMember (Type found_type, MemberInfo member)
-                       {
-                               IsEmpty = false;
-                               Type = found_type;
-                               Member = member;
-                       }
+                               null, ds, out warn, cref, false, null, r) as TypeSpec;
+                       if (ts != null)
+                               return ts;
+                       return null;
                }
 
                //
                // Returns a MemberInfo that is referenced in XML documentation
                // (by "see" or "seealso" elements).
                //
-               private static FoundMember FindDocumentedMember (MemberCore mc,
-                       Type type, string member_name, Type [] param_list, 
+               private static MemberSpec FindDocumentedMember (MemberCore mc,
+                       TypeSpec type, string member_name, AParametersCollection param_list, 
                        DeclSpace ds, out int warning_type, string cref,
                        bool warn419, string name_for_error, Report r)
                {
-                       for (; type != null; type = type.DeclaringType) {
-                               MemberInfo mi = FindDocumentedMemberNoNest (
+//                     for (; type != null; type = type.DeclaringType) {
+                               var mi = FindDocumentedMemberNoNest (
                                        mc, type, member_name, param_list, ds,
                                        out warning_type, cref, warn419,
                                        name_for_error, r);
                                if (mi != null)
-                                       return new FoundMember (type, mi);
-                       }
+                                       return mi; // new FoundMember (type, mi);
+//                     }
                        warning_type = 0;
-                       return FoundMember.Empty;
+                       return null;
                }
 
-               private static MemberInfo FindDocumentedMemberNoNest (
-                       MemberCore mc, Type type, string member_name,
-                       Type [] param_list, DeclSpace ds, out int warning_type, 
+               private static MemberSpec FindDocumentedMemberNoNest (
+                       MemberCore mc, TypeSpec type, string member_name,
+                       AParametersCollection param_list, DeclSpace ds, out int warning_type, 
                        string cref, bool warn419, string name_for_error, Report Report)
                {
                        warning_type = 0;
-                       MemberInfo [] mis;
+                       var filter = new MemberFilter (member_name, 0, MemberKind.All, param_list, null);
+                       IList<MemberSpec> found = null;
+                       while (type != null && found == null) {
+                               found = MemberCache.FindMembers (type, filter, BindingRestriction.None);
+                               type = type.DeclaringType;
+                       }
+
+                       if (found == null)
+                               return null;
 
+                       if (warn419 && found.Count > 1) {
+                               Report419 (mc, name_for_error, found.ToArray (), Report);
+                       }
+
+                       return found [0];
+
+/*
                        if (param_list == null) {
                                // search for fields/events etc.
                                mis = TypeManager.MemberLookup (type, null,
-                                       type, MemberTypes.All,
-                                       BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
+                                       type, MemberKind.All,
+                                       BindingRestriction.None,
                                        member_name, null);
                                mis = FilterOverridenMembersOut (mis);
                                if (mis == null || mis.Length == 0)
@@ -538,14 +450,14 @@ namespace Mono.CSharp {
                                msig);
                        if (mis.Length == 0)
                                return null; // CS1574
-                       MemberInfo mi = mis [0];
-                       Type expected = mi is MethodInfo ?
-                               ((MethodInfo) mi).ReturnType :
-                               mi is PropertyInfo ?
-                               ((PropertyInfo) mi).PropertyType :
+                       var mi = mis [0];
+                       TypeSpec expected = mi is MethodSpec ?
+                               ((MethodSpec) mi).ReturnType :
+                               mi is PropertySpec ?
+                               ((PropertySpec) mi).PropertyType :
                                null;
                        if (return_type_name != null) {
-                               Type returnType = FindDocumentedType (mc, return_type_name, ds, cref, Report);
+                               TypeSpec returnType = FindDocumentedType (mc, return_type_name, ds, cref, Report);
                                if (returnType == null || returnType != expected) {
                                        warning_type = 1581;
                                        Report.Warning (1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref);
@@ -553,19 +465,7 @@ namespace Mono.CSharp {
                                }
                        }
                        return mis [0];
-               }
-
-               private static bool IsAmbiguous (MemberInfo [] members)
-               {
-                       if (members.Length < 2)
-                               return false;
-                       if (members.Length > 2)
-                               return true;
-                       if (members [0] is EventInfo && members [1] is FieldInfo)
-                               return false;
-                       if (members [1] is EventInfo && members [0] is FieldInfo)
-                               return false;
-                       return true;
+*/ 
                }
 
                //
@@ -638,18 +538,18 @@ namespace Mono.CSharp {
                        }
 
                        // check if parameters are valid
-                       Type [] parameter_types;
+                       AParametersCollection parameter_types;
                        if (parameters == null)
                                parameter_types = null;
                        else if (parameters.Length == 0)
-                               parameter_types = Type.EmptyTypes;
+                               parameter_types = ParametersCompiled.EmptyReadOnlyParameters;
                        else {
                                string [] param_list = parameters.Split (',');
-                               var plist = new List<Type> ();
+                               var plist = new List<TypeSpec> ();
                                for (int i = 0; i < param_list.Length; i++) {
                                        string param_type_name = param_list [i].Trim (wsChars);
                                        Normalize (mc, ref param_type_name, Report);
-                                       Type param_type = FindDocumentedType (mc, param_type_name, ds, cref, Report);
+                                       TypeSpec param_type = FindDocumentedType (mc, param_type_name, ds, cref, Report);
                                        if (param_type == null) {
                                                Report.Warning (1580, 1, mc.Location, "Invalid type for parameter `{0}' in XML comment cref attribute `{1}'",
                                                        (i + 1).ToString (), cref);
@@ -657,13 +557,14 @@ namespace Mono.CSharp {
                                        }
                                        plist.Add (param_type);
                                }
-                               parameter_types = plist.ToArray ();
+
+                               parameter_types = ParametersCompiled.CreateFullyResolved (plist.ToArray ());
                        }
 
-                       Type type = FindDocumentedType (mc, name, ds, cref, Report);
+                       TypeSpec type = FindDocumentedType (mc, name, ds, cref, Report);
                        if (type != null
                                // delegate must not be referenced with args
-                               && (!TypeManager.IsDelegateType (type)
+                               && (!type.IsDelegate
                                || parameter_types == null)) {
                                string result = GetSignatureForDoc (type)
                                        + (brace_pos < 0 ? String.Empty : signature.Substring (brace_pos));
@@ -675,36 +576,36 @@ namespace Mono.CSharp {
                        if (period > 0) {
                                string typeName = name.Substring (0, period);
                                string member_name = name.Substring (period + 1);
+                               string lookup_name = member_name == "this" ? MemberCache.IndexerNameAlias : member_name;
+                               Normalize (mc, ref lookup_name, Report);
                                Normalize (mc, ref member_name, Report);
                                type = FindDocumentedType (mc, typeName, ds, cref, Report);
                                int warn_result;
                                if (type != null) {
-                                       FoundMember fm = FindDocumentedMember (mc, type, member_name, parameter_types, ds, out warn_result, cref, true, name, Report);
+                                       var mi = FindDocumentedMember (mc, type, lookup_name, parameter_types, ds, out warn_result, cref, true, name, Report);
                                        if (warn_result > 0)
                                                return;
-                                       if (!fm.IsEmpty) {
-                                               MemberInfo mi = fm.Member;
+                                       if (mi != null) {
                                                // we cannot use 'type' directly
                                                // to get its name, since mi
                                                // could be from DeclaringType
                                                // for nested types.
-                                               xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + GetSignatureForDoc (fm.Type) + "." + member_name + GetParametersFormatted (mi));
+                                               xref.SetAttribute ("cref", GetMemberDocHead (mi) + GetSignatureForDoc (mi.DeclaringType) + "." + member_name + GetParametersFormatted (mi));
                                                return; // a member of a type
                                        }
                                }
-                       }
-                       else {
+                       } else {
                                int warn_result;
-                               FoundMember fm = FindDocumentedMember (mc, ds.TypeBuilder, name, parameter_types, ds, out warn_result, cref, true, name, Report);
+                               var mi = FindDocumentedMember (mc, ds.PartialContainer.Definition, name, parameter_types, ds, out warn_result, cref, true, name, Report);
+
                                if (warn_result > 0)
                                        return;
-                               if (!fm.IsEmpty) {
-                                       MemberInfo mi = fm.Member;
+                               if (mi != null) {
                                        // we cannot use 'type' directly
                                        // to get its name, since mi
                                        // could be from DeclaringType
                                        // for nested types.
-                                       xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + GetSignatureForDoc (fm.Type) + "." + name + GetParametersFormatted (mi));
+                                       xref.SetAttribute ("cref", GetMemberDocHead (mi) + GetSignatureForDoc (mi.DeclaringType) + "." + name + GetParametersFormatted (mi));
                                        return; // local member name
                                }
                        }
@@ -726,33 +627,25 @@ namespace Mono.CSharp {
                        xref.SetAttribute ("cref", "!:" + name);
                }
 
-               static string GetParametersFormatted (MemberInfo mi)
+               static string GetParametersFormatted (MemberSpec mi)
                {
-                       MethodBase mb = mi as MethodBase;
-                       bool is_setter = false;
-                       PropertyInfo pi = mi as PropertyInfo;
-                       if (pi != null) {
-                               mb = pi.GetGetMethod ();
-                               if (mb == null) {
-                                       is_setter = true;
-                                       mb = pi.GetSetMethod ();
-                               }
-                       }
-                       if (mb == null)
-                               return String.Empty;
+                       var pm = mi as IParametersMember;
+                       if (pm == null || pm.Parameters.IsEmpty)
+                               return string.Empty;
 
-                       AParametersCollection parameters = TypeManager.GetParameterData (mb);
+                       AParametersCollection parameters = pm.Parameters;
+/*
                        if (parameters == null || parameters.Count == 0)
                                return String.Empty;
-
+*/
                        StringBuilder sb = new StringBuilder ();
                        sb.Append ('(');
                        for (int i = 0; i < parameters.Count; i++) {
-                               if (is_setter && i + 1 == parameters.Count)
-                                       break; // skip "value".
+//                             if (is_setter && i + 1 == parameters.Count)
+//                                     break; // skip "value".
                                if (i > 0)
                                        sb.Append (',');
-                               Type t = parameters.Types [i];
+                               TypeSpec t = parameters.Types [i];
                                sb.Append (GetSignatureForDoc (t));
                        }
                        sb.Append (')');
@@ -773,7 +666,7 @@ namespace Mono.CSharp {
                        return identifier;
                }
 
-               static void Report419 (MemberCore mc, string member_name, MemberInfo [] mis, Report Report)
+               static void Report419 (MemberCore mc, string member_name, MemberSpec [] mis, Report Report)
                {
                        Report.Warning (419, 3, mc.Location, 
                                "Ambiguous reference in cref attribute `{0}'. Assuming `{1}' but other overloads including `{2}' have also matched",
@@ -786,22 +679,19 @@ namespace Mono.CSharp {
                // Get a prefix from member type for XML documentation (used
                // to formalize cref target name).
                //
-               static string GetMemberDocHead (MemberTypes type)
+               static string GetMemberDocHead (MemberSpec type)
                {
-                       switch (type) {
-                       case MemberTypes.Constructor:
-                       case MemberTypes.Method:
+                       if (type is FieldSpec)
+                               return "F:";
+                       if (type is MethodSpec)
                                return "M:";
-                       case MemberTypes.Event:
+                       if (type is EventSpec)
                                return "E:";
-                       case MemberTypes.Field:
-                               return "F:";
-                       case MemberTypes.NestedType:
-                       case MemberTypes.TypeInfo:
-                               return "T:";
-                       case MemberTypes.Property:
+                       if (type is PropertySpec)
                                return "P:";
-                       }
+                       if (type is TypeSpec)
+                               return "T:";
+
                        return "!:";
                }
 
@@ -840,32 +730,35 @@ namespace Mono.CSharp {
                                switch (op.OperatorType) {
                                case Operator.OpType.Implicit:
                                case Operator.OpType.Explicit:
-                                       suffix = "~" + GetSignatureForDoc (op.MethodBuilder.ReturnType);
+                                       suffix = "~" + GetSignatureForDoc (op.ReturnType);
                                        break;
                                }
                        }
                        return String.Concat (mc.DocCommentHeader, ds.Name, ".", name, paramSpec, suffix);
                }
 
-               static string GetSignatureForDoc (Type type)
+               static string GetSignatureForDoc (TypeSpec type)
                {
-                       if (TypeManager.IsGenericParameter (type))
-                               return (type.DeclaringMethod != null ? "``" : "`") + TypeManager.GenericParameterPosition (type);
+                       var tp = type as TypeParameterSpec;
+                       if (tp != null) {
+                               var prefix = tp.IsMethodOwned ? "``" : "`";
+                               return prefix + tp.DeclaredPosition;
+                       }
 
                        if (TypeManager.IsGenericType (type)) {
-                               string g = type.Namespace;
+                               string g = type.MemberDefinition.Namespace;
                                if (g != null && g.Length > 0)
                                        g += '.';
                                int idx = type.Name.LastIndexOf ('`');
                                g += (idx < 0 ? type.Name : type.Name.Substring (0, idx)) + '{';
                                int argpos = 0;
-                               foreach (Type t in type.GetGenericArguments ())
+                               foreach (TypeSpec t in TypeManager.GetTypeArguments (type))
                                        g += (argpos++ > 0 ? "," : String.Empty) + GetSignatureForDoc (t);
                                g += '}';
                                return g;
                        }
 
-                       string name = type.FullName != null ? type.FullName : type.Name;
+                       string name = type.GetMetaInfo ().FullName != null ? type.GetMetaInfo ().FullName : type.Name;
                        return name.Replace ("+", ".").Replace ('&', '@');
                }
 
@@ -884,7 +777,7 @@ namespace Mono.CSharp {
                                string xname = pelem.GetAttribute ("name");
                                if (xname.Length == 0)
                                        continue; // really? but MS looks doing so
-                               if (xname != "" && mc.Parameters.GetParameterIndexByName (xname) < 0)
+                               if (xname != "" && mc.ParameterInfo.GetParameterIndexByName (xname) < 0)
                                        Report.Warning (1572, 2, mc.Location, "XML comment on `{0}' has a param tag for `{1}', but there is no parameter by that name",
                                                mc.GetSignatureForError (), xname);
                                else if (paramTags.ContainsKey (xname))
@@ -892,7 +785,7 @@ namespace Mono.CSharp {
                                                mc.GetSignatureForError (), xname);
                                paramTags [xname] = xname;
                        }
-                       IParameterData [] plist = mc.Parameters.FixedParameters;
+                       IParameterData [] plist = mc.ParameterInfo.FixedParameters;
                        foreach (Parameter p in plist) {
                                if (paramTags.Count > 0 && !paramTags.ContainsKey (p.Name))
                                        Report.Warning (1573, 4, mc.Location, "Parameter `{0}' has no matching param tag in the XML comment for `{1}'",
@@ -1009,10 +902,6 @@ namespace Mono.CSharp {
                        if (root.Types != null)
                                foreach (TypeContainer tc in root.Types)
                                        DocUtil.GenerateTypeDocComment (tc, null, r);
-
-                       if (root.Delegates != null)
-                               foreach (Delegate d in root.Delegates) 
-                                       DocUtil.GenerateDocComment (d, null, r);
                }
        }
 }
index 316b0901fd8917ac5bcecfbe540075c44ac7986e..2ec21ee01647a1c28bb7747d10f5d4da2915c7bc 100644 (file)
@@ -1650,6 +1650,8 @@ namespace Mono.CSharp
                {
                        // TODO: Should be passed to parser as an argument
                        RootContext.ToplevelTypes = new ModuleCompiled (ctx, RootContext.Unsafe);
+                       var ctypes = TypeManager.InitCoreTypes ();
+                       TypeManager.InitExpressionTypes ();
 
                        Parse ();
                        if (Report.Errors > 0)
@@ -1702,6 +1704,7 @@ namespace Mono.CSharp
                        if (timestamps)
                                ShowTime ("Loading references");
 
+                       Import.Initialize ();
                        LoadReferences ();
                        
                        if (modules.Count > 0) {
@@ -1712,7 +1715,7 @@ namespace Mono.CSharp
                        if (timestamps)
                                ShowTime ("References loaded");
                        
-                       if (!TypeManager.InitCoreTypes (ctx) || Report.Errors > 0)
+                       if (!TypeManager.InitCoreTypes (ctx, ctypes))
                                return false;
 
                        TypeManager.InitOptionalCoreTypes (ctx);
@@ -1731,8 +1734,7 @@ namespace Mono.CSharp
                                return false;
                        if (timestamps)
                                ShowTime ("Populate tree");
-                       if (!RootContext.StdLib)
-                               RootContext.BootCorlib_PopulateCoreTypes ();
+
                        RootContext.PopulateTypes ();
 
                        if (Report.Errors == 0 &&
@@ -1755,7 +1757,6 @@ namespace Mono.CSharp
                        if (RootContext.VerifyClsCompliance) {
                                if (CodeGen.Assembly.IsClsCompliant) {
                                        AttributeTester.VerifyModulesClsCompliance (ctx);
-                                       TypeManager.LoadAllImportedTypes ();
                                }
                        }
                        if (Report.Errors > 0)
@@ -2024,19 +2025,28 @@ namespace Mono.CSharp
                {
                        Driver.Reset ();
                        CSharpParser.yacc_verbose_flag = 0;
-                       RootContext.Reset (full_flag);
                        Location.Reset ();
+
+                       if (!full_flag)
+                               return;
+
+                       RootContext.Reset (full_flag);
                        TypeManager.Reset ();
                        PredefinedAttributes.Reset ();
-                       TypeHandle.Reset ();
-
-                       if (full_flag)
-                               GlobalRootNamespace.Reset ();
+                       ArrayContainer.Reset ();
+                       ReferenceContainer.Reset ();
+                       PointerContainer.Reset ();
+                       Parameter.Reset ();
+
+                       GlobalRootNamespace.Reset ();
+                       Unary.Reset ();
+                       Binary.Reset ();
+                       ConstantFold.Reset ();
+                       CastFromDecimal.Reset ();
                        
                        NamespaceEntry.Reset ();
                        CodeGen.Reset ();
                        Attribute.Reset ();
-                       AttributeTester.Reset ();
                        AnonymousTypeClass.Reset ();
                        AnonymousMethodBody.Reset ();
                        AnonymousMethodStorey.Reset ();
index 09287b4f744aa09e09d796e8b9c8473b9abe2965..3a466401fb857036e2506f1ab314108f870ab70f 100644 (file)
@@ -71,19 +71,18 @@ namespace Mono.CSharp
 #if !NET_4_0
                public class DynamicMetaObject
                {
-                       public Type RuntimeType;
-                       public Type LimitType;
+                       public TypeSpec RuntimeType;
+                       public TypeSpec LimitType;
                        public SLE.Expression Expression;
                }
 #endif
 
                readonly DynamicMetaObject obj;
 
-               public RuntimeValueExpression (DynamicMetaObject obj, bool isCompileTimeType)
+               public RuntimeValueExpression (DynamicMetaObject obj, TypeSpec type)
                {
                        this.obj = obj;
-                       this.type = isCompileTimeType ? obj.LimitType : obj.RuntimeType;
-                       this.type = obj.LimitType;
+                       this.type = type;
                        this.eclass = ExprClass.Variable;
                }
 
@@ -133,7 +132,7 @@ namespace Mono.CSharp
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Convert (obj.Expression, type);
+                       return SLE.Expression.Convert (obj.Expression, type.GetMetaInfo ());
                }
 
                public DynamicMetaObject MetaObject {
@@ -148,7 +147,7 @@ namespace Mono.CSharp
        //
        public class DynamicResultCast : ShimExpression
        {
-               public DynamicResultCast (Type type, Expression expr)
+               public DynamicResultCast (TypeSpec type, Expression expr)
                        : base (expr)
                {
                        this.type = type;
@@ -164,7 +163,7 @@ namespace Mono.CSharp
 #if NET_4_0
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Block (expr.MakeExpression (ctx), SLE.Expression.Default (type));
+                       return SLE.Expression.Block (expr.MakeExpression (ctx), SLE.Expression.Default (type.GetMetaInfo ()));
                }
 #endif
        }
@@ -261,6 +260,7 @@ namespace Mono.CSharp
                        if (global_site_container == null) {
                                global_site_container = new StaticDataClass ();
                                RootContext.ToplevelTypes.AddCompilerGeneratedClass (global_site_container);
+                               global_site_container.CreateType ();
                                global_site_container.DefineType ();
                                global_site_container.Define ();
                        }
@@ -310,7 +310,7 @@ namespace Mono.CSharp
 
                        if (TypeManager.generic_call_site_type == null)
                                TypeManager.generic_call_site_type = TypeManager.CoreLookupType (rc.Compiler,
-                                       "System.Runtime.CompilerServices", "CallSite`1", MemberKind.Class, true);
+                                       "System.Runtime.CompilerServices", "CallSite", 1, MemberKind.Class, true);
 
                        if (TypeManager.binder_flags == null) {
                                TypeManager.binder_flags = TypeManager.CoreLookupType (rc.Compiler,
@@ -346,7 +346,7 @@ namespace Mono.CSharp
                        TypeExpr site_type = CreateSiteType (RootContext.ToplevelTypes.Compiler, arguments, dyn_args_count, isStatement);
                        FieldExpr site_field_expr = new FieldExpr (CreateSiteField (site_type), loc);
 
-                       SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
+                       SymbolWriter.OpenCompilerGeneratedBlock (ec);
 
                        Arguments args = new Arguments (1);
                        args.Add (new Argument (binder));
@@ -376,7 +376,7 @@ namespace Mono.CSharp
                        if (target != null)
                                target.Emit (ec);
 
-                       SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
+                       SymbolWriter.CloseCompilerGeneratedBlock (ec);
                }
 
                public static MemberAccess GetBinderNamespace (Location loc)
@@ -398,7 +398,7 @@ namespace Mono.CSharp
                        FullNamedExpression[] targs = new FullNamedExpression[dyn_args_count + default_args];
                        targs [0] = new TypeExpression (TypeManager.call_site_type, loc);
                        for (int i = 0; i < dyn_args_count; ++i) {
-                               Type arg_type;
+                               TypeSpec arg_type;
                                Argument a = arguments [i];
                                if (a.Type == TypeManager.null_type)
                                        arg_type = TypeManager.object_type;
@@ -413,9 +413,9 @@ namespace Mono.CSharp
 
                        TypeExpr del_type = null;
                        if (!has_ref_out_argument) {
-                               string d_name = is_statement ? "Action`" : "Func`";
+                               string d_name = is_statement ? "Action" : "Func";
 
-                               Type t = TypeManager.CoreLookupType (ctx, "System", d_name + (dyn_args_count + default_args), MemberKind.Delegate, false);
+                               TypeSpec t = TypeManager.CoreLookupType (ctx, "System", d_name, dyn_args_count + default_args, MemberKind.Delegate, false);
                                if (t != null) {
                                        if (!is_statement)
                                                targs [targs.Length - 1] = new TypeExpression (type, loc);
@@ -428,7 +428,7 @@ namespace Mono.CSharp
                        // Create custom delegate when no appropriate predefined one is found
                        //
                        if (del_type == null) {
-                               Type rt = is_statement ? TypeManager.void_type : type;
+                               TypeSpec rt = is_statement ? TypeManager.void_type : type;
                                Parameter[] p = new Parameter [dyn_args_count + 1];
                                p[0] = new Parameter (targs [0], "p0", Parameter.Modifier.NONE, null, loc);
 
@@ -441,12 +441,13 @@ namespace Mono.CSharp
                                        new MemberName ("Container" + container_counter++.ToString ("X")),
                                        new ParametersCompiled (ctx, p), null);
 
+                               d.CreateType ();
                                d.DefineType ();
                                d.Define ();
                                d.Emit ();
 
                                parent.AddDelegate (d);
-                               del_type = new TypeExpression (d.TypeBuilder, loc);
+                               del_type = new TypeExpression (d.Definition, loc);
                        }
 
                        TypeExpr site_type = new GenericTypeExpr (TypeManager.generic_call_site_type, new TypeArguments (del_type), loc);
@@ -502,7 +503,7 @@ namespace Mono.CSharp
 
        class DynamicConversion : DynamicExpressionStatement, IDynamicBinder
        {
-               public DynamicConversion (Type targetType, CSharpBinderFlags flags, Arguments args, Location loc)
+               public DynamicConversion (TypeSpec targetType, CSharpBinderFlags flags, Arguments args, Location loc)
                        : base (null, args, loc)
                {
                        type = targetType;
@@ -525,7 +526,7 @@ namespace Mono.CSharp
 
        class DynamicConstructorBinder : DynamicExpressionStatement, IDynamicBinder
        {
-               public DynamicConstructorBinder (Type type, Arguments args, Location loc)
+               public DynamicConstructorBinder (TypeSpec type, Arguments args, Location loc)
                        : base (null, args, loc)
                {
                        this.type = type;
@@ -574,7 +575,7 @@ namespace Mono.CSharp
                        this.member = member;
                }
 
-               public DynamicInvocation (ATypeNameExpression member, Arguments args, Type type, Location loc)
+               public DynamicInvocation (ATypeNameExpression member, Arguments args, TypeSpec type, Location loc)
                        : this (member, args, loc)
                {
                        // When a return type is known not to be dynamic
@@ -610,7 +611,7 @@ namespace Mono.CSharp
                                TypeArguments ta = member.TypeArguments;
                                if (ta.Resolve (ec)) {
                                        var targs = new ArrayInitializer (ta.Count, loc);
-                                       foreach (Type t in ta.Arguments)
+                                       foreach (TypeSpec t in ta.Arguments)
                                                targs.Add (new TypeOf (new TypeExpression (t, loc), loc));
 
                                        binder_args.Add (new Argument (new ImplicitlyTypedArrayCreation ("[]", targs, loc)));
index bf2788731d094c8eccd2418b86d9beed06b56405..ab04c7cb904237a2e574c67896151998bd00cb88 100644 (file)
@@ -120,10 +120,10 @@ namespace Mono.CSharp {
        /// </remarks>
        public abstract class Expression {
                public ExprClass eclass;
-               protected Type type;
+               protected TypeSpec type;
                protected Location loc;
                
-               public Type Type {
+               public TypeSpec Type {
                        get { return type; }
                        set { type = value; }
                }
@@ -139,10 +139,10 @@ namespace Mono.CSharp {
 
                public virtual string GetSignatureForError ()
                {
-                       return TypeManager.CSharpName (type);
+                       return type.GetDefinition ().GetSignatureForError ();
                }
 
-               public static bool IsAccessorAccessible (Type invocation_type, MethodSpec mi, out bool must_do_cs1540_check)
+               public static bool IsMemberAccessible (TypeSpec invocation_type, MemberSpec mi, out bool must_do_cs1540_check)
                {
                        var ma = mi.Modifiers & Modifiers.AccessibilityMask;
 
@@ -150,16 +150,17 @@ namespace Mono.CSharp {
 
                        if (ma == Modifiers.PUBLIC)
                                return true;
-                       
+               
                        //
                        // If only accessible to the current class or children
                        //
                        if (ma == Modifiers.PRIVATE)
-                               return TypeManager.IsPrivateAccessible (invocation_type, mi.DeclaringType) ||
+                               return invocation_type.MemberDefinition == mi.DeclaringType.MemberDefinition ||
                                        TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType);
 
                        if ((ma & Modifiers.INTERNAL) != 0) {
-                               var b = TypeManager.IsThisOrFriendAssembly (invocation_type.Assembly, mi.DeclaringType.Assembly);
+                               var b = TypeManager.IsThisOrFriendAssembly (invocation_type == InternalType.FakeInternalType ?
+                                        CodeGen.Assembly.Builder : invocation_type.Assembly, mi.DeclaringType.Assembly);
                                if (b || ma == Modifiers.INTERNAL)
                                        return b;
                        }
@@ -245,43 +246,7 @@ namespace Mono.CSharp {
                // value will be returned if the expression is not a type
                // reference
                //
-               public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
-               {
-                       TypeExpr te = ResolveAsBaseTerminal (ec, silent);
-                       if (te == null)
-                               return null;
-
-                       if (!silent) { // && !(te is TypeParameterExpr)) {
-                               ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (te.Type);
-                               if (obsolete_attr != null && !ec.IsObsolete) {
-                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Compiler.Report);
-                               }
-                       }
-
-                       GenericTypeExpr ct = te as GenericTypeExpr;
-                       if (ct != null) {
-                               //
-                               // TODO: Constrained type parameters check for parameters of generic method overrides is broken
-                               // There are 2 solutions.
-                               // 1, Skip this check completely when we are in override/explicit impl scope
-                               // 2, Copy type parameters constraints from base implementation and pass (they have to be emitted anyway)
-                               //
-                               MemberCore gm = ec as GenericMethod;
-                               if (gm == null)
-                                       gm = ec as Method;
-                               if (gm != null && ((gm.ModFlags & Modifiers.OVERRIDE) != 0 || gm.MemberName.Left != null)) {
-                                       te.loc = loc;
-                                       return te;
-                               }
-
-                               // TODO: silent flag is ignored
-                               ct.CheckConstraints (ec);
-                       }
-
-                       return te;
-               }
-       
-               public TypeExpr ResolveAsBaseTerminal (IMemberContext ec, bool silent)
+               public virtual TypeExpr ResolveAsTypeTerminal (IMemberContext ec , bool silent)
                {
                        int errors = ec.Compiler.Report.Errors;
 
@@ -300,23 +265,34 @@ namespace Mono.CSharp {
                        if (!te.CheckAccessLevel (ec)) {
                                ec.Compiler.Report.SymbolRelatedToPreviousError (te.Type);
                                ErrorIsInaccesible (loc, TypeManager.CSharpName (te.Type), ec.Compiler.Report);
-                               return null;
                        }
 
                        te.loc = loc;
+
+                       //
+                       // Obsolete checks cannot be done when resolving base context as they
+                       // require type dependecies to be set but we are just resolving them
+                       //
+                       if (!silent && !(ec is TypeContainer.BaseContext)) {
+                               ObsoleteAttribute obsolete_attr = te.Type.GetAttributeObsolete ();
+                               if (obsolete_attr != null && !ec.IsObsolete) {
+                                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, te.GetSignatureForError (), Location, ec.Compiler.Report);
+                               }
+                       }
+
                        return te;
                }
-
+       
                public static void ErrorIsInaccesible (Location loc, string name, Report Report)
                {
                        Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", name);
                }
 
-               protected static void Error_CannotAccessProtected (ResolveContext ec, Location loc, MemberInfo m, Type qualifier, Type container)
+               protected static void Error_CannotAccessProtected (ResolveContext ec, Location loc, MemberSpec m, TypeSpec qualifier, TypeSpec container)
                {
                        ec.Report.Error (1540, loc, "Cannot access protected member `{0}' via a qualifier of type `{1}'."
                                + " The qualifier must be of type `{2}' or derived from it", 
-                               TypeManager.GetFullNameSignature (m),
+                               m.GetSignatureForError (),
                                TypeManager.CSharpName (qualifier),
                                TypeManager.CSharpName (container));
 
@@ -327,7 +303,7 @@ namespace Mono.CSharp {
                        rc.Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
                }
 
-               public void Error_ConstantCanBeInitializedWithNullOnly (ResolveContext rc, Type type, Location loc, string name)
+               public void Error_ConstantCanBeInitializedWithNullOnly (ResolveContext rc, TypeSpec type, Location loc, string name)
                {
                        rc.Report.Error (134, loc, "A constant `{0}' of reference type `{1}' can only be initialized with null",
                                name, TypeManager.CSharpName (type));
@@ -349,17 +325,18 @@ namespace Mono.CSharp {
                        Report.Error (1547, loc, "Keyword `void' cannot be used in this context");
                }
 
-               public virtual void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
+               public virtual void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
                {
                        Error_ValueCannotBeConvertedCore (ec, loc, target, expl);
                }
 
-               protected void Error_ValueCannotBeConvertedCore (ResolveContext ec, Location loc, Type target, bool expl)
+               protected void Error_ValueCannotBeConvertedCore (ResolveContext ec, Location loc, TypeSpec target, bool expl)
                {
                        // The error was already reported as CS1660
                        if (type == InternalType.AnonymousMethod)
                                return;
 
+/*
                        if (TypeManager.IsGenericParameter (Type) && TypeManager.IsGenericParameter (target) && type.Name == target.Name) {
                                string sig1 = type.DeclaringMethod == null ?
                                        TypeManager.CSharpName (type.DeclaringType) :
@@ -371,13 +348,13 @@ namespace Mono.CSharp {
                                        String.Format (
                                                "The generic parameter `{0}' of `{1}' cannot be converted to the generic parameter `{0}' of `{2}' (in the previous ",
                                                Type.Name, sig1, sig2));
-                       } else if (Type.FullName == target.FullName){
+                       } else if (Type.MetaInfo.FullName == target.MetaInfo.FullName) {
                                ec.Report.ExtraInformation (loc,
                                        String.Format (
                                        "The type `{0}' has two conflicting definitions, one comes from `{1}' and the other from `{2}' (in the previous ",
-                                       Type.FullName, Type.Assembly.FullName, target.Assembly.FullName));
+                                       Type.MetaInfo.FullName, Type.Assembly.FullName, target.Assembly.FullName));
                        }
-
+*/
                        if (expl) {
                                ec.Report.Error (30, loc, "Cannot convert type `{0}' to `{1}'",
                                        TypeManager.CSharpName (type), TypeManager.CSharpName (target));
@@ -396,8 +373,7 @@ namespace Mono.CSharp {
                        }
 
                        ec.Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
-                               TypeManager.CSharpName (type),
-                               TypeManager.CSharpName (target));
+                               type.GetSignatureForError (), target.GetSignatureForError ());
                }
 
                public virtual void Error_VariableIsUsedBeforeItIsDeclared (Report Report, string name)
@@ -405,28 +381,36 @@ namespace Mono.CSharp {
                        Report.Error (841, loc, "A local variable `{0}' cannot be used before it is declared", name);
                }
 
-               public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc)
+               public void Error_TypeArgumentsCannotBeUsed (Report report, Location loc, MemberSpec member, int arity)
                {
                        // Better message for possible generic expressions
-                       if (eclass == ExprClass.MethodGroup || eclass == ExprClass.Type) {
-                               if (this is TypeExpr)
-                                       report.SymbolRelatedToPreviousError (type);
+                       if (member != null && (member.Kind & MemberKind.GenericMask) != 0) {
+                               report.SymbolRelatedToPreviousError (member);
+                               if (member is TypeSpec)
+                                       member = ((TypeSpec) member).GetDefinition ();
+                               else
+                                       member = ((MethodSpec) member).GetGenericMethodDefinition ();
 
-                               string name = eclass == ExprClass.Type ? ExprClassName : "method";
-                               report.Error (308, loc, "The non-generic {0} `{1}' cannot be used with the type arguments",
-                                       name, GetSignatureForError ());
+                               string name = member.Kind == MemberKind.Method ? "method" : "type";
+                               if (member.IsGeneric) {
+                                       report.Error (305, loc, "Using the generic {0} `{1}' requires `{2}' type argument(s)",
+                                               name, member.GetSignatureForError (), member.Arity.ToString ());
+                               } else {
+                                       report.Error (308, loc, "The non-generic {0} `{1}' cannot be used with the type arguments",
+                                               name, member.GetSignatureForError ());
+                               }
                        } else {
                                report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
                                        ExprClassName, GetSignatureForError ());
                        }
                }
 
-               protected virtual void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
+               protected virtual void Error_TypeDoesNotContainDefinition (ResolveContext ec, TypeSpec type, string name)
                {
                        Error_TypeDoesNotContainDefinition (ec, loc, type, name);
                }
 
-               public static void Error_TypeDoesNotContainDefinition (ResolveContext ec, Location loc, Type type, string name)
+               public static void Error_TypeDoesNotContainDefinition (ResolveContext ec, Location loc, TypeSpec type, string name)
                {
                        ec.Report.SymbolRelatedToPreviousError (type);
                        ec.Report.Error (117, loc, "`{0}' does not contain a definition for `{1}'",
@@ -549,7 +533,7 @@ namespace Mono.CSharp {
                        return e;
                }
 
-               public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public virtual void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        Attribute.Error_AttributeArgumentNotValid (rc, loc);
                }
@@ -572,7 +556,7 @@ namespace Mono.CSharp {
                public virtual void EmitBranchable (EmitContext ec, Label target, bool on_true)
                {
                        Emit (ec);
-                       ec.ig.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+                       ec.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
                }
 
                // Emit this expression for its side effects, not for its value.
@@ -581,7 +565,7 @@ namespace Mono.CSharp {
                public virtual void EmitSideEffect (EmitContext ec)
                {
                        Emit (ec);
-                       ec.ig.Emit (OpCodes.Pop);
+                       ec.Emit (OpCodes.Pop);
                }
 
                /// <summary>
@@ -597,28 +581,22 @@ namespace Mono.CSharp {
                ///   Returns a fully formed expression after a MemberLookup
                /// </summary>
                /// 
-               public static Expression ExprClassFromMemberInfo (Type container_type, MemberInfo mi, Location loc)
-               {
-                       if (mi is EventInfo)
-                               return new EventExpr (Import.CreateEvent ((EventInfo) mi), loc);
-                       else if (mi is FieldInfo) {
-                               FieldInfo fi = (FieldInfo) mi;
-                               var spec = Import.CreateField (fi);
-                               if (spec is ConstSpec)
-                                       return new ConstantExpr ((ConstSpec) spec, loc);
-                               return new FieldExpr (spec, loc);
-                       } else if (mi is PropertyInfo)
-                               return new PropertyExpr (container_type, Import.CreateProperty ((PropertyInfo) mi), loc);
-                       else if (mi is Type) {
-                               return new TypeExpression ((System.Type) mi, loc);
-                       }
+               public static Expression ExprClassFromMemberInfo (TypeSpec container_type, MemberSpec spec, Location loc)
+               {
+                       if (spec is EventSpec)
+                               return new EventExpr ((EventSpec) spec, loc);
+                       if (spec is ConstSpec)
+                               return new ConstantExpr ((ConstSpec) spec, loc);
+                       if (spec is FieldSpec)
+                               return new FieldExpr ((FieldSpec) spec, loc);
+                       if (spec is PropertySpec)
+                               return new PropertyExpr (container_type, (PropertySpec) spec, loc);
+                       if (spec is TypeSpec)
+                               return new TypeExpression (((TypeSpec) spec), loc);
 
                        return null;
                }
 
-               // TODO: [Obsolete ("Can be removed")]
-               protected static IList<MemberInfo> almost_matched_members = new List<MemberInfo> (4);
-
                //
                // FIXME: Probably implement a cache for (t,name,current_access_set)?
                //
@@ -647,135 +625,64 @@ namespace Mono.CSharp {
                // FIXME: Potential optimization, have a static ArrayList
                //
 
-               public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type queried_type, string name,
-                                                      MemberTypes mt, BindingFlags bf, Location loc)
+               public static Expression MemberLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec queried_type, string name, int arity,
+                                                      MemberKind mt, BindingRestriction bf, Location loc)
                {
-                       return MemberLookup (ctx, container_type, null, queried_type, name, mt, bf, loc);
+                       return MemberLookup (ctx, container_type, null, queried_type, name, arity, mt, bf, loc);
                }
 
                //
                // Lookup type `queried_type' for code in class `container_type' with a qualifier of
                // `qualifier_type' or null to lookup members in the current class.
                //
-
-               public static Expression MemberLookup (CompilerContext ctx, Type container_type,
-                                                      Type qualifier_type, Type queried_type,
-                                                      string name, MemberTypes mt,
-                                                      BindingFlags bf, Location loc)
+               public static Expression MemberLookup (CompilerContext ctx, TypeSpec container_type,
+                                                      TypeSpec qualifier_type, TypeSpec queried_type,
+                                                      string name, int arity, MemberKind mt,
+                                                      BindingRestriction binding, Location loc)
                {
-                       almost_matched_members.Clear ();
-
-                       MemberInfo [] mi = TypeManager.MemberLookup (container_type, qualifier_type,
-                                                                    queried_type, mt, bf, name, almost_matched_members);
-
+                       var mi = TypeManager.MemberLookup (container_type, qualifier_type,
+                                                                    queried_type, mt, binding, name, arity, null);
                        if (mi == null)
                                return null;
 
-                       if (mi.Length > 1) {
-                               bool is_interface = qualifier_type != null && qualifier_type.IsInterface;
-                               var methods = new List<MethodSpec> (2);
-                               List<MemberInfo> non_methods = null;
-
-                               foreach (var m in mi) {
-                                       if (m is MethodBase) {
-                                               methods.Add (Import.CreateMethod ((MethodBase) m));
-                                               continue;
-                                       }
-
-                                       if (non_methods == null)
-                                               non_methods = new List<MemberInfo> (2);
-
-                                       bool is_candidate = true;
-                                       for (int i = 0; i < non_methods.Count; ++i) {
-                                               MemberInfo n_m = non_methods [i];
-                                               if (n_m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (m.DeclaringType, n_m.DeclaringType)) {
-                                                       non_methods.Remove (n_m);
-                                                       --i;
-                                               } else if (m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (n_m.DeclaringType, m.DeclaringType)) {
-                                                       is_candidate = false;
-                                                       break;
-                                               }
-                                       }
-                                       
-                                       if (is_candidate) {
-                                               non_methods.Add (m);
-                                       }
+                       var first = mi [0];
+                       if (mi.Count > 1) {
+                               foreach (var mc in mi) {
+                                       if (mc is MethodSpec)
+                                               return new MethodGroupExpr (mi, queried_type, loc);
                                }
-                               
-                               if (methods.Count == 0 && non_methods != null && non_methods.Count > 1) {
-                                       ctx.Report.SymbolRelatedToPreviousError (non_methods [1]);
-                                       ctx.Report.SymbolRelatedToPreviousError (non_methods [0]);
-                                       ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
-                                               TypeManager.GetFullNameSignature (non_methods [1]),
-                                               TypeManager.GetFullNameSignature (non_methods [0]));
-                                       return null;
-                               }
-
-                               if (methods.Count == 0)
-                                       return ExprClassFromMemberInfo (container_type, (MemberInfo)non_methods [0], loc);
-
-                               if (non_methods != null && non_methods.Count > 0) {
-                                       var method = methods [0];
-                                       MemberInfo non_method = (MemberInfo) non_methods [0];
-                                       if (method.DeclaringType == non_method.DeclaringType) {
-                                               // Cannot happen with C# code, but is valid in IL
-                                               ctx.Report.SymbolRelatedToPreviousError (method.MetaInfo);
-                                               ctx.Report.SymbolRelatedToPreviousError (non_method);
-                                               ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
-                                                             TypeManager.GetFullNameSignature (non_method),
-                                                             TypeManager.CSharpSignature (method.MetaInfo));
-                                               return null;
-                                       }
 
-                                       if (is_interface) {
-                                               ctx.Report.SymbolRelatedToPreviousError (method.MetaInfo);
-                                               ctx.Report.SymbolRelatedToPreviousError (non_method);
-                                               ctx.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
-                                                               TypeManager.CSharpSignature (method.MetaInfo), TypeManager.GetFullNameSignature (non_method));
-                                       }
-                               }
-
-                               return new MethodGroupExpr (methods, queried_type, loc);
+                               ctx.Report.SymbolRelatedToPreviousError (mi [1]);
+                               ctx.Report.SymbolRelatedToPreviousError (first);
+                               ctx.Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+                                       first.GetSignatureForError (), mi [1].GetSignatureForError ());
                        }
 
-                       if (mi [0] is MethodBase)
-                               return new MethodGroupExpr (mi.Select (l => Import.CreateMethod ((MethodBase) l)).ToArray (), queried_type, loc);
+                       if (first is MethodSpec)
+                               return new MethodGroupExpr (mi, queried_type, loc);
 
-                       return ExprClassFromMemberInfo (container_type, mi [0], loc);
+                       return ExprClassFromMemberInfo (container_type, first, loc);
                }
 
-               public const MemberTypes AllMemberTypes =
-                       MemberTypes.Constructor |
-                       MemberTypes.Event       |
-                       MemberTypes.Field       |
-                       MemberTypes.Method      |
-                       MemberTypes.NestedType  |
-                       MemberTypes.Property;
-               
-               public const BindingFlags AllBindingFlags =
-                       BindingFlags.Public |
-                       BindingFlags.Static |
-                       BindingFlags.Instance;
-
-               public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type queried_type,
-                                                      string name, Location loc)
+               public static Expression MemberLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec queried_type,
+                                                          string name, int arity, BindingRestriction binding, Location loc)
                {
-                       return MemberLookup (ctx, container_type, null, queried_type, name,
-                                            AllMemberTypes, AllBindingFlags, loc);
+                       return MemberLookup (ctx, container_type, null, queried_type, name, arity,
+                                            MemberKind.All, binding | BindingRestriction.AccessibleOnly, loc);
                }
 
-               public static Expression MemberLookup (CompilerContext ctx, Type container_type, Type qualifier_type,
-                                                      Type queried_type, string name, Location loc)
+               public static Expression MemberLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec qualifier_type,
+                                                          TypeSpec queried_type, string name, int arity, BindingRestriction binding, Location loc)
                {
                        return MemberLookup (ctx, container_type, qualifier_type, queried_type,
-                                            name, AllMemberTypes, AllBindingFlags, loc);
+                                                name, arity, MemberKind.All, binding | BindingRestriction.AccessibleOnly, loc);
                }
 
-               public static MethodGroupExpr MethodLookup (CompilerContext ctx, Type container_type, Type queried_type,
-                                                      string name, Location loc)
+               public static MethodGroupExpr MethodLookup (CompilerContext ctx, TypeSpec container_type, TypeSpec queried_type,
+                                                      MemberKind kind, string name, int arity, Location loc)
                {
-                       return (MethodGroupExpr)MemberLookup (ctx, container_type, null, queried_type, name,
-                                            MemberTypes.Method, AllBindingFlags, loc);
+                       return (MethodGroupExpr)MemberLookup (ctx, container_type, null, queried_type, name, arity,
+                                            kind, BindingRestriction.AccessibleOnly, loc);
                }
 
                /// <summary>
@@ -784,35 +691,36 @@ namespace Mono.CSharp {
                ///   look for private members and display a useful debugging message if we
                ///   find it.
                /// </summary>
-               protected Expression MemberLookupFinal (ResolveContext ec, Type qualifier_type,
-                                                           Type queried_type, string name,
-                                                           MemberTypes mt, BindingFlags bf,
+               protected Expression MemberLookupFinal (ResolveContext ec, TypeSpec qualifier_type,
+                                                           TypeSpec queried_type, string name, int arity,
+                                                           MemberKind mt, BindingRestriction bf,
                                                            Location loc)
                {
                        Expression e;
 
                        int errors = ec.Report.Errors;
-                       e = MemberLookup (ec.Compiler, ec.CurrentType, qualifier_type, queried_type, name, mt, bf, loc);
+                       e = MemberLookup (ec.Compiler, ec.CurrentType, qualifier_type, queried_type, name, arity, mt, bf, loc);
 
                        if (e != null || errors != ec.Report.Errors)
                                return e;
 
                        // No errors were reported by MemberLookup, but there was an error.
                        return Error_MemberLookupFailed (ec, ec.CurrentType, qualifier_type, queried_type,
-                                       name, null, mt, bf);
+                                       name, arity, null, mt, bf);
                }
 
-               protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, Type container_type, Type qualifier_type,
-                                                      Type queried_type, string name, string class_name,
-                                                          MemberTypes mt, BindingFlags bf)
+               protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, TypeSpec container_type, TypeSpec qualifier_type,
+                                                      TypeSpec queried_type, string name, int arity, string class_name,
+                                                          MemberKind mt, BindingRestriction bf)
                {
-                       MemberInfo[] lookup = null;
+                       IList<MemberSpec> lookup = null;
                        if (queried_type == null) {
                                class_name = "global::";
                        } else {
+                               BindingRestriction restriction = bf & BindingRestriction.DeclaredOnly;
+
                                lookup = TypeManager.MemberLookup (queried_type, null, queried_type,
-                                       mt, (bf & ~BindingFlags.Public) | BindingFlags.NonPublic,
-                                       name, null);
+                                       mt, restriction, name, arity, null);
 
                                if (lookup != null) {
                                        Expression e = Error_MemberLookupFailed (ec, queried_type, lookup);
@@ -822,10 +730,10 @@ namespace Mono.CSharp {
                                        // OverloadResolve to do correct arguments matching.
                                        // Requires MemberLookup accessiblity check removal
                                        //
-                                       if (e == null || (mt & (MemberTypes.Method | MemberTypes.Constructor)) == 0) {
-                                               MemberInfo mi = lookup[0];
+                                       if (e == null || (mt & (MemberKind.Method | MemberKind.Constructor)) == 0) {
+                                               var mi = lookup.First ();
                                                ec.Report.SymbolRelatedToPreviousError (mi);
-                                               if (qualifier_type != null && container_type != null && qualifier_type != container_type &&
+                                               if ((mi.Modifiers & Modifiers.PROTECTED) != 0 && qualifier_type != null && container_type != null && qualifier_type != container_type &&
                                                        TypeManager.IsNestedFamilyAccessible (container_type, mi.DeclaringType)) {
                                                        // Although a derived class can access protected members of
                                                        // its base class it cannot do so through an instance of the
@@ -842,8 +750,7 @@ namespace Mono.CSharp {
                                }
 
                                lookup = TypeManager.MemberLookup (queried_type, null, queried_type,
-                                       AllMemberTypes, AllBindingFlags | BindingFlags.NonPublic,
-                                       name, null);
+                                       MemberKind.All, BindingRestriction.None, name, -System.Math.Max (1, arity), null);
                        }
 
                        if (lookup == null) {
@@ -856,36 +763,21 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (TypeManager.MemberLookup (queried_type, null, queried_type,
-                                                     AllMemberTypes, AllBindingFlags |
-                                                     BindingFlags.NonPublic, name, null) == null) {
-                               if ((lookup.Length == 1) && (lookup [0] is Type)) {
-                                       Type t = (Type) lookup [0];
-
-                                       ec.Report.Error (305, loc,
-                                                     "Using the generic type `{0}' " +
-                                                     "requires {1} type arguments",
-                                                     TypeManager.CSharpName (t),
-                                                     TypeManager.GetNumberOfTypeArguments (t).ToString ());
-                                       return null;
-                               }
+                       var mge = Error_MemberLookupFailed (ec, queried_type, lookup);
+                       if (arity > 0 && mge != null) {
+                               mge.SetTypeArguments (ec, new TypeArguments (new FullNamedExpression [arity]));
                        }
 
-                       return Error_MemberLookupFailed (ec, queried_type, lookup);
+                       return mge;
                }
 
-               protected virtual Expression Error_MemberLookupFailed (ResolveContext ec, Type type, MemberInfo[] members)
+               protected virtual MemberExpr Error_MemberLookupFailed (ResolveContext ec, TypeSpec type, IList<MemberSpec> members)
                {
-                       List<MethodSpec> methods = new List<MethodSpec> ();
-                       for (int i = 0; i < members.Length; ++i) {
-                               if (!(members [i] is MethodBase))
-                                       return null;
-
-                               methods.Add (Import.CreateMethod (members[i] as MethodBase));
-                       }
+                       if (members.Any ((m) => !(m is MethodSpec)))
+                               return (MemberExpr) ExprClassFromMemberInfo (type, members.First (), loc);
 
                        // By default propagate the closest candidates upwards
-                       return new MethodGroupExpr (methods.ToArray (), type, loc, true);
+                       return new MethodGroupExpr (members, type, loc, true);
                }
 
                protected virtual void Error_NegativeArrayIndex (ResolveContext ec, Location loc)
@@ -920,7 +812,7 @@ namespace Mono.CSharp {
                {
                        MethodGroupExpr operator_group;
                        string mname = Operator.GetMetadataName (is_true ? Operator.OpType.True : Operator.OpType.False);
-                       operator_group = MethodLookup (ec.Compiler, ec.CurrentType, e.Type, mname, loc) as MethodGroupExpr;
+                       operator_group = MethodLookup (ec.Compiler, ec.CurrentType, e.Type, MemberKind.Operator, mname, 0, loc) as MethodGroupExpr;
                        if (operator_group == null)
                                return null;
 
@@ -1029,85 +921,12 @@ namespace Mono.CSharp {
                        Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
                }
 
-               //
-               // Load the object from the pointer.  
-               //
-               public static void LoadFromPtr (ILGenerator ig, Type t)
-               {
-                       if (t == TypeManager.int32_type)
-                               ig.Emit (OpCodes.Ldind_I4);
-                       else if (t == TypeManager.uint32_type)
-                               ig.Emit (OpCodes.Ldind_U4);
-                       else if (t == TypeManager.short_type)
-                               ig.Emit (OpCodes.Ldind_I2);
-                       else if (t == TypeManager.ushort_type)
-                               ig.Emit (OpCodes.Ldind_U2);
-                       else if (t == TypeManager.char_type)
-                               ig.Emit (OpCodes.Ldind_U2);
-                       else if (t == TypeManager.byte_type)
-                               ig.Emit (OpCodes.Ldind_U1);
-                       else if (t == TypeManager.sbyte_type)
-                               ig.Emit (OpCodes.Ldind_I1);
-                       else if (t == TypeManager.uint64_type)
-                               ig.Emit (OpCodes.Ldind_I8);
-                       else if (t == TypeManager.int64_type)
-                               ig.Emit (OpCodes.Ldind_I8);
-                       else if (t == TypeManager.float_type)
-                               ig.Emit (OpCodes.Ldind_R4);
-                       else if (t == TypeManager.double_type)
-                               ig.Emit (OpCodes.Ldind_R8);
-                       else if (t == TypeManager.bool_type)
-                               ig.Emit (OpCodes.Ldind_I1);
-                       else if (t == TypeManager.intptr_type)
-                               ig.Emit (OpCodes.Ldind_I);
-                       else if (TypeManager.IsEnumType (t)) {
-                               if (t == TypeManager.enum_type)
-                                       ig.Emit (OpCodes.Ldind_Ref);
-                               else
-                                       LoadFromPtr (ig, TypeManager.GetEnumUnderlyingType (t));
-                       } else if (TypeManager.IsStruct (t) || TypeManager.IsGenericParameter (t))
-                               ig.Emit (OpCodes.Ldobj, t);
-                       else if (t.IsPointer)
-                               ig.Emit (OpCodes.Ldind_I);
-                       else
-                               ig.Emit (OpCodes.Ldind_Ref);
-               }
-
-               //
-               // The stack contains the pointer and the value of type `type'
-               //
-               public static void StoreFromPtr (ILGenerator ig, Type type)
-               {
-                       if (TypeManager.IsEnumType (type))
-                               type = TypeManager.GetEnumUnderlyingType (type);
-                       if (type == TypeManager.int32_type || type == TypeManager.uint32_type)
-                               ig.Emit (OpCodes.Stind_I4);
-                       else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)
-                               ig.Emit (OpCodes.Stind_I8);
-                       else if (type == TypeManager.char_type || type == TypeManager.short_type ||
-                                type == TypeManager.ushort_type)
-                               ig.Emit (OpCodes.Stind_I2);
-                       else if (type == TypeManager.float_type)
-                               ig.Emit (OpCodes.Stind_R4);
-                       else if (type == TypeManager.double_type)
-                               ig.Emit (OpCodes.Stind_R8);
-                       else if (type == TypeManager.byte_type || type == TypeManager.sbyte_type ||
-                                type == TypeManager.bool_type)
-                               ig.Emit (OpCodes.Stind_I1);
-                       else if (type == TypeManager.intptr_type)
-                               ig.Emit (OpCodes.Stind_I);
-                       else if (TypeManager.IsStruct (type) || TypeManager.IsGenericParameter (type))
-                               ig.Emit (OpCodes.Stobj, type);
-                       else
-                               ig.Emit (OpCodes.Stind_Ref);
-               }
-               
+       
                //
                // Returns the size of type `t' if known, otherwise, 0
                //
-               public static int GetTypeSize (Type t)
+               public static int GetTypeSize (TypeSpec t)
                {
-                       t = TypeManager.TypeToCoreType (t);
                        if (t == TypeManager.int32_type ||
                            t == TypeManager.uint32_type ||
                            t == TypeManager.float_type)
@@ -1152,7 +971,7 @@ namespace Mono.CSharp {
                //
                protected Expression ConvertExpressionToArrayIndex (ResolveContext ec, Expression source)
                {
-                       if (TypeManager.IsDynamicType (source.type)) {
+                       if (source.type == InternalType.Dynamic) {
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (source));
                                return new DynamicConversion (TypeManager.int32_type, CSharpBinderFlags.ConvertArrayIndex, args, loc).Resolve (ec);
@@ -1246,7 +1065,7 @@ namespace Mono.CSharp {
                {
                        TypeExpr texpr = TypeManager.expression_type_expr;
                        if (texpr == null) {
-                               Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "Expression", MemberKind.Class, true);
+                               TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "Expression", MemberKind.Class, true);
                                if (t == null)
                                        return null;
 
@@ -1265,11 +1084,6 @@ namespace Mono.CSharp {
                {
                        throw new NotImplementedException ("MakeExpression for " + GetType ());
                }
-
-               public virtual void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       // TODO: It should probably be type = storey.MutateType (type);
-               }
        }
 
        /// <summary>
@@ -1324,7 +1138,7 @@ namespace Mono.CSharp {
        {
                protected readonly Expression child;
 
-               protected TypeCast (Expression child, Type return_type)
+               protected TypeCast (Expression child, TypeSpec return_type)
                {
                        eclass = child.eclass;
                        loc = child.Location;
@@ -1366,14 +1180,8 @@ namespace Mono.CSharp {
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        return ctx.HasSet (BuilderContext.Options.CheckedScope) ?
-                               SLE.Expression.ConvertChecked (child.MakeExpression (ctx), type) :
-                               SLE.Expression.Convert (child.MakeExpression (ctx), type);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-                       child.MutateHoistedGenericType (storey);
+                               SLE.Expression.ConvertChecked (child.MakeExpression (ctx), type.GetMetaInfo ()) :
+                               SLE.Expression.Convert (child.MakeExpression (ctx), type.GetMetaInfo ());
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -1387,12 +1195,12 @@ namespace Mono.CSharp {
        }
 
        public class EmptyCast : TypeCast {
-               EmptyCast (Expression child, Type target_type)
+               EmptyCast (Expression child, TypeSpec target_type)
                        : base (child, target_type)
                {
                }
 
-               public static Expression Create (Expression child, Type type)
+               public static Expression Create (Expression child, TypeSpec type)
                {
                        Constant c = child as Constant;
                        if (c != null)
@@ -1420,14 +1228,14 @@ namespace Mono.CSharp {
        // Used for predefined class library user casts (no obsolete check, etc.)
        //
        public class OperatorCast : TypeCast {
-               MethodInfo conversion_operator;
+               MethodSpec conversion_operator;
                        
-               public OperatorCast (Expression child, Type target_type) 
+               public OperatorCast (Expression child, TypeSpec target_type) 
                        : this (child, target_type, false)
                {
                }
 
-               public OperatorCast (Expression child, Type target_type, bool find_explicit)
+               public OperatorCast (Expression child, TypeSpec target_type, bool find_explicit)
                        : base (child, target_type)
                {
                        conversion_operator = GetConversionOperator (find_explicit);
@@ -1437,24 +1245,23 @@ namespace Mono.CSharp {
 
                // Returns the implicit operator that converts from
                // 'child.Type' to our target type (type)
-               MethodInfo GetConversionOperator (bool find_explicit)
+               MethodSpec GetConversionOperator (bool find_explicit)
                {
                        string operator_name = find_explicit ? "op_Explicit" : "op_Implicit";
 
-                       MemberInfo [] mi;
-
-                       mi = TypeManager.MemberLookup (child.Type, child.Type, child.Type, MemberTypes.Method,
-                               BindingFlags.Static | BindingFlags.Public, operator_name, null);
+                       // Operators are always public
+                       var mi = TypeManager.MemberLookup (child.Type, child.Type, child.Type, MemberKind.Operator,
+                               BindingRestriction.None, operator_name, 0, null);
 
                        if (mi == null){
-                               mi = TypeManager.MemberLookup (type, type, type, MemberTypes.Method,
-                                                              BindingFlags.Static | BindingFlags.Public, operator_name, null);
+                               mi = TypeManager.MemberLookup (type, type, type, MemberKind.Operator,
+                                       BindingRestriction.None, operator_name, 0, null);
                        }
                        
-                       foreach (MethodInfo oper in mi) {
-                               AParametersCollection pd = TypeManager.GetParameterData (oper);
+                       foreach (MethodSpec oper in mi) {
+                               AParametersCollection pd = oper.Parameters;
 
-                               if (pd.Types [0] == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
+                               if (pd.Types [0] == child.Type && oper.ReturnType == type)
                                        return oper;
                        }
 
@@ -1464,7 +1271,7 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        child.Emit (ec);
-                       ec.ig.Emit (OpCodes.Call, conversion_operator);
+                       ec.Emit (OpCodes.Call, conversion_operator);
                }
        }
        
@@ -1488,14 +1295,13 @@ namespace Mono.CSharp {
        /// </summary>
        public class CastFromDecimal : TypeCast
        {
-               static Dictionary<Type, MethodInfo> operators;
+               static Dictionary<TypeSpec, MethodSpec> operators;
 
-               public CastFromDecimal (Expression child, Type return_type)
+               public CastFromDecimal (Expression child, TypeSpec return_type)
                        : base (child, return_type)
                {
                        if (child.Type != TypeManager.decimal_type)
-                               throw new InternalErrorException (
-                                       "The expected type is Decimal, instead it is " + child.Type.FullName);
+                               throw new ArgumentException ("Expected decimal child " + child.Type.GetSignatureForError ());
                }
 
                // Returns the explicit operator that converts from an
@@ -1503,15 +1309,15 @@ namespace Mono.CSharp {
                public Expression Resolve ()
                {
                        if (operators == null) {
-                               MemberInfo[] all_oper = TypeManager.MemberLookup (TypeManager.decimal_type,
-                                  TypeManager.decimal_type, TypeManager.decimal_type, MemberTypes.Method,
-                                  BindingFlags.Static | BindingFlags.Public, "op_Explicit", null);
+                               var all_oper = TypeManager.MemberLookup (TypeManager.decimal_type,
+                                  TypeManager.decimal_type, TypeManager.decimal_type, MemberKind.Operator,
+                                  BindingRestriction.None, "op_Explicit", 0, null);
 
-                               operators = new Dictionary<Type, MethodInfo> (ReferenceEquality<Type>.Default);
-                               foreach (MethodInfo oper in all_oper) {
-                                       AParametersCollection pd = TypeManager.GetParameterData (oper);
+                               operators = new Dictionary<TypeSpec, MethodSpec> ();
+                               foreach (MethodSpec oper in all_oper) {
+                                       AParametersCollection pd = oper.Parameters;
                                        if (pd.Types [0] == TypeManager.decimal_type)
-                                               operators.Add (TypeManager.TypeToCoreType (oper.ReturnType), oper);
+                                               operators.Add (oper.ReturnType, oper);
                                }
                        }
 
@@ -1520,10 +1326,14 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
                        child.Emit (ec);
 
-                       ig.Emit (OpCodes.Call, operators [type]);
+                       ec.Emit (OpCodes.Call, operators [type]);
+               }
+
+               public static void Reset ()
+               {
+                       operators = null;
                }
        }
 
@@ -1537,7 +1347,7 @@ namespace Mono.CSharp {
        {
                public Constant child;
 
-               public EmptyConstantCast (Constant child, Type type)
+               public EmptyConstantCast (Constant child, TypeSpec type)
                        : base (child.Location)
                {
                        if (child == null)
@@ -1558,7 +1368,7 @@ namespace Mono.CSharp {
                        return child.GetValue ();
                }
 
-               public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                {
                        if (child.Type == target_type)
                                return child;
@@ -1615,7 +1425,7 @@ namespace Mono.CSharp {
 
                        // Only to make verifier happy
                        if (TypeManager.IsGenericParameter (type) && child.IsNull)
-                               ec.ig.Emit (OpCodes.Unbox_Any, type);
+                               ec.Emit (OpCodes.Unbox_Any, type);
                }
 
                public override void EmitSideEffect (EmitContext ec)
@@ -1623,18 +1433,13 @@ namespace Mono.CSharp {
                        child.EmitSideEffect (ec);
                }
 
-               public override Constant ConvertImplicitly (ResolveContext rc, Type target_type)
+               public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type)
                {
                        // FIXME: Do we need to check user conversions?
                        if (!Convert.ImplicitStandardConversionExists (this, target_type))
                                return null;
                        return child.ConvertImplicitly (rc, target_type);
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       child.MutateHoistedGenericType (storey);
-               }
        }
 
        /// <summary>
@@ -1644,7 +1449,7 @@ namespace Mono.CSharp {
        {
                public Constant Child;
 
-               public EnumConstant (Constant child, Type enum_type)
+               public EnumConstant (Constant child, TypeSpec enum_type)
                        : base (child.Location)
                {
                        this.Child = child;
@@ -1668,7 +1473,7 @@ namespace Mono.CSharp {
                        Child.Emit (ec);
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        Child.EncodeAttributeValue (rc, enc, Child.Type);
                }
@@ -1708,11 +1513,11 @@ namespace Mono.CSharp {
                        //
                        // This works only sometimes
                        //
-                       if (TypeManager.IsBeingCompiled (type))
+                       if (type.MemberDefinition is TypeContainer)
                                return Child.GetValue ();
 #endif
 
-                       return System.Enum.ToObject (type, Child.GetValue ());
+                       return System.Enum.ToObject (type.GetMetaInfo (), Child.GetValue ());
                }
                
                public override string AsString ()
@@ -1741,7 +1546,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Constant ConvertExplicitly(bool in_checked_context, Type target_type)
+               public override Constant ConvertExplicitly(bool in_checked_context, TypeSpec target_type)
                {
                        if (Child.Type == target_type)
                                return Child;
@@ -1749,19 +1554,9 @@ namespace Mono.CSharp {
                        return Child.ConvertExplicitly (in_checked_context, target_type);
                }
 
-               public override Constant ConvertImplicitly (ResolveContext rc, Type type)
+               public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
                {
-                       Type this_type = TypeManager.DropGenericTypeArguments (Type);
-                       type = TypeManager.DropGenericTypeArguments (type);
-
-                       if (this_type == type) {
-                               // This is workaround of mono bug. It can be removed when the latest corlib spreads enough
-                               if (TypeManager.IsEnumType (type.UnderlyingSystemType))
-                                       return this;
-
-                               Type child_type = TypeManager.DropGenericTypeArguments (Child.Type);
-                               if (type.UnderlyingSystemType != child_type)
-                                       Child = Child.ConvertImplicitly (rc, type.UnderlyingSystemType);
+                       if (this.type == type) {
                                return this;
                        }
 
@@ -1781,7 +1576,7 @@ namespace Mono.CSharp {
        /// </summary>
        public class BoxedCast : TypeCast {
 
-               public BoxedCast (Expression expr, Type target_type)
+               public BoxedCast (Expression expr, TypeSpec target_type)
                        : base (expr, target_type)
                {
                        eclass = ExprClass.Value;
@@ -1795,7 +1590,7 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        enc.Encode (child.Type);
                        child.EncodeAttributeValue (rc, enc, child.Type);
@@ -1805,7 +1600,7 @@ namespace Mono.CSharp {
                {
                        base.Emit (ec);
                        
-                       ec.ig.Emit (OpCodes.Box, child.Type);
+                       ec.Emit (OpCodes.Box, child.Type);
                }
 
                public override void EmitSideEffect (EmitContext ec)
@@ -1821,7 +1616,7 @@ namespace Mono.CSharp {
        }
 
        public class UnboxCast : TypeCast {
-               public UnboxCast (Expression expr, Type return_type)
+               public UnboxCast (Expression expr, TypeSpec return_type)
                        : base (expr, return_type)
                {
                }
@@ -1845,14 +1640,7 @@ namespace Mono.CSharp {
                {
                        base.Emit (ec);
 
-                       ILGenerator ig = ec.ig;
-                       ig.Emit (OpCodes.Unbox_Any, type);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-                       base.MutateHoistedGenericType (storey);                 
+                       ec.Emit (OpCodes.Unbox_Any, type);
                }
        }
        
@@ -1881,7 +1669,7 @@ namespace Mono.CSharp {
 
                Mode mode;
                
-               public ConvCast (Expression child, Type return_type, Mode m)
+               public ConvCast (Expression child, TypeSpec return_type, Mode m)
                        : base (child, return_type)
                {
                        mode = m;
@@ -1902,179 +1690,177 @@ namespace Mono.CSharp {
                
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       
                        base.Emit (ec);
 
                        if (ec.HasSet (EmitContext.Options.CheckedScope)) {
                                switch (mode){
-                               case Mode.I1_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
-                               case Mode.I1_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-                               case Mode.I1_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
-                               case Mode.I1_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
-                               case Mode.I1_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I1_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.I1_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I1_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.I1_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.I1_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
 
-                               case Mode.U1_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.U1_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
                                case Mode.U1_CH: /* nothing */ break;
 
-                               case Mode.I2_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
-                               case Mode.I2_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
-                               case Mode.I2_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-                               case Mode.I2_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
-                               case Mode.I2_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
-                               case Mode.I2_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I2_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.I2_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.I2_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I2_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.I2_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.I2_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
 
-                               case Mode.U2_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
-                               case Mode.U2_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
-                               case Mode.U2_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+                               case Mode.U2_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.U2_U1: ec.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+                               case Mode.U2_I2: ec.Emit (OpCodes.Conv_Ovf_I2_Un); break;
                                case Mode.U2_CH: /* nothing */ break;
 
-                               case Mode.I4_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
-                               case Mode.I4_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
-                               case Mode.I4_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
-                               case Mode.I4_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
-                               case Mode.I4_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-                               case Mode.I4_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
-                               case Mode.I4_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-
-                               case Mode.U4_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
-                               case Mode.U4_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
-                               case Mode.U4_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
-                               case Mode.U4_U2: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
-                               case Mode.U4_I4: ig.Emit (OpCodes.Conv_Ovf_I4_Un); break;
-                               case Mode.U4_CH: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
-
-                               case Mode.I8_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
-                               case Mode.I8_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
-                               case Mode.I8_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
-                               case Mode.I8_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-                               case Mode.I8_I4: ig.Emit (OpCodes.Conv_Ovf_I4); break;
-                               case Mode.I8_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
-                               case Mode.I8_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
-                               case Mode.I8_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-                               case Mode.I8_I: ig.Emit (OpCodes.Conv_Ovf_U); break;
-
-                               case Mode.U8_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
-                               case Mode.U8_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
-                               case Mode.U8_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
-                               case Mode.U8_U2: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
-                               case Mode.U8_I4: ig.Emit (OpCodes.Conv_Ovf_I4_Un); break;
-                               case Mode.U8_U4: ig.Emit (OpCodes.Conv_Ovf_U4_Un); break;
-                               case Mode.U8_I8: ig.Emit (OpCodes.Conv_Ovf_I8_Un); break;
-                               case Mode.U8_CH: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
-                               case Mode.U8_I: ig.Emit (OpCodes.Conv_Ovf_U_Un); break;
-
-                               case Mode.CH_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
-                               case Mode.CH_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
-                               case Mode.CH_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
-
-                               case Mode.R4_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
-                               case Mode.R4_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
-                               case Mode.R4_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
-                               case Mode.R4_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-                               case Mode.R4_I4: ig.Emit (OpCodes.Conv_Ovf_I4); break;
-                               case Mode.R4_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
-                               case Mode.R4_I8: ig.Emit (OpCodes.Conv_Ovf_I8); break;
-                               case Mode.R4_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
-                               case Mode.R4_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-
-                               case Mode.R8_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
-                               case Mode.R8_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
-                               case Mode.R8_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
-                               case Mode.R8_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-                               case Mode.R8_I4: ig.Emit (OpCodes.Conv_Ovf_I4); break;
-                               case Mode.R8_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
-                               case Mode.R8_I8: ig.Emit (OpCodes.Conv_Ovf_I8); break;
-                               case Mode.R8_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
-                               case Mode.R8_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
-                               case Mode.R8_R4: ig.Emit (OpCodes.Conv_R4); break;
-
-                               case Mode.I_I8: ig.Emit (OpCodes.Conv_Ovf_I8_Un); break;
+                               case Mode.I4_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.I4_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.I4_I2: ec.Emit (OpCodes.Conv_Ovf_I2); break;
+                               case Mode.I4_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.I4_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I4_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.I4_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+
+                               case Mode.U4_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.U4_U1: ec.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+                               case Mode.U4_I2: ec.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+                               case Mode.U4_U2: ec.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+                               case Mode.U4_I4: ec.Emit (OpCodes.Conv_Ovf_I4_Un); break;
+                               case Mode.U4_CH: ec.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+
+                               case Mode.I8_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.I8_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.I8_I2: ec.Emit (OpCodes.Conv_Ovf_I2); break;
+                               case Mode.I8_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I8_I4: ec.Emit (OpCodes.Conv_Ovf_I4); break;
+                               case Mode.I8_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.I8_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.I8_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I8_I: ec.Emit (OpCodes.Conv_Ovf_U); break;
+
+                               case Mode.U8_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.U8_U1: ec.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+                               case Mode.U8_I2: ec.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+                               case Mode.U8_U2: ec.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+                               case Mode.U8_I4: ec.Emit (OpCodes.Conv_Ovf_I4_Un); break;
+                               case Mode.U8_U4: ec.Emit (OpCodes.Conv_Ovf_U4_Un); break;
+                               case Mode.U8_I8: ec.Emit (OpCodes.Conv_Ovf_I8_Un); break;
+                               case Mode.U8_CH: ec.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+                               case Mode.U8_I: ec.Emit (OpCodes.Conv_Ovf_U_Un); break;
+
+                               case Mode.CH_I1: ec.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.CH_U1: ec.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+                               case Mode.CH_I2: ec.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+
+                               case Mode.R4_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.R4_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.R4_I2: ec.Emit (OpCodes.Conv_Ovf_I2); break;
+                               case Mode.R4_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.R4_I4: ec.Emit (OpCodes.Conv_Ovf_I4); break;
+                               case Mode.R4_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.R4_I8: ec.Emit (OpCodes.Conv_Ovf_I8); break;
+                               case Mode.R4_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.R4_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+
+                               case Mode.R8_I1: ec.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.R8_U1: ec.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.R8_I2: ec.Emit (OpCodes.Conv_Ovf_I2); break;
+                               case Mode.R8_U2: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.R8_I4: ec.Emit (OpCodes.Conv_Ovf_I4); break;
+                               case Mode.R8_U4: ec.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.R8_I8: ec.Emit (OpCodes.Conv_Ovf_I8); break;
+                               case Mode.R8_U8: ec.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.R8_CH: ec.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.R8_R4: ec.Emit (OpCodes.Conv_R4); break;
+
+                               case Mode.I_I8: ec.Emit (OpCodes.Conv_Ovf_I8_Un); break;
                                }
                        } else {
                                switch (mode){
-                               case Mode.I1_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.I1_U2: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.I1_U4: ig.Emit (OpCodes.Conv_U4); break;
-                               case Mode.I1_U8: ig.Emit (OpCodes.Conv_I8); break;
-                               case Mode.I1_CH: ig.Emit (OpCodes.Conv_U2); break;
-
-                               case Mode.U1_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.U1_CH: ig.Emit (OpCodes.Conv_U2); break;
-
-                               case Mode.I2_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.I2_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.I2_U2: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.I2_U4: ig.Emit (OpCodes.Conv_U4); break;
-                               case Mode.I2_U8: ig.Emit (OpCodes.Conv_I8); break;
-                               case Mode.I2_CH: ig.Emit (OpCodes.Conv_U2); break;
-
-                               case Mode.U2_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.U2_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.U2_I2: ig.Emit (OpCodes.Conv_I2); break;
+                               case Mode.I1_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.I1_U2: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I1_U4: ec.Emit (OpCodes.Conv_U4); break;
+                               case Mode.I1_U8: ec.Emit (OpCodes.Conv_I8); break;
+                               case Mode.I1_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.U1_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.U1_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.I2_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.I2_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.I2_U2: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I2_U4: ec.Emit (OpCodes.Conv_U4); break;
+                               case Mode.I2_U8: ec.Emit (OpCodes.Conv_I8); break;
+                               case Mode.I2_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.U2_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.U2_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.U2_I2: ec.Emit (OpCodes.Conv_I2); break;
                                case Mode.U2_CH: /* nothing */ break;
 
-                               case Mode.I4_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.I4_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.I4_I2: ig.Emit (OpCodes.Conv_I2); break;
+                               case Mode.I4_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.I4_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.I4_I2: ec.Emit (OpCodes.Conv_I2); break;
                                case Mode.I4_U4: /* nothing */ break;
-                               case Mode.I4_U2: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.I4_U8: ig.Emit (OpCodes.Conv_I8); break;
-                               case Mode.I4_CH: ig.Emit (OpCodes.Conv_U2); break;
-
-                               case Mode.U4_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.U4_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.U4_I2: ig.Emit (OpCodes.Conv_I2); break;
-                               case Mode.U4_U2: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I4_U2: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I4_U8: ec.Emit (OpCodes.Conv_I8); break;
+                               case Mode.I4_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.U4_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.U4_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.U4_I2: ec.Emit (OpCodes.Conv_I2); break;
+                               case Mode.U4_U2: ec.Emit (OpCodes.Conv_U2); break;
                                case Mode.U4_I4: /* nothing */ break;
-                               case Mode.U4_CH: ig.Emit (OpCodes.Conv_U2); break;
-
-                               case Mode.I8_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.I8_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.I8_I2: ig.Emit (OpCodes.Conv_I2); break;
-                               case Mode.I8_U2: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.I8_I4: ig.Emit (OpCodes.Conv_I4); break;
-                               case Mode.I8_U4: ig.Emit (OpCodes.Conv_U4); break;
+                               case Mode.U4_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.I8_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.I8_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.I8_I2: ec.Emit (OpCodes.Conv_I2); break;
+                               case Mode.I8_U2: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I8_I4: ec.Emit (OpCodes.Conv_I4); break;
+                               case Mode.I8_U4: ec.Emit (OpCodes.Conv_U4); break;
                                case Mode.I8_U8: /* nothing */ break;
-                               case Mode.I8_CH: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.I8_I: ig.Emit (OpCodes.Conv_U); break;
-
-                               case Mode.U8_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.U8_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.U8_I2: ig.Emit (OpCodes.Conv_I2); break;
-                               case Mode.U8_U2: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.U8_I4: ig.Emit (OpCodes.Conv_I4); break;
-                               case Mode.U8_U4: ig.Emit (OpCodes.Conv_U4); break;
+                               case Mode.I8_CH: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I8_I: ec.Emit (OpCodes.Conv_U); break;
+
+                               case Mode.U8_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.U8_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.U8_I2: ec.Emit (OpCodes.Conv_I2); break;
+                               case Mode.U8_U2: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.U8_I4: ec.Emit (OpCodes.Conv_I4); break;
+                               case Mode.U8_U4: ec.Emit (OpCodes.Conv_U4); break;
                                case Mode.U8_I8: /* nothing */ break;
-                               case Mode.U8_CH: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.U8_I: ig.Emit (OpCodes.Conv_U); break;
-
-                               case Mode.CH_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.CH_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.CH_I2: ig.Emit (OpCodes.Conv_I2); break;
-
-                               case Mode.R4_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.R4_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.R4_I2: ig.Emit (OpCodes.Conv_I2); break;
-                               case Mode.R4_U2: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.R4_I4: ig.Emit (OpCodes.Conv_I4); break;
-                               case Mode.R4_U4: ig.Emit (OpCodes.Conv_U4); break;
-                               case Mode.R4_I8: ig.Emit (OpCodes.Conv_I8); break;
-                               case Mode.R4_U8: ig.Emit (OpCodes.Conv_U8); break;
-                               case Mode.R4_CH: ig.Emit (OpCodes.Conv_U2); break;
-
-                               case Mode.R8_I1: ig.Emit (OpCodes.Conv_I1); break;
-                               case Mode.R8_U1: ig.Emit (OpCodes.Conv_U1); break;
-                               case Mode.R8_I2: ig.Emit (OpCodes.Conv_I2); break;
-                               case Mode.R8_U2: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.R8_I4: ig.Emit (OpCodes.Conv_I4); break;
-                               case Mode.R8_U4: ig.Emit (OpCodes.Conv_U4); break;
-                               case Mode.R8_I8: ig.Emit (OpCodes.Conv_I8); break;
-                               case Mode.R8_U8: ig.Emit (OpCodes.Conv_U8); break;
-                               case Mode.R8_CH: ig.Emit (OpCodes.Conv_U2); break;
-                               case Mode.R8_R4: ig.Emit (OpCodes.Conv_R4); break;
-
-                               case Mode.I_I8: ig.Emit (OpCodes.Conv_U8); break;
+                               case Mode.U8_CH: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.U8_I: ec.Emit (OpCodes.Conv_U); break;
+
+                               case Mode.CH_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.CH_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.CH_I2: ec.Emit (OpCodes.Conv_I2); break;
+
+                               case Mode.R4_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.R4_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.R4_I2: ec.Emit (OpCodes.Conv_I2); break;
+                               case Mode.R4_U2: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.R4_I4: ec.Emit (OpCodes.Conv_I4); break;
+                               case Mode.R4_U4: ec.Emit (OpCodes.Conv_U4); break;
+                               case Mode.R4_I8: ec.Emit (OpCodes.Conv_I8); break;
+                               case Mode.R4_U8: ec.Emit (OpCodes.Conv_U8); break;
+                               case Mode.R4_CH: ec.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.R8_I1: ec.Emit (OpCodes.Conv_I1); break;
+                               case Mode.R8_U1: ec.Emit (OpCodes.Conv_U1); break;
+                               case Mode.R8_I2: ec.Emit (OpCodes.Conv_I2); break;
+                               case Mode.R8_U2: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.R8_I4: ec.Emit (OpCodes.Conv_I4); break;
+                               case Mode.R8_U4: ec.Emit (OpCodes.Conv_U4); break;
+                               case Mode.R8_I8: ec.Emit (OpCodes.Conv_I8); break;
+                               case Mode.R8_U8: ec.Emit (OpCodes.Conv_U8); break;
+                               case Mode.R8_CH: ec.Emit (OpCodes.Conv_U2); break;
+                               case Mode.R8_R4: ec.Emit (OpCodes.Conv_R4); break;
+
+                               case Mode.I_I8: ec.Emit (OpCodes.Conv_U8); break;
                                }
                        }
                }
@@ -2083,7 +1869,7 @@ namespace Mono.CSharp {
        public class OpcodeCast : TypeCast {
                readonly OpCode op;
                
-               public OpcodeCast (Expression child, Type return_type, OpCode op)
+               public OpcodeCast (Expression child, TypeSpec return_type, OpCode op)
                        : base (child, return_type)
                {
                        this.op = op;
@@ -2100,10 +1886,10 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        base.Emit (ec);
-                       ec.ig.Emit (op);
+                       ec.Emit (op);
                }
 
-               public Type UnderlyingType {
+               public TypeSpec UnderlyingType {
                        get { return child.Type; }
                }
        }
@@ -2115,12 +1901,12 @@ namespace Mono.CSharp {
        public sealed class ClassCast : TypeCast {
                readonly bool forced;
                
-               public ClassCast (Expression child, Type return_type)
+               public ClassCast (Expression child, TypeSpec return_type)
                        : base (child, return_type)
                {
                }
                
-               public ClassCast (Expression child, Type return_type, bool forced)
+               public ClassCast (Expression child, TypeSpec return_type, bool forced)
                        : base (child, return_type)
                {
                        this.forced = forced;
@@ -2132,17 +1918,17 @@ namespace Mono.CSharp {
 
                        bool gen = TypeManager.IsGenericParameter (child.Type);
                        if (gen)
-                               ec.ig.Emit (OpCodes.Box, child.Type);
+                               ec.Emit (OpCodes.Box, child.Type);
                        
                        if (type.IsGenericParameter) {
-                               ec.ig.Emit (OpCodes.Unbox_Any, type);
+                               ec.Emit (OpCodes.Unbox_Any, type);
                                return;
                        }
                        
                        if (gen && !forced)
                                return;
                        
-                       ec.ig.Emit (OpCodes.Castclass, type);
+                       ec.Emit (OpCodes.Castclass, type);
                }
        }
 
@@ -2162,7 +1948,7 @@ namespace Mono.CSharp {
                                this.orig_expr = orig_expr;
                        }
 
-                       public override Constant ConvertImplicitly (ResolveContext rc, Type target_type)
+                       public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec target_type)
                        {
                                Constant c = base.ConvertImplicitly (rc, target_type);
                                if (c != null)
@@ -2176,7 +1962,7 @@ namespace Mono.CSharp {
                                return orig_expr.CreateExpressionTree (ec);
                        }
 
-                       public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+                       public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
                        {
                                Constant c = base.ConvertExplicitly (in_checked_context, target_type);
                                if (c != null)
@@ -2218,11 +2004,6 @@ namespace Mono.CSharp {
                        {
                                stm.EmitStatement (ec);
                        }
-
-                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                       {
-                               stm.MutateHoistedGenericType (storey);
-                       }
                }
 
                readonly Expression expr, orig_expr;
@@ -2296,11 +2077,6 @@ namespace Mono.CSharp {
                {
                        return orig_expr.MakeExpression (ctx);
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-               }
        }
 
        //
@@ -2380,11 +2156,6 @@ namespace Mono.CSharp {
                public Expression Expr {
                        get { return expr; }
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       throw new InternalErrorException ("Missing Resolve call");
-               }
        }
 
        //
@@ -2408,12 +2179,42 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
+               protected ATypeNameExpression (string name, int arity, Location l)
+                       : this (name, new UnboundTypeArguments (arity), l)
+               {
+               }
+
+               #region Properties
+
+               protected int Arity {
+                       get {
+                               return targs == null ? 0 : targs.Count;
+                       }
+               }
+
                public bool HasTypeArguments {
                        get {
-                               return targs != null;
+                               return targs != null && !targs.IsEmpty;
                        }
                }
 
+               public string Name {
+                       get {
+                               return name;
+                       }
+                       set {
+                               name = value;
+                       }
+               }
+
+               public TypeArguments TypeArguments {
+                       get {
+                               return targs;
+                       }
+               }
+
+               #endregion
+
                public override bool Equals (object obj)
                {
                        ATypeNameExpression atne = obj as ATypeNameExpression;
@@ -2426,29 +2227,32 @@ namespace Mono.CSharp {
                        return Name.GetHashCode ();
                }
 
-               public override string GetSignatureForError ()
+               // TODO: Move it to MemberCore
+               public static string GetMemberType (MemberCore mc)
                {
-                       if (targs != null) {
-                               return TypeManager.RemoveGenericArity (Name) + "<" +
-                                       targs.GetSignatureForError () + ">";
-                       }
+                       if (mc is Property)
+                               return "property";
+                       if (mc is Indexer)
+                               return "indexer";
+                       if (mc is FieldBase)
+                               return "field";
+                       if (mc is MethodCore)
+                               return "method";
+                       if (mc is EnumMember)
+                               return "enum";
+                       if (mc is Event)
+                               return "event";
 
-                       return Name;
+                       return "type";
                }
 
-               public string Name {
-                       get {
-                               return name;
-                       }
-                       set {
-                               name = value;
+               public override string GetSignatureForError ()
+               {
+                       if (targs != null) {
+                               return Name + "<" + targs.GetSignatureForError () + ">";
                        }
-               }
 
-               public TypeArguments TypeArguments {
-                       get {
-                               return targs;
-                       }
+                       return Name;
                }
        }
        
@@ -2468,45 +2272,14 @@ namespace Mono.CSharp {
                {
                }
 
-               public SimpleName (string name, TypeParameter[] type_params, Location l)
-                       : base (name, l)
+               public SimpleName (string name, int arity, Location l)
+                       : base (name, arity, l)
                {
-                       targs = new TypeArguments ();
-                       foreach (TypeParameter type_param in type_params)
-                               targs.Add (new TypeParameterExpr (type_param, l));
-               }
-
-               public static string RemoveGenericArity (string name)
-               {
-                       int start = 0;
-                       StringBuilder sb = null;
-                       do {
-                               int pos = name.IndexOf ('`', start);
-                               if (pos < 0) {
-                                       if (start == 0)
-                                               return name;
-
-                                       sb.Append (name.Substring (start));
-                                       break;
-                               }
-
-                               if (sb == null)
-                                       sb = new StringBuilder ();
-                               sb.Append (name.Substring (start, pos-start));
-
-                               pos++;
-                               while ((pos < name.Length) && Char.IsNumber (name [pos]))
-                                       pos++;
-
-                               start = pos;
-                       } while (start < name.Length);
-
-                       return sb.ToString ();
                }
 
                public SimpleName GetMethodGroup ()
                {
-                       return new SimpleName (RemoveGenericArity (Name), targs, loc);
+                       return new SimpleName (Name, targs, loc);
                }
 
                public static void Error_ObjectRefRequired (ResolveContext ec, Location l, string name)
@@ -2521,11 +2294,67 @@ namespace Mono.CSharp {
                                        name);
                }
 
+               protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ec)
+               {
+                       if (ec.CurrentType != null) {
+                               if (ec.CurrentMemberDefinition != null) {
+                                       MemberCore mc = ec.CurrentMemberDefinition.Parent.GetDefinition (Name);
+                                       if (mc != null) {
+                                               Error_UnexpectedKind (ec.Compiler.Report, mc, "type", GetMemberType (mc), loc);
+                                               return;
+                                       }
+                               }
+
+                               /*
+                                                               // TODO MemberCache: Implement
+                                                               string ns = ec.CurrentType.Namespace;
+                                                               string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
+                                                               foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
+                                                                       var type = a.GetType (fullname);
+                                                                       if (type != null) {
+                                                                               ec.Compiler.Report.SymbolRelatedToPreviousError (type);
+                                                                               Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type), ec.Compiler.Report);
+                                                                               return;
+                                                                       }
+                                                               }
+
+                                                               if (ec.CurrentTypeDefinition != null) {
+                                                                       TypeSpec t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name);
+                                                                       if (t != null) {
+                                                                               Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, t, loc);
+                                                                               return;
+                                                                       }
+                                                               }
+                               */
+                       }
+
+                       FullNamedExpression retval = ec.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), loc, true);
+                       if (retval != null) {
+                               Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc, retval.Type, Arity);
+/*
+                               var te = retval as TypeExpr;
+                               if (HasTypeArguments && te != null && !te.Type.IsGeneric)
+                                       retval.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
+                               else
+                                       Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, retval.Type, loc);
+*/
+                               return;
+                       }
+
+                       NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
+               }
+
                public bool IdenticalNameAndTypeName (IMemberContext mc, Expression resolved_to, Location loc)
                {
-                       return resolved_to != null && resolved_to.Type != null && 
-                               resolved_to.Type.Name == Name &&
-                               (mc.LookupNamespaceOrType (Name, loc, /* ignore_cs0104 = */ true) != null);
+                       if (resolved_to == null || resolved_to.Type == null)
+                               return false;
+
+                       if (resolved_to.Type is ElementTypeSpec || resolved_to.Type is InternalType)
+                               return false;
+
+                       return resolved_to.Type.Name == Name &&
+                               (mc.LookupNamespaceOrType (Name, Arity, loc, /* ignore_cs0104 = */ true) != null);
                }
 
                protected override Expression DoResolve (ResolveContext ec)
@@ -2543,10 +2372,10 @@ namespace Mono.CSharp {
                        return SimpleNameResolve (ec, null, intermediate);
                }
 
-               static bool IsNestedChild (Type t, Type parent)
+               static bool IsNestedChild (TypeSpec t, TypeSpec parent)
                {
                        while (parent != null) {
-                               if (TypeManager.IsNestedChildOf (t, TypeManager.DropGenericTypeArguments (parent)))
+                               if (TypeManager.IsNestedChildOf (t, parent))
                                        return true;
 
                                parent = parent.BaseType;
@@ -2555,59 +2384,15 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               FullNamedExpression ResolveNested (Type t)
-               {
-                       if (!TypeManager.IsGenericTypeDefinition (t) && !TypeManager.IsGenericType (t))
-                               return null;
-
-                       Type ds = t;
-                       while (ds != null && !IsNestedChild (t, ds))
-                               ds = ds.DeclaringType;
-
-                       if (ds == null)
-                               return null;
-
-                       Type[] gen_params = TypeManager.GetTypeArguments (t);
-
-                       int arg_count = targs != null ? targs.Count : 0;
-
-                       for (; (ds != null) && TypeManager.IsGenericType (ds); ds = ds.DeclaringType) {
-                               Type[] gargs = TypeManager.GetTypeArguments (ds);
-                               if (arg_count + gargs.Length == gen_params.Length) {
-                                       TypeArguments new_args = new TypeArguments ();
-                                       foreach (Type param in gargs)
-                                               new_args.Add (new TypeExpression (param, loc));
-
-                                       if (targs != null)
-                                               new_args.Add (targs);
-
-                                       return new GenericTypeExpr (t, new_args, loc);
-                               }
-                       }
-
-                       return null;
-               }
-
                public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
                {
                        int errors = ec.Compiler.Report.Errors;
-                       FullNamedExpression fne = ec.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);
+                       FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false);
 
                        if (fne != null) {
-                               if (fne.Type == null)
-                                       return fne;
-
-                               FullNamedExpression nested = ResolveNested (fne.Type);
-                               if (nested != null)
-                                       return nested.ResolveAsTypeStep (ec, false);
-
-                               if (targs != null) {
-                                       if (TypeManager.IsGenericType (fne.Type)) {
-                                               GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
-                                               return ct.ResolveAsTypeStep (ec, false);
-                                       }
-
-                                       fne.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
+                               if (HasTypeArguments && fne.Type != null && TypeManager.IsGenericType (fne.Type)) {
+                                       GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
+                                       return ct.ResolveAsTypeStep (ec, false);
                                }
 
                                return fne;
@@ -2633,68 +2418,6 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               protected virtual void Error_TypeOrNamespaceNotFound (IMemberContext ec)
-               {
-                       if (ec.CurrentType != null) {
-                               if (ec.CurrentTypeDefinition != null) {
-                                       MemberCore mc = ec.CurrentTypeDefinition.GetDefinition (Name);
-                                       if (mc != null) {
-                                               Error_UnexpectedKind (ec.Compiler.Report, mc, "type", GetMemberType (mc), loc);
-                                               return;
-                                       }
-                               }
-
-                               string ns = ec.CurrentType.Namespace;
-                               string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
-                               foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
-                                       Type type = a.GetType (fullname);
-                                       if (type != null) {
-                                               ec.Compiler.Report.SymbolRelatedToPreviousError (type);
-                                               Expression.ErrorIsInaccesible (loc, TypeManager.CSharpName (type), ec.Compiler.Report);
-                                               return;
-                                       }
-                               }
-
-                               if (ec.CurrentTypeDefinition != null) {
-                                       Type t = ec.CurrentTypeDefinition.LookupAnyGeneric (Name);
-                                       if (t != null) {
-                                               Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, t, loc);
-                                               return;
-                                       }
-                               }
-                       }
-
-                       if (targs != null) {
-                               FullNamedExpression retval = ec.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
-                               if (retval != null) {
-                                       retval.Error_TypeArgumentsCannotBeUsed (ec.Compiler.Report, loc);
-                                       return;
-                               }
-                       }
-                                               
-                       NamespaceEntry.Error_NamespaceNotFound (loc, Name, ec.Compiler.Report);
-               }
-
-               // TODO: I am still not convinced about this. If someone else will need it
-               // implement this as virtual property in MemberCore hierarchy
-               public static string GetMemberType (MemberCore mc)
-               {
-                       if (mc is Property)
-                               return "property";
-                       if (mc is Indexer)
-                               return "indexer";
-                       if (mc is FieldBase)
-                               return "field";
-                       if (mc is MethodCore)
-                               return "method";
-                       if (mc is EnumMember)
-                               return "enum";
-                       if (mc is Event)
-                               return "event";
-
-                       return "type";
-               }
-
                Expression SimpleNameResolve (ResolveContext ec, Expression right_side, bool intermediate)
                {
                        Expression e = DoSimpleNameResolve (ec, right_side, intermediate);
@@ -2750,8 +2473,8 @@ namespace Mono.CSharp {
                                                }
                                        }
 
-                                       if (targs != null && e != null)
-                                               e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
+                                       if (HasTypeArguments && e != null)
+                                               e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
 
                                        return e;
                                }
@@ -2763,8 +2486,8 @@ namespace Mono.CSharp {
                                        else
                                                e = e.Resolve (ec);
 
-                                       if (targs != null && e != null)
-                                               e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
+                                       if (HasTypeArguments && e != null)
+                                               e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
 
                                        return e;
                                }
@@ -2773,24 +2496,22 @@ namespace Mono.CSharp {
                        //
                        // Stage 2: Lookup members 
                        //
-
-                       Type almost_matched_type = null;
-                       IList<MemberInfo> almost_matched = null;
-                       for (Type lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
-                               e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, loc);
+                       int arity = HasTypeArguments ? Arity : -1;
+//                     TypeSpec almost_matched_type = null;
+//                     IList<MemberSpec> almost_matched = null;
+                       for (TypeSpec lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
+                               e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, arity, BindingRestriction.NoOverrides, loc);
                                if (e != null) {
                                        PropertyExpr pe = e as PropertyExpr;
                                        if (pe != null) {
-                                               AParametersCollection param = TypeManager.GetParameterData (pe.PropertyInfo);
-
                                                // since TypeManager.MemberLookup doesn't know if we're doing a lvalue access or not,
                                                // it doesn't know which accessor to check permissions against
-                                               if (param.IsEmpty && pe.IsAccessibleFrom (ec.CurrentType, right_side != null))
+                                               if (pe.PropertyInfo.Kind == MemberKind.Property && pe.IsAccessibleFrom (ec.CurrentType, right_side != null))
                                                        break;
                                        } else if (e is EventExpr) {
                                                if (((EventExpr) e).IsAccessibleFrom (ec.CurrentType))
                                                        break;
-                                       } else if (targs != null && e is TypeExpression) {
+                                       } else if (HasTypeArguments && e is TypeExpression) {
                                                e = new GenericTypeExpr (e.Type, targs, loc).ResolveAsTypeStep (ec, false);
                                                break;
                                        } else {
@@ -2798,18 +2519,21 @@ namespace Mono.CSharp {
                                        }
                                        e = null;
                                }
-
+/*
                                if (almost_matched == null && almost_matched_members.Count > 0) {
                                        almost_matched_type = lookup_ds;
-                                       almost_matched = new List<MemberInfo>(almost_matched_members);
+                                       almost_matched = new List<MemberSpec>(almost_matched_members);
                                }
+*/ 
                        }
 
                        if (e == null) {
+/*
                                if (almost_matched == null && almost_matched_members.Count > 0) {
                                        almost_matched_type = ec.CurrentType;
-                                       almost_matched = new List<MemberInfo> (almost_matched_members);
+                                       almost_matched = new List<MemberSpec> (almost_matched_members);
                                }
+*/ 
                                e = ResolveAsTypeStep (ec, true);
                        }
 
@@ -2830,17 +2554,17 @@ namespace Mono.CSharp {
                                if (RootContext.EvalMode){
                                        FieldInfo fi = Evaluator.LookupField (Name);
                                        if (fi != null)
-                                               return new FieldExpr (Import.CreateField (fi), loc).Resolve (ec);
+                                               return new FieldExpr (Import.CreateField (fi, null), loc).Resolve (ec);
                                }
-
+/*
                                if (almost_matched != null)
                                        almost_matched_members = almost_matched;
                                if (almost_matched_type == null)
                                        almost_matched_type = ec.CurrentType;
-
+*/
                                string type_name = ec.MemberContext.CurrentType == null ? null : ec.MemberContext.CurrentType.Name;
-                               return Error_MemberLookupFailed (ec, ec.CurrentType, null, almost_matched_type, Name,
-                                       type_name, AllMemberTypes, AllBindingFlags);
+                               return Error_MemberLookupFailed (ec, ec.CurrentType, null, ec.CurrentType, Name, arity,
+                                       type_name, MemberKind.All, BindingRestriction.AccessibleOnly);
                        }
 
                        if (e is MemberExpr) {
@@ -2855,13 +2579,13 @@ namespace Mono.CSharp {
                                                // and each predicate is true if the MethodGroupExpr contains
                                                // at least one of that kind of method.
                                                //
-
+/*
                                                if (!me.IsStatic &&
                                                    (!intermediate || !IdenticalNameAndTypeName (ec, me, loc))) {
                                                        Error_ObjectRefRequired (ec, loc, me.GetSignatureForError ());
                                                        return null;
                                                }
-
+*/
                                                //
                                                // Pass the buck to MemberAccess and Invocation.
                                                //
@@ -2877,7 +2601,7 @@ namespace Mono.CSharp {
                                if (me == null)
                                        return null;
 
-                               if (targs != null) {
+                               if (HasTypeArguments) {
                                        if (!targs.Resolve (ec))
                                                return null;
 
@@ -2920,11 +2644,6 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ("ET");
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       throw new NotSupportedException ();
-               }
-
                public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
                {
                        return this;
@@ -2958,35 +2677,11 @@ namespace Mono.CSharp {
 
                public virtual bool CheckAccessLevel (IMemberContext mc)
                {
-                       return mc.CurrentTypeDefinition.CheckAccessLevel (Type);
-               }
+                       DeclSpace c = mc.CurrentMemberDefinition as DeclSpace;
+                       if (c == null)
+                               c = mc.CurrentMemberDefinition.Parent;
 
-               public virtual bool IsClass {
-                       get { return Type.IsClass; }
-               }
-
-               public virtual bool IsValueType {
-                       get { return TypeManager.IsStruct (Type); }
-               }
-
-               public virtual bool IsInterface {
-                       get { return Type.IsInterface; }
-               }
-
-               public virtual bool IsSealed {
-                       get { return Type.IsSealed; }
-               }
-
-               public virtual bool CanInheritFrom ()
-               {
-                       if (Type == TypeManager.enum_type ||
-                           (Type == TypeManager.value_type && RootContext.StdLib) ||
-                           Type == TypeManager.multicast_delegate_type ||
-                           Type == TypeManager.delegate_type ||
-                           Type == TypeManager.array_type)
-                               return false;
-
-                       return true;
+                       return c.CheckAccessLevel (Type);
                }
 
                protected abstract TypeExpr DoResolveAsTypeStep (IMemberContext ec);
@@ -3004,18 +2699,13 @@ namespace Mono.CSharp {
                {
                        return Type.GetHashCode ();
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-               }
        }
 
        /// <summary>
        ///   Fully resolved Expression that already evaluated to a type
        /// </summary>
        public class TypeExpression : TypeExpr {
-               public TypeExpression (Type t, Location l)
+               public TypeExpression (TypeSpec t, Location l)
                {
                        Type = t;
                        eclass = ExprClass.Type;
@@ -3038,48 +2728,16 @@ namespace Mono.CSharp {
        // by the parser to setup the core types.
        //
        public sealed class TypeLookupExpression : TypeExpr {
-               readonly string ns_name;
-               readonly string name;
                
-               public TypeLookupExpression (string ns, string name)
+               public TypeLookupExpression (TypeSpec type)
                {
-                       this.name = name;
-                       this.ns_name = ns;
                        eclass = ExprClass.Type;
+                       this.type = type;
                }
 
-               public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
-               {
-                       //
-                       // It's null only during mscorlib bootstrap when DefineType
-                       // nees to resolve base type of same type
-                       //
-                       // For instance struct Char : IComparable<char>
-                       //
-                       // TODO: it could be removed when Resolve starts to use 
-                       // DeclSpace instead of Type
-                       //
-                       if (type == null) {
-                               Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, false);
-                               FullNamedExpression fne = ns.Lookup (ec.Compiler, name, loc);
-                               if (fne != null)
-                                       type = fne.Type;
-                       }
-
-                       return this;
-               }
-
-               protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
-               {
-                       return this;
-               }
-
-               public override string GetSignatureForError ()
+               protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
                {
-                       if (type == null)
-                               return TypeManager.CSharpName (ns_name + "." + name, null);
-
-                       return base.GetSignatureForError ();
+                       return this;
                }
        }
 
@@ -3123,7 +2781,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   The type which declares this member.
                /// </summary>
-               public abstract Type DeclaringType {
+               public abstract TypeSpec DeclaringType {
                        get;
                }
 
@@ -3144,14 +2802,6 @@ namespace Mono.CSharp {
                        ec.Report.Error (831, loc, "An expression tree may not contain a base access");
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (InstanceExpression != null)
-                               InstanceExpression.MutateHoistedGenericType (storey);
-               }
-
-               // TODO: possible optimalization
-               // Cache resolved constant result in FieldBuilder <-> expression map
                public virtual MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
                                                               SimpleName original)
                {
@@ -3161,20 +2811,20 @@ namespace Mono.CSharp {
                        //
 
                        if (left is TypeExpr) {
-                               left = left.ResolveAsBaseTerminal (ec, false);
+                               left = ((TypeExpr) left).ResolveAsTypeTerminal (ec, false);
                                if (left == null)
                                        return null;
 
                                // TODO: Same problem as in class.cs, TypeTerminal does not
                                // always do all necessary checks
-                               ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (left.Type);
+                               ObsoleteAttribute oa = left.Type.GetAttributeObsolete ();
                                if (oa != null && !ec.IsObsolete) {
                                        AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc, ec.Report);
                                }
 
-                               GenericTypeExpr ct = left as GenericTypeExpr;
-                               if (ct != null && !ct.CheckConstraints (ec))
-                                       return null;
+//                             GenericTypeExpr ct = left as GenericTypeExpr;
+//                             if (ct != null && !ct.CheckConstraints (ec))
+//                                     return null;
                                //
 
                                if (!IsStatic) {
@@ -3226,7 +2876,7 @@ namespace Mono.CSharp {
                                InstanceExpression.Emit (ec);
 
                        if (prepare_for_load)
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                }
 
                public virtual void SetTypeArguments (ResolveContext ec, TypeArguments ta)
@@ -3244,10 +2894,9 @@ namespace Mono.CSharp {
        {
                readonly NamespaceEntry namespace_entry;
                public Expression ExtensionExpression;
-               Argument extension_argument;
 
-               public ExtensionMethodGroupExpr (List<MethodSpec> list, NamespaceEntry n, Type extensionType, Location l)
-                       : base (list, extensionType, l)
+               public ExtensionMethodGroupExpr (List<MethodSpec> list, NamespaceEntry n, TypeSpec extensionType, Location l)
+                       : base (list.Cast<MemberSpec>().ToList (), extensionType, l)
                {
                        this.namespace_entry = n;
                }
@@ -3260,12 +2909,6 @@ namespace Mono.CSharp {
                        get { return namespace_entry == null; }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       extension_argument.Expr.MutateHoistedGenericType (storey);
-                       base.MutateHoistedGenericType (storey);
-               }
-
                public override MethodGroupExpr OverloadResolve (ResolveContext ec, ref Arguments arguments, bool may_fail, Location loc)
                {
                        if (arguments == null)
@@ -3275,9 +2918,7 @@ namespace Mono.CSharp {
                        MethodGroupExpr mg = ResolveOverloadExtensions (ec, ref arguments, namespace_entry, loc);
 
                        // Store resolved argument and restore original arguments
-                       if (mg != null)
-                               ((ExtensionMethodGroupExpr)mg).extension_argument = arguments [0];
-                       else
+                       if (mg == null)
                                arguments.RemoveAt (0); // Clean-up modified arguments for error reporting
 
                        return mg;
@@ -3294,7 +2935,8 @@ namespace Mono.CSharp {
                                return null;
 
                        // Search continues
-                       ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, Name, loc);
+                       int arity = type_arguments == null ? -1 : type_arguments.Count;
+                       ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, Name, arity, loc);
                        if (e == null)
                                return base.OverloadResolve (ec, ref arguments, false, loc);
 
@@ -3317,47 +2959,34 @@ namespace Mono.CSharp {
                }
 
                public IErrorHandler CustomErrorHandler;
-               public MethodSpec [] Methods;
+               public IList<MemberSpec> Methods;
                MethodSpec best_candidate;
                // TODO: make private
                public TypeArguments type_arguments;
                bool identical_type_name;
                bool has_inaccessible_candidates_only;
-               Type delegate_type;
-               Type queried_type;
-               
-               public MethodGroupExpr (MethodSpec [] mi, Type type, Location l)
+               TypeSpec delegate_type;
+               TypeSpec queried_type;
+
+               public MethodGroupExpr (IList<MemberSpec> mi, TypeSpec type, Location l)
                        : this (type, l)
                {
-                       Methods = new MethodSpec[mi.Length];
-                       mi.CopyTo (Methods, 0);
+                       Methods = mi;
                }
 
-               public MethodGroupExpr (MethodSpec[] mi, Type type, Location l, bool inacessibleCandidatesOnly)
-                       : this (mi, type, l)
+               public MethodGroupExpr (MethodSpec m, TypeSpec type, Location l)
+                       : this (type, l)
                {
-                       has_inaccessible_candidates_only = inacessibleCandidatesOnly;
+                       Methods = new List<MemberSpec> (1) { m };
                }
 
-               public MethodGroupExpr (List<MethodSpec> list, Type type, Location l)
-                       : this (type, l)
+               public MethodGroupExpr (IList<MemberSpec> mi, TypeSpec type, Location l, bool inacessibleCandidatesOnly)
+                       : this (mi, type, l)
                {
-                       try {
-                               Methods = list.ToArray ();
-                       } catch {
-                               //foreach (MemberInfo m in list){
-                               //    if (!(m is MethodBase)){
-                               //        Console.WriteLine ("Name " + m.Name);
-                               //        Console.WriteLine ("Found a: " + m.GetType ().FullName);
-                               //    }
-                               //}
-                               throw;
-                       }
-
-
+                       has_inaccessible_candidates_only = inacessibleCandidatesOnly;
                }
-
-               protected MethodGroupExpr (Type type, Location loc)
+               
+               protected MethodGroupExpr (TypeSpec type, Location loc)
                {
                        this.loc = loc;
                        eclass = ExprClass.MethodGroup;
@@ -3365,7 +2994,7 @@ namespace Mono.CSharp {
                        queried_type = type;
                }
 
-               public override Type DeclaringType {
+               public override TypeSpec DeclaringType {
                        get {
                                return queried_type;
                        }
@@ -3377,7 +3006,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public Type DelegateType {
+               public TypeSpec DelegateType {
                        set {
                                delegate_type = value;
                        }
@@ -3392,14 +3021,14 @@ namespace Mono.CSharp {
                public override string GetSignatureForError ()
                {
                        if (best_candidate != null)
-                               return TypeManager.CSharpSignature (best_candidate.MetaInfo);
-                       
-                       return TypeManager.CSharpSignature (Methods [0].MetaInfo);
+                               return best_candidate.GetSignatureForError ();
+
+                       return Methods.First ().GetSignatureForError ();
                }
 
                public override string Name {
                        get {
-                               return Methods [0].Name;
+                               return Methods.First ().Name;
                        }
                }
 
@@ -3440,22 +3069,22 @@ namespace Mono.CSharp {
                //              2    if a->q is better,
                //              0 if neither is better
                //
-               static int BetterExpressionConversion (ResolveContext ec, Argument a, Type p, Type q)
+               static int BetterExpressionConversion (ResolveContext ec, Argument a, TypeSpec p, TypeSpec q)
                {
-                       Type argument_type = TypeManager.TypeToCoreType (a.Type);
+                       TypeSpec argument_type = a.Type;
                        if (argument_type == InternalType.AnonymousMethod && RootContext.Version > LanguageVersion.ISO_2) {
                                //
                                // Uwrap delegate from Expression<T>
                                //
-                               if (TypeManager.DropGenericTypeArguments (p) == TypeManager.expression_type) {
+                               if (p.GetDefinition () == TypeManager.expression_type) {
                                        p = TypeManager.GetTypeArguments (p) [0];
                                }
-                               if (TypeManager.DropGenericTypeArguments (q) == TypeManager.expression_type) {
+                               if (q.GetDefinition () == TypeManager.expression_type) {
                                        q = TypeManager.GetTypeArguments (q) [0];
                                }
                                
-                               p = Delegate.GetInvokeMethod (ec.Compiler, null, p).ReturnType;
-                               q = Delegate.GetInvokeMethod (ec.Compiler, null, q).ReturnType;
+                               p = Delegate.GetInvokeMethod (ec.Compiler, p).ReturnType;
+                               q = Delegate.GetInvokeMethod (ec.Compiler, q).ReturnType;
                                if (p == TypeManager.void_type && q != TypeManager.void_type)
                                        return 2;
                                if (q == TypeManager.void_type && p != TypeManager.void_type)
@@ -3474,7 +3103,7 @@ namespace Mono.CSharp {
                //
                // 7.4.3.4  Better conversion from type
                //
-               public static int BetterTypeConversion (ResolveContext ec, Type p, Type q)
+               public static int BetterTypeConversion (ResolveContext ec, TypeSpec p, TypeSpec q)
                {
                        if (p == null || q == null)
                                throw new InternalErrorException ("BetterTypeConversion got a null conversion");
@@ -3559,8 +3188,8 @@ namespace Mono.CSharp {
                                if (a.IsDefaultArgument && candidate_params == best_params)
                                        return false;
 
-                               Type ct = candidate_pd.Types [c_idx];
-                               Type bt = best_pd.Types [b_idx];
+                               TypeSpec ct = candidate_pd.Types [c_idx];
+                               TypeSpec bt = best_pd.Types [b_idx];
 
                                if (candidate_params && candidate_pd.FixedParameters [c_idx].ModFlags == Parameter.Modifier.PARAMS) 
                                {
@@ -3609,10 +3238,10 @@ namespace Mono.CSharp {
                        //
                        // The two methods have equal parameter types.  Now apply tie-breaking rules
                        //
-                       if (best.IsGenericMethod) {
-                               if (!candidate.IsGenericMethod)
+                       if (best.IsGeneric) {
+                               if (!candidate.IsGeneric)
                                        return true;
-                       } else if (candidate.IsGenericMethod) {
+                       } else if (candidate.IsGeneric) {
                                return false;
                        }
 
@@ -3637,24 +3266,20 @@ namespace Mono.CSharp {
                                return candidate_param_count > best_param_count && best_pd.HasParams;
 
                        //
-                       // now, both methods have the same number of parameters, and the parameters have the same types
-                       // Pick the "more specific" signature
+                       // Both methods have the same number of parameters, and the parameters have equal types
+                       // Pick the "more specific" signature using rules over original (non-inflated) types
                        //
-
-                       MethodBase orig_candidate = TypeManager.DropGenericMethodArguments (candidate);
-                       MethodBase orig_best = TypeManager.DropGenericMethodArguments (best);
-
-                       AParametersCollection orig_candidate_pd = TypeManager.GetParameterData (orig_candidate);
-                       AParametersCollection orig_best_pd = TypeManager.GetParameterData (orig_best);
+                       var candidate_def_pd = ((IParametersMember) candidate.MemberDefinition).Parameters;
+                       var best_def_pd = ((IParametersMember) best.MemberDefinition).Parameters;
 
                        bool specific_at_least_once = false;
                        for (int j = 0; j < candidate_param_count; ++j) 
                        {
-                               Type ct = orig_candidate_pd.Types [j];
-                               Type bt = orig_best_pd.Types [j];
-                               if (ct.Equals (bt))
+                               var ct = candidate_def_pd.Types [j];
+                               var bt = best_def_pd.Types [j];
+                               if (ct == bt)
                                        continue;
-                               Type specific = MoreSpecific (ct, bt);
+                               TypeSpec specific = MoreSpecific (ct, bt);
                                if (specific == bt)
                                        return false;
                                if (specific == ct)
@@ -3700,8 +3325,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       IMethodData md = TypeManager.GetMethod (best_candidate.MetaInfo);
-                       if (md != null && md.IsExcluded ())
+                       if (best_candidate.IsConditionallyExcluded (loc))
                                ec.Report.Error (765, loc,
                                        "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
                        
@@ -3743,18 +3367,18 @@ namespace Mono.CSharp {
                        if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ec, ambiguous))
                                return;
 
-                       ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+                       ec.Report.SymbolRelatedToPreviousError (best_candidate);
                        ec.Report.Error (121, loc, "The call is ambiguous between the following methods or properties: `{0}' and `{1}'",
-                               TypeManager.CSharpSignature (ambiguous), TypeManager.CSharpSignature (best_candidate.MetaInfo));
+                               best_candidate.GetSignatureForError (), ambiguous.GetSignatureForError ());
                }
 
                protected virtual void Error_InvalidArguments (ResolveContext ec, Location loc, int idx, MethodSpec method,
-                                                                                                       Argument a, AParametersCollection expected_par, Type paramType)
+                                                                                                       Argument a, AParametersCollection expected_par, TypeSpec paramType)
                {
                        ExtensionMethodGroupExpr emg = this as ExtensionMethodGroupExpr;
 
                        if (a is CollectionElementInitializer.ElementInitializerArgument) {
-                               ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+                               ec.Report.SymbolRelatedToPreviousError (method);
                                if ((expected_par.FixedParameters [idx].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
                                        ec.Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
                                                TypeManager.CSharpSignature (method));
@@ -3766,7 +3390,7 @@ namespace Mono.CSharp {
                                ec.Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
                                        TypeManager.CSharpName (method.DeclaringType));
                        } else {
-                               ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+                               ec.Report.SymbolRelatedToPreviousError (method);
                                if (emg != null) {
                                        ec.Report.Error (1928, loc,
                                                "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments",
@@ -3809,7 +3433,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
                {
                        ec.Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
                                Name, TypeManager.CSharpName (target));
@@ -3824,13 +3448,27 @@ namespace Mono.CSharp {
                protected virtual int GetApplicableParametersCount (MethodSpec method, AParametersCollection parameters)
                {
                        return parameters.Count;
-               }               
+               }
 
-               public static bool IsAncestralType (Type first_type, Type second_type)
+               protected virtual IList<MemberSpec> GetBaseTypeMethods (ResolveContext rc, TypeSpec type)
                {
-                       return first_type != second_type &&
-                               (TypeManager.IsSubclassOf (second_type, first_type) ||
-                               TypeManager.ImplementsInterface (second_type, first_type));
+                       return TypeManager.MemberLookup (rc.CurrentType, null, type,
+                               MemberKind.Method, BindingRestriction.AccessibleOnly | BindingRestriction.NoOverrides,
+                               Name, 0, null); // TODO MemberCache: Arity !
+               }
+
+               bool GetBaseTypeMethods (ResolveContext rc)
+               {
+                       var base_type = Methods.First ().DeclaringType.BaseType;
+                       if (base_type == null)
+                               return false;
+
+                       var methods = GetBaseTypeMethods (rc, base_type);
+                       if (methods == null)
+                               return false;
+
+                       Methods = methods;
+                       return true;
                }
 
                ///
@@ -3942,13 +3580,13 @@ namespace Mono.CSharp {
                        //
                        // 1. Handle generic method using type arguments when specified or type inference
                        //
-                       if (candidate.IsGenericMethod) {
+                       if (candidate.IsGeneric) {
                                if (type_arguments != null) {
-                                       Type [] g_args = candidate.GetGenericArguments ();
-                                       if (g_args.Length != type_arguments.Count)
-                                               return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args.Length);
+                                       var g_args_count = candidate.Arity;
+                                       if (g_args_count != type_arguments.Count)
+                                               return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args_count);
 
-                                       method = candidate.Inflate (type_arguments.Arguments);
+                                       method = candidate.MakeGenericMethod (type_arguments.Arguments);
                                        candidate = method;
                                        pd = candidate.Parameters;
                                } else {
@@ -3956,10 +3594,6 @@ namespace Mono.CSharp {
                                        if (score != 0)
                                                return score - 20000;
 
-                                       if (TypeManager.IsGenericMethodDefinition (candidate.MetaInfo))
-                                               throw new InternalErrorException ("A generic method `{0}' definition took part in overload resolution",
-                                                       TypeManager.CSharpSignature (candidate.MetaInfo));
-
                                        pd = candidate.Parameters;
                                }
                        } else {
@@ -3972,7 +3606,7 @@ namespace Mono.CSharp {
                        //
                        method = candidate;
                        Parameter.Modifier p_mod = 0;
-                       Type pt = null;
+                       TypeSpec pt = null;
                        for (int i = 0; i < arg_count; i++) {
                                Argument a = arguments [i];
                                if (a == null) {
@@ -4019,7 +3653,7 @@ namespace Mono.CSharp {
                        return 0;
                }
 
-               int IsArgumentCompatible (ResolveContext ec, Parameter.Modifier arg_mod, Argument argument, Parameter.Modifier param_mod, Type parameter)
+               int IsArgumentCompatible (ResolveContext ec, Parameter.Modifier arg_mod, Argument argument, Parameter.Modifier param_mod, TypeSpec parameter)
                {
                        //
                        // Types have to be identical when ref or out modifer is used 
@@ -4028,19 +3662,19 @@ namespace Mono.CSharp {
                                if (TypeManager.HasElementType (parameter))
                                        parameter = TypeManager.GetElementType (parameter);
 
-                               Type a_type = argument.Type;
+                               TypeSpec a_type = argument.Type;
                                if (TypeManager.HasElementType (a_type))
                                        a_type = TypeManager.GetElementType (a_type);
 
                                if (a_type != parameter) {
-                                       if (TypeManager.IsDynamicType (a_type))
+                                       if (a_type == InternalType.Dynamic)
                                                return 0;
 
                                        return 2;
                                }
                        } else {
                                if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
-                                       if (TypeManager.IsDynamicType (argument.Type))
+                                       if (argument.Type == InternalType.Dynamic)
                                                return 0;
 
                                        return 2;
@@ -4053,31 +3687,6 @@ namespace Mono.CSharp {
                        return 0;
                }
 
-               public static bool IsOverride (MethodBase cand_method, MethodBase base_method)
-               {
-                       if (!IsAncestralType (base_method.DeclaringType, cand_method.DeclaringType))
-                               return false;
-
-                       AParametersCollection cand_pd = TypeManager.GetParameterData (cand_method);
-                       AParametersCollection base_pd = TypeManager.GetParameterData (base_method);
-               
-                       if (cand_pd.Count != base_pd.Count)
-                               return false;
-
-                       for (int j = 0; j < cand_pd.Count; ++j) 
-                       {
-                               Parameter.Modifier cm = cand_pd.FixedParameters [j].ModFlags;
-                               Parameter.Modifier bm = base_pd.FixedParameters [j].ModFlags;
-                               Type ct = cand_pd.Types [j];
-                               Type bt = base_pd.Types [j];
-
-                               if (cm != bm || ct != bt)
-                                       return false;
-                       }
-
-                       return true;
-               }
-
                public static MethodGroupExpr MakeUnionSet (MethodGroupExpr mg1, MethodGroupExpr mg2, Location loc)
                {
                        if (mg1 == null) {
@@ -4089,46 +3698,42 @@ namespace Mono.CSharp {
                        if (mg2 == null)
                                return mg1;
 
-                       var all = new List<MethodSpec> (mg1.Methods);
-                       foreach (var m in mg2.Methods){
-                               if (!TypeManager.ArrayContainsMethod (mg1.Methods.Select (l => l.MetaInfo).ToArray (), m.MetaInfo, false))
+                       var all = new List<MemberSpec> (mg1.Methods);
+                       foreach (MethodSpec m in mg2.Methods){
+                               if (!TypeManager.ArrayContainsMethod (all, m, false))
                                        all.Add (m);
                        }
 
                        return new MethodGroupExpr (all, null, loc);
                }               
 
-               static Type MoreSpecific (Type p, Type q)
+               static TypeSpec MoreSpecific (TypeSpec p, TypeSpec q)
                {
                        if (TypeManager.IsGenericParameter (p) && !TypeManager.IsGenericParameter (q))
                                return q;
                        if (!TypeManager.IsGenericParameter (p) && TypeManager.IsGenericParameter (q))
                                return p;
 
-                       if (TypeManager.HasElementType (p)) 
-                       {
-                               Type pe = TypeManager.GetElementType (p);
-                               Type qe = TypeManager.GetElementType (q);
-                               Type specific = MoreSpecific (pe, qe);
-                               if (specific == pe)
+                       var ac_p = p as ArrayContainer;
+                       if (ac_p != null) {
+                               var ac_q = ((ArrayContainer) q);
+                               TypeSpec specific = MoreSpecific (ac_p.Element, (ac_q.Element));
+                               if (specific == ac_p.Element)
                                        return p;
-                               if (specific == qe)
+                               if (specific == ac_q.Element)
                                        return q;
-                       } 
-                       else if (TypeManager.IsGenericType (p)) 
-                       {
-                               Type[] pargs = TypeManager.GetTypeArguments (p);
-                               Type[] qargs = TypeManager.GetTypeArguments (q);
+                       } else if (TypeManager.IsGenericType (p)) {
+                               var pargs = TypeManager.GetTypeArguments (p);
+                               var qargs = TypeManager.GetTypeArguments (q);
 
                                bool p_specific_at_least_once = false;
                                bool q_specific_at_least_once = false;
 
-                               for (int i = 0; i < pargs.Length; i++) 
-                               {
-                                       Type specific = MoreSpecific (TypeManager.TypeToCoreType (pargs [i]), TypeManager.TypeToCoreType (qargs [i]));
-                                       if (specific == pargs [i])
+                               for (int i = 0; i < pargs.Length; i++) {
+                                       TypeSpec specific = MoreSpecific (pargs[i], qargs[i]);
+                                       if (specific == pargs[i])
                                                p_specific_at_least_once = true;
-                                       if (specific == qargs [i])
+                                       if (specific == qargs[i])
                                                q_specific_at_least_once = true;
                                }
 
@@ -4141,17 +3746,6 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       base.MutateHoistedGenericType (storey);
-
-                       if (best_candidate.IsConstructor) {
-                               storey.MutateConstructor (best_candidate);
-                       } else {
-                               storey.MutateGenericMethod (best_candidate);                            
-                       }
-               }
-
                /// <summary>
                ///   Find the Applicable Function Members (7.4.2.1)
                ///
@@ -4171,126 +3765,81 @@ namespace Mono.CSharp {
                public virtual MethodGroupExpr OverloadResolve (ResolveContext ec, ref Arguments Arguments,
                        bool may_fail, Location loc)
                {
-                       bool method_params = false;
-                       Type applicable_type = null;
                        var candidates = new List<MethodSpec> (2);
-                       List<MethodSpec> candidate_overrides = null;
+                       List<MethodSpec> params_candidates = null;
 
-                       //
-                       // Used to keep a map between the candidate
-                       // and whether it is being considered in its
-                       // normal or expanded form
-                       //
-                       // false is normal form, true is expanded form
-                       //
-                       Dictionary<MethodSpec, MethodSpec> candidate_to_form = null;
+                       int arg_count = Arguments != null ? Arguments.Count : 0;
                        Dictionary<MethodSpec, Arguments> candidates_expanded = null;
                        Arguments candidate_args = Arguments;
 
-                       int arg_count = Arguments != null ? Arguments.Count : 0;
-
                        if (RootContext.Version == LanguageVersion.ISO_1 && Name == "Invoke" && TypeManager.IsDelegateType (DeclaringType)) {
                                if (!may_fail)
                                        ec.Report.Error (1533, loc, "Invoke cannot be called directly on a delegate");
                                return null;
                        }
 
-                       int nmethods = Methods.Length;
-
-                       if (!IsBase) {
-                               //
-                               // Methods marked 'override' don't take part in 'applicable_type'
-                               // computation, nor in the actual overload resolution.
-                               // However, they still need to be emitted instead of a base virtual method.
-                               // So, we salt them away into the 'candidate_overrides' array.
-                               //
-                               // In case of reflected methods, we replace each overriding method with
-                               // its corresponding base virtual method.  This is to improve compatibility
-                               // with non-C# libraries which change the visibility of overrides (#75636)
-                               //
-                               int j = 0;
-                               MethodBase mb = null;
-                               for (int i = 0; i < Methods.Length; ++i) {
-                                       var m = Methods [i];
-                                       mb = m.MetaInfo;
-                                       if (TypeManager.IsOverride (m)) {
-                                               if (candidate_overrides == null)
-                                                       candidate_overrides = new List<MethodSpec> ();
-                                               candidate_overrides.Add (m);
-                                               mb = TypeManager.TryGetBaseDefinition (mb);
-                                               if (mb != null && Array.Exists (Methods, l => l.MetaInfo == mb))
-                                                       continue;
-                                       }
-                                       if (mb != null)
-                                               Methods [j++] = Import.CreateMethod (mb);
-                               }
-                               nmethods = j;
-                       }
-
                        //
                        // Enable message recording, it's used mainly by lambda expressions
                        //
-                       SessionReportPrinter msg_recorder = new SessionReportPrinter ();
-                       ReportPrinter prev_recorder = ec.Report.SetPrinter (msg_recorder);
-
-                       //
-                       // First we construct the set of applicable methods
-                       //
-                       bool is_sorted = true;
-                       int best_candidate_rate = int.MaxValue;
-                       for (int i = 0; i < nmethods; i++) {
-                               Type decl_type = Methods [i].DeclaringType;
+                       var msg_recorder = new SessionReportPrinter ();
+                       var prev_recorder = ec.Report.SetPrinter (msg_recorder);
 
+                       do {
                                //
-                               // If we have already found an applicable method
-                               // we eliminate all base types (Section 14.5.5.1)
+                               // Methods in a base class are not candidates if any method in a derived
+                               // class is applicable
                                //
-                               if (applicable_type != null && IsAncestralType (decl_type, applicable_type))
-                                       continue;
+                               int best_candidate_rate = int.MaxValue;
+
+                               foreach (var member in Methods) {
+                                       var m = member as MethodSpec;
+                                       if (m == null) {
+                                               // TODO: It's wrong when non-member is before applicable method
+                                               // TODO: Should report only when at least 1 from the batch is applicable
+                                               if (candidates.Count != 0) {
+                                                       ec.Report.SymbolRelatedToPreviousError (candidates [0]);
+                                                       ec.Report.SymbolRelatedToPreviousError (member);
+                                                       ec.Report.Warning (467, 2, loc, "Ambiguity between method `{0}' and non-method `{1}'. Using method `{0}'",
+                                                               candidates[0].GetSignatureForError (), member.GetSignatureForError ());
+                                               }
+                                               continue;
+                                       }
 
-                               //
-                               // Check if candidate is applicable (section 14.4.2.1)
-                               //
-                               bool params_expanded_form = false;
-                               int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref Methods [i], ref params_expanded_form);
+                                       //
+                                       // Check if candidate is applicable (section 14.4.2.1)
+                                       //
+                                       bool params_expanded_form = false;
+                                       int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref m, ref params_expanded_form);
 
-                               if (candidate_rate < best_candidate_rate) {
-                                       best_candidate_rate = candidate_rate;
-                                       best_candidate = Methods [i];
-                               }
-                               
-                               if (params_expanded_form) {
-                                       if (candidate_to_form == null)
-                                               candidate_to_form = new Dictionary<MethodSpec, MethodSpec> (4, ReferenceEquality<MethodSpec>.Default);
-                                       var candidate = Methods [i];
-                                       candidate_to_form [candidate] = candidate;
-                               }
-                               
-                               if (candidate_args != Arguments) {
-                                       if (candidates_expanded == null)
-                                               candidates_expanded = new Dictionary<MethodSpec, Arguments> (4, ReferenceEquality<MethodSpec>.Default);
+                                       if (candidate_rate < best_candidate_rate) {
+                                               best_candidate_rate = candidate_rate;
+                                               best_candidate = m;
+                                       }
 
-                                       candidates_expanded.Add (Methods [i], candidate_args);
-                                       candidate_args = Arguments;
-                               }
+                                       if (params_expanded_form) {
+                                               if (params_candidates == null)
+                                                       params_candidates = new List<MethodSpec> (2);
+                                               params_candidates.Add (m);
+                                       }
 
-                               if (candidate_rate != 0 || has_inaccessible_candidates_only) {
-                                       if (msg_recorder != null)
-                                               msg_recorder.EndSession ();
-                                       continue;
-                               }
+                                       if (candidate_args != Arguments) {
+                                               if (candidates_expanded == null)
+                                                       candidates_expanded = new Dictionary<MethodSpec, Arguments> (2);
+
+                                               candidates_expanded.Add (m, candidate_args);
+                                               candidate_args = Arguments;
+                                       }
 
-                               msg_recorder = null;
-                               candidates.Add (Methods [i]);
+                                       if (candidate_rate != 0 || has_inaccessible_candidates_only) {
+                                               if (msg_recorder != null)
+                                                       msg_recorder.EndSession ();
+                                               continue;
+                                       }
 
-                               if (applicable_type == null)
-                                       applicable_type = decl_type;
-                               else if (applicable_type != decl_type) {
-                                       is_sorted = false;
-                                       if (IsAncestralType (applicable_type, decl_type))
-                                               applicable_type = decl_type;
+                                       msg_recorder = null;
+                                       candidates.Add (m);
                                }
-                       }
+                       } while (candidates.Count == 0 && GetBaseTypeMethods (ec));
 
                        ec.Report.SetPrinter (prev_recorder);
                        if (msg_recorder != null && !msg_recorder.IsEmpty) {
@@ -4299,16 +3848,17 @@ namespace Mono.CSharp {
 
                                return null;
                        }
-                       
-                       int candidate_top = candidates.Count;
 
-                       if (applicable_type == null) {
+                       int candidate_top = candidates.Count;
+                       if (candidate_top == 0) {
                                //
                                // When we found a top level method which does not match and it's 
                                // not an extension method. We start extension methods lookup from here
                                //
                                if (InstanceExpression != null) {
-                                       ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (type, Name, loc);
+                                       var first = Methods.First ();
+                                       var arity = type_arguments == null ? -1 : type_arguments.Count;
+                                       ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (type, first.Name, arity, loc);
                                        if (ex_method_lookup != null) {
                                                ex_method_lookup.ExtensionExpression = InstanceExpression;
                                                ex_method_lookup.SetTypeArguments (ec, type_arguments);
@@ -4327,18 +3877,19 @@ namespace Mono.CSharp {
                                        if (CustomErrorHandler != null && !has_inaccessible_candidates_only && CustomErrorHandler.NoExactMatch (ec, best_candidate))
                                                return null;
 
-                                       if (NoExactMatch (ec, ref Arguments, candidate_to_form))
+                                       bool params_expanded = params_candidates != null && params_candidates.Contains (best_candidate);
+                                       if (NoExactMatch (ec, ref Arguments, params_expanded))
                                                return null;
                                }
 
                                //
                                // We failed to find any method with correct argument count
                                //
-                               if (Name == ConstructorInfo.ConstructorName) {
+                               if (Methods.First ().Kind == MemberKind.Constructor) {
                                        ec.Report.SymbolRelatedToPreviousError (queried_type);
                                        ec.Report.Error (1729, loc,
                                                "The type `{0}' does not contain a constructor that takes `{1}' arguments",
-                                               TypeManager.CSharpName (queried_type), arg_count);
+                                               TypeManager.CSharpName (queried_type), arg_count.ToString ());
                                } else {
                                        Error_ArgumentCountWrong (ec, arg_count);
                                }
@@ -4351,80 +3902,24 @@ namespace Mono.CSharp {
                                return this;
                        }
 
-                       if (!is_sorted) {
-                               //
-                               // At this point, applicable_type is _one_ of the most derived types
-                               // in the set of types containing the methods in this MethodGroup.
-                               // Filter the candidates so that they only contain methods from the
-                               // most derived types.
-                               //
-
-                               int finalized = 0; // Number of finalized candidates
-
-                               do {
-                                       // Invariant: applicable_type is a most derived type
-                                       
-                                       // We'll try to complete Section 14.5.5.1 for 'applicable_type' by 
-                                       // eliminating all it's base types.  At the same time, we'll also move
-                                       // every unrelated type to the end of the array, and pick the next
-                                       // 'applicable_type'.
-
-                                       Type next_applicable_type = null;
-                                       int j = finalized; // where to put the next finalized candidate
-                                       int k = finalized; // where to put the next undiscarded candidate
-                                       for (int i = finalized; i < candidate_top; ++i) {
-                                               var candidate = candidates [i];
-                                               Type decl_type = candidate.DeclaringType;
-
-                                               if (decl_type == applicable_type) {
-                                                       candidates [k++] = candidates [j];
-                                                       candidates [j++] = candidates [i];
-                                                       continue;
-                                               }
-
-                                               if (IsAncestralType (decl_type, applicable_type))
-                                                       continue;
-
-                                               if (next_applicable_type != null &&
-                                                       IsAncestralType (decl_type, next_applicable_type))
-                                                       continue;
-
-                                               candidates [k++] = candidates [i];
-
-                                               if (next_applicable_type == null ||
-                                                       IsAncestralType (next_applicable_type, decl_type))
-                                                       next_applicable_type = decl_type;
-                                       }
-
-                                       applicable_type = next_applicable_type;
-                                       finalized = j;
-                                       candidate_top = k;
-                               } while (applicable_type != null);
-                       }
-
                        //
                        // Now we actually find the best method
                        //
-
                        best_candidate = candidates [0];
-                       method_params = candidate_to_form != null && candidate_to_form.ContainsKey (best_candidate);
-
-                       //
-                       // TODO: Broken inverse order of candidates logic does not work with optional
-                       // parameters used for method overrides and I am not going to fix it for SRE
-                       //
-                       if (candidates_expanded != null && candidates_expanded.ContainsKey (best_candidate)) {
-                               candidate_args = candidates_expanded [best_candidate];
-                               arg_count = candidate_args.Count;
-                       }
+                       bool method_params = params_candidates != null && params_candidates.Contains (best_candidate);
 
                        for (int ix = 1; ix < candidate_top; ix++) {
                                var candidate = candidates [ix];
 
-                               if (candidate.MetaInfo == best_candidate.MetaInfo)
+                               if (candidate == best_candidate)
                                        continue;
 
-                               bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (candidate);
+                               bool cand_params = params_candidates != null && params_candidates.Contains (candidate);
+
+                               if (candidates_expanded != null && candidates_expanded.ContainsKey (candidate)) {
+                                       candidate_args = candidates_expanded[candidate];
+                                       arg_count = candidate_args.Count;
+                               }
 
                                if (BetterFunction (ec, candidate_args, arg_count, 
                                        candidate, cand_params,
@@ -4432,7 +3927,18 @@ namespace Mono.CSharp {
                                        best_candidate = candidate;
                                        method_params = cand_params;
                                }
+
+                               if (candidate_args != Arguments) {
+                                       candidate_args = Arguments;
+                                       arg_count = candidate_args != null ? candidate_args.Count : 0;
+                               }
                        }
+
+                       if (candidates_expanded != null && candidates_expanded.ContainsKey (best_candidate)) {
+                               candidate_args = candidates_expanded[best_candidate];
+                               arg_count = candidate_args.Count;
+                       }
+
                        //
                        // Now check that there are no ambiguities i.e the selected method
                        // should be better than all the others
@@ -4441,16 +3947,16 @@ namespace Mono.CSharp {
                        for (int ix = 1; ix < candidate_top; ix++) {
                                var candidate = candidates [ix];
 
-                               if (candidate.MetaInfo == best_candidate.MetaInfo)
+                               if (candidate == best_candidate)
                                        continue;
 
-                               bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (candidate);
+                               bool cand_params = params_candidates != null && params_candidates.Contains (candidate);
                                if (!BetterFunction (ec, candidate_args, arg_count,
                                        best_candidate, method_params,
                                        candidate, cand_params)) 
                                {
                                        if (!may_fail)
-                                               ec.Report.SymbolRelatedToPreviousError (candidate.MetaInfo);
+                                               ec.Report.SymbolRelatedToPreviousError (candidate);
                                        ambiguous = candidate;
                                }
                        }
@@ -4460,44 +3966,6 @@ namespace Mono.CSharp {
                                return this;
                        }
 
-                       //
-                       // If the method is a virtual function, pick an override closer to the LHS type.
-                       //
-                       if (!IsBase && best_candidate.IsVirtual) {
-                               if (TypeManager.IsOverride (best_candidate))
-                                       throw new InternalErrorException (
-                                               "Should not happen.  An 'override' method took part in overload resolution: " + best_candidate);
-
-                               if (candidate_overrides != null) {
-                                       Type[] gen_args = null;
-                                       bool gen_override = false;
-                                       if (best_candidate.IsGenericMethod)
-                                               gen_args = TypeManager.GetGenericArguments (best_candidate.MetaInfo);
-
-                                       foreach (var candidate in candidate_overrides) {
-                                               if (candidate.IsGenericMethod) {
-                                                       if (gen_args == null)
-                                                               continue;
-
-                                                       if (gen_args.Length != TypeManager.GetGenericArguments (candidate.MetaInfo).Length)
-                                                               continue;
-                                               } else {
-                                                       if (gen_args != null)
-                                                               continue;
-                                               }
-                                               
-                                               if (IsOverride (candidate.MetaInfo, best_candidate.MetaInfo)) {
-                                                       gen_override = true;
-                                                       best_candidate = candidate;
-                                               }
-                                       }
-
-                                       if (gen_override && gen_args != null) {
-                                               best_candidate = best_candidate.Inflate (gen_args);
-                                       }
-                               }
-                       }
-
                        //
                        // And now check if the arguments are all
                        // compatible, perform conversions if
@@ -4511,54 +3979,43 @@ namespace Mono.CSharp {
                        if (best_candidate == null)
                                return null;
 
-                       MethodBase the_method = TypeManager.DropGenericMethodArguments (best_candidate);
-                       if (TypeManager.IsGenericMethodDefinition (the_method) &&
-                           !ConstraintChecker.CheckConstraints (ec, the_method, best_candidate.MetaInfo, loc))
-                               return null;
+                       if (best_candidate.IsGeneric) {
+                               ConstraintChecker.CheckAll (best_candidate.GetGenericMethodDefinition (), best_candidate.TypeArguments,
+                                       best_candidate.Constraints, loc, ec.Report);
+                       }
 
                        //
                        // Check ObsoleteAttribute on the best method
                        //
-                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (the_method);
+                       ObsoleteAttribute oa = best_candidate.GetAttributeObsolete ();
                        if (oa != null && !ec.IsObsolete)
                                AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
 
-                       IMethodData data = TypeManager.GetMethod (the_method);
-                       if (data != null)
-                               data.SetIsUsed ();
+                       best_candidate.MemberDefinition.SetIsUsed ();
 
                        Arguments = candidate_args;
                        return this;
                }
 
-               bool NoExactMatch (ResolveContext ec, ref Arguments Arguments, IDictionary<MethodSpec, MethodSpec> candidate_to_form)
+               bool NoExactMatch (ResolveContext ec, ref Arguments Arguments, bool params_expanded)
                {
                        AParametersCollection pd = best_candidate.Parameters;
                        int arg_count = Arguments == null ? 0 : Arguments.Count;
 
                        if (arg_count == pd.Count || pd.HasParams) {
-                               if (TypeManager.IsGenericMethodDefinition (best_candidate.MetaInfo)) {
+                               if (best_candidate.IsGeneric) {
                                        if (type_arguments == null) {
                                                ec.Report.Error (411, loc,
-                                                       "The type arguments for method `{0}' cannot be inferred from " +
-                                                       "the usage. Try specifying the type arguments explicitly",
-                                                       TypeManager.CSharpSignature (best_candidate.MetaInfo));
+                                                       "The type arguments for method `{0}' cannot be inferred from the usage. Try specifying the type arguments explicitly",
+                                                       best_candidate.GetGenericMethodDefinition().GetSignatureForError ());
                                                return true;
                                        }
+                               }
 
-                                       Type[] g_args = TypeManager.GetGenericArguments (best_candidate.MetaInfo);
-                                       if (type_arguments.Count != g_args.Length) {
-                                               ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
-                                               ec.Report.Error (305, loc, "Using the generic method `{0}' requires `{1}' type argument(s)",
-                                                       TypeManager.CSharpSignature (best_candidate.MetaInfo),
-                                                       g_args.Length.ToString ());
-                                               return true;
-                                       }
-                               } else {
-                                       if (type_arguments != null && !best_candidate.IsGenericMethod) {
-                                               Error_TypeArgumentsCannotBeUsed (ec.Report, loc);
-                                               return true;
-                                       }
+                               var ta = type_arguments == null ? 0 : type_arguments.Count;
+                               if (ta != best_candidate.Arity) {
+                                       Error_TypeArgumentsCannotBeUsed (ec.Report, loc, best_candidate, type_arguments.Count);
+                                       return true;
                                }
 
                                if (has_inaccessible_candidates_only) {
@@ -4568,15 +4025,14 @@ namespace Mono.CSharp {
                                                // base class (CS1540).  If the qualifier_type is a base of the
                                                // ec.CurrentType and the lookup succeeds with the latter one,
                                                // then we are in this situation.
-                                               Error_CannotAccessProtected (ec, loc, best_candidate.MetaInfo, queried_type, ec.CurrentType);
+                                               Error_CannotAccessProtected (ec, loc, best_candidate, queried_type, ec.CurrentType);
                                        } else {
-                                               ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+                                               ec.Report.SymbolRelatedToPreviousError (best_candidate);
                                                ErrorIsInaccesible (loc, GetSignatureForError (), ec.Report);
                                        }
                                }
 
-                               bool cand_params = candidate_to_form != null && candidate_to_form.ContainsKey (best_candidate);
-                               if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, false, loc))
+                               if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, params_expanded, false, loc))
                                        return true;
 
                                if (has_inaccessible_candidates_only)
@@ -4601,7 +4057,7 @@ namespace Mono.CSharp {
 
                        int errors = ec.Report.Errors;
                        Parameter.Modifier p_mod = 0;
-                       Type pt = null;
+                       TypeSpec pt = null;
                        int a_idx = 0, a_pos = 0;
                        Argument a = null;
                        ArrayInitializer params_initializers = null;
@@ -4644,16 +4100,16 @@ namespace Mono.CSharp {
                                                                        "The delegate `{0}' does not contain a parameter named `{1}'",
                                                                        TypeManager.CSharpName (DeclaringType), na.Name);
                                                        } else {
-                                                               ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+                                                               ec.Report.SymbolRelatedToPreviousError (best_candidate);
                                                                ec.Report.Error (1739, na.Location,
                                                                        "The best overloaded method match for `{0}' does not contain a parameter named `{1}'",
-                                                                       TypeManager.CSharpSignature (method.MetaInfo), na.Name);
+                                                                       TypeManager.CSharpSignature (method), na.Name);
                                                        }
                                                } else if (arguments[name_index] != a) {
                                                        if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType))
                                                                ec.Report.SymbolRelatedToPreviousError (DeclaringType);
                                                        else
-                                                               ec.Report.SymbolRelatedToPreviousError (best_candidate.MetaInfo);
+                                                               ec.Report.SymbolRelatedToPreviousError (best_candidate);
 
                                                        ec.Report.Error (1744, na.Location,
                                                                "Named argument `{0}' cannot be used for a parameter which has positional argument specified",
@@ -4662,7 +4118,7 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               if (TypeManager.IsDynamicType (a.Expr.Type))
+                               if (a.Expr.Type == InternalType.Dynamic)
                                        continue;
 
                                if (delegate_type != null && !Delegate.IsTypeCovariant (a.Expr, pt))
@@ -4758,7 +4214,7 @@ namespace Mono.CSharp {
                        get { return true; }
                }
 
-               public override Type DeclaringType {
+               public override TypeSpec DeclaringType {
                        get { return constant.DeclaringType; }
                }
 
@@ -4772,16 +4228,16 @@ namespace Mono.CSharp {
                        constant.MemberDefinition.SetIsUsed ();
 
                        if (!rc.IsObsolete) {
-                               var oa = constant.GetObsoleteAttribute ();
+                               var oa = constant.GetAttributeObsolete ();
                                if (oa != null)
-                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (constant.MetaInfo), loc, rc.Report);
+                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (constant), loc, rc.Report);
                        }
 
                        // Constants are resolved on-demand
                        var c = constant.Value.Resolve (rc) as Constant;
 
                        // Creates reference expression to the constant value
-                       return Constant.CreateConstant (rc, c.Type, c.GetValue (), loc);
+                       return Constant.CreateConstant (rc, constant.MemberType, c.GetValue (), loc);
                }
 
                public override void Emit (EmitContext ec)
@@ -4791,7 +4247,7 @@ namespace Mono.CSharp {
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.GetFullNameSignature (constant.MetaInfo);
+                       return TypeManager.GetFullNameSignature (constant);
                }
        }
 
@@ -4800,7 +4256,6 @@ namespace Mono.CSharp {
        /// </summary>
        public class FieldExpr : MemberExpr, IDynamicAssign, IMemoryLocation, IVariableReference {
                protected FieldSpec spec;
-               readonly Type constructed_generic_type;
                VariableInfo variable_info;
                
                LocalTemporary temp;
@@ -4816,7 +4271,7 @@ namespace Mono.CSharp {
                        this.spec = spec;
                        this.loc = loc;
 
-                       type = TypeManager.TypeToCoreType (spec.FieldType);
+                       type = spec.MemberType;
                }
                
                public FieldExpr (FieldBase fi, Location l)
@@ -4825,14 +4280,6 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public FieldExpr (Field fi, Type genericType, Location l)
-                       : this (fi, l)
-               {
-                       if (TypeManager.IsGenericTypeDefinition (genericType))
-                               return;
-                       this.constructed_generic_type = genericType;
-               }
-
                public override string Name {
                        get {
                                return spec.Name;
@@ -4857,15 +4304,15 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Type DeclaringType {
+               public override TypeSpec DeclaringType {
                        get {
-                               return spec.MetaInfo.DeclaringType;
+                               return spec.DeclaringType;
                        }
                }
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.GetFullNameSignature (spec.MetaInfo);
+                       return TypeManager.GetFullNameSignature (spec);
                }
 
                public VariableInfo VariableInfo {
@@ -4877,10 +4324,7 @@ namespace Mono.CSharp {
                public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, Location loc,
                                                                SimpleName original)
                {
-                       FieldInfo fi = TypeManager.GetGenericFieldDefinition (spec.MetaInfo);
-                       Type t = fi.FieldType;
-
-                       if (t.IsPointer && !ec.IsUnsafe) {
+                       if (spec.MemberType.IsPointer && !ec.IsUnsafe) {
                                UnsafeError (ec, loc);
                        }
 
@@ -4912,7 +4356,7 @@ namespace Mono.CSharp {
 
                public Expression CreateTypeOfExpression ()
                {
-                       return new TypeOfField (Import.CreateField (GetConstructedFieldInfo ()), loc);
+                       return new TypeOfField (spec, loc);
                }
 
                protected override Expression DoResolve (ResolveContext ec)
@@ -4961,14 +4405,9 @@ namespace Mono.CSharp {
                        }
 
                        if (!ec.IsObsolete) {
-                               FieldBase f = TypeManager.GetField (spec.MetaInfo);
-                               if (f != null) {
-                                       f.CheckObsoleteness (loc);
-                               } else {
-                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
-                                       if (oa != null)
-                                               AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (spec.MetaInfo), loc, ec.Report);
-                               }
+                               ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (spec), loc, ec.Report);
                        }
 
                        var fb = spec as FixedFieldSpec;
@@ -4981,9 +4420,9 @@ namespace Mono.CSharp {
                                }
 
                                if (InstanceExpression.eclass != ExprClass.Variable) {
-                                       ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
+                                       ec.Report.SymbolRelatedToPreviousError (spec);
                                        ec.Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields",
-                                               TypeManager.GetFullNameSignature (spec.MetaInfo));
+                                               TypeManager.GetFullNameSignature (spec));
                                } else if (var != null && var.IsHoisted) {
                                        AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, var, loc);
                                }
@@ -5048,7 +4487,7 @@ namespace Mono.CSharp {
                        if (var != null && var.VariableInfo != null)
                                var.VariableInfo.SetFieldAssigned (ec, Name);
 
-                       bool lvalue_instance = !spec.IsStatic && TypeManager.IsValueType (spec.MetaInfo.DeclaringType);
+                       bool lvalue_instance = !spec.IsStatic && TypeManager.IsValueType (spec.DeclaringType);
                        bool out_access = right_side == EmptyExpression.OutAccess.Instance || right_side == EmptyExpression.LValueMemberOutAccess;
 
                        Expression e = DoResolve (ec, lvalue_instance, out_access);
@@ -5056,16 +4495,13 @@ namespace Mono.CSharp {
                        if (e == null)
                                return null;
 
-                       FieldBase fb = TypeManager.GetField (spec.MetaInfo);
-                       if (fb != null) {
-                               fb.SetAssigned ();
+                       spec.MemberDefinition.SetIsAssigned ();
 
-                               if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess.Instance) &&
-                                       (fb.ModFlags & Modifiers.VOLATILE) != 0) {
-                                       ec.Report.Warning (420, 1, loc,
-                                               "`{0}': A volatile field references will not be treated as volatile",
-                                               fb.GetSignatureForError ());
-                               }
+                       if ((right_side == EmptyExpression.UnaryAddress || right_side == EmptyExpression.OutAccess.Instance) &&
+                                       (spec.Modifiers & Modifiers.VOLATILE) != 0) {
+                               ec.Report.Warning (420, 1, loc,
+                                       "`{0}': A volatile field references will not be treated as volatile",
+                                       spec.GetSignatureForError ());
                        }
 
                        if (spec.IsReadOnly) {
@@ -5074,10 +4510,9 @@ namespace Mono.CSharp {
                                        return Report_AssignToReadonly (ec, right_side);
 
                                if (ec.HasSet (ResolveContext.Options.ConstructorScope)) {
-                                       Type ctype = ec.CurrentType;
 
                                        // InitOnly fields cannot be assigned-to in a different constructor from their declaring type
-                                       if (!TypeManager.IsEqual (ctype, DeclaringType))
+                                       if (!TypeManager.IsEqual (ec.CurrentMemberDefinition.Parent.Definition, DeclaringType.GetDefinition ()))
                                                return Report_AssignToReadonly (ec, right_side);
                                        // static InitOnly fields cannot be assigned-to in an instance constructor
                                        if (IsStatic && !ec.IsStatic)
@@ -5126,7 +4561,7 @@ namespace Mono.CSharp {
                                //
                                IVariableReference variable = InstanceExpression as IVariableReference;
                                if (variable != null)
-                                       return TypeManager.IsStruct (InstanceExpression.Type) && variable.IsFixed;
+                                       return InstanceExpression.Type.IsStruct && variable.IsFixed;
 
                                IFixedExpression fe = InstanceExpression as IFixedExpression;
                                return fe != null && fe.IsFixed;
@@ -5146,7 +4581,7 @@ namespace Mono.CSharp {
                        if (fe == null)
                                return false;
 
-                       if (spec.MetaInfo != fe.spec.MetaInfo)
+                       if (spec != fe.spec)
                                return false;
 
                        if (InstanceExpression == null || fe.InstanceExpression == null)
@@ -5157,45 +4592,41 @@ namespace Mono.CSharp {
                
                public void Emit (EmitContext ec, bool leave_copy)
                {
-                       ILGenerator ig = ec.ig;
                        bool is_volatile = false;
 
-                       var f = TypeManager.GetField (spec.MetaInfo);
-                       if (f != null){
-                               if ((f.ModFlags & Modifiers.VOLATILE) != 0)
-                                       is_volatile = true;
+                       if ((spec.Modifiers & Modifiers.VOLATILE) != 0)
+                               is_volatile = true;
 
-                               f.SetIsUsed ();
-                       }
+                       spec.MemberDefinition.SetIsUsed ();
                        
                        if (IsStatic){
                                if (is_volatile)
-                                       ig.Emit (OpCodes.Volatile);
+                                       ec.Emit (OpCodes.Volatile);
 
-                               ig.Emit (OpCodes.Ldsfld, GetConstructedFieldInfo ());
+                               ec.Emit (OpCodes.Ldsfld, spec);
                        } else {
                                if (!prepared)
                                        EmitInstance (ec, false);
 
                                // Optimization for build-in types
                                if (TypeManager.IsStruct (type) && TypeManager.IsEqual (type, ec.MemberContext.CurrentType) && TypeManager.IsEqual (InstanceExpression.Type, type)) {
-                                       LoadFromPtr (ig, type);
+                                       ec.EmitLoadFromPtr (type);
                                } else {
                                        var ff = spec as FixedFieldSpec;
                                        if (ff != null) {
-                                               ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
-                                               ig.Emit (OpCodes.Ldflda, ff.Element);
+                                               ec.Emit (OpCodes.Ldflda, spec);
+                                               ec.Emit (OpCodes.Ldflda, ff.Element);
                                        } else {
                                                if (is_volatile)
-                                                       ig.Emit (OpCodes.Volatile);
+                                                       ec.Emit (OpCodes.Volatile);
 
-                                               ig.Emit (OpCodes.Ldfld, GetConstructedFieldInfo ());
+                                               ec.Emit (OpCodes.Ldfld, spec);
                                        }
                                }
                        }
 
                        if (leave_copy) {
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                                if (!IsStatic) {
                                        temp = new LocalTemporary (this.Type);
                                        temp.Store (ec);
@@ -5205,34 +4636,27 @@ namespace Mono.CSharp {
 
                public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
                {
-                       //FieldAttributes fa = FieldInfo.Attributes;
-                       //bool is_static = (fa & FieldAttributes.Static) != 0;
-                       ILGenerator ig = ec.ig;
-
                        prepared = prepare_for_load;
                        EmitInstance (ec, prepared);
 
                        source.Emit (ec);
                        if (leave_copy) {
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                                if (!IsStatic) {
                                        temp = new LocalTemporary (this.Type);
                                        temp.Store (ec);
                                }
                        }
 
-                       FieldBase f = TypeManager.GetField (spec.MetaInfo);
-                       if (f != null){
-                               if ((f.ModFlags & Modifiers.VOLATILE) != 0)
-                                       ig.Emit (OpCodes.Volatile);
+                       if ((spec.Modifiers & Modifiers.VOLATILE) != 0)
+                               ec.Emit (OpCodes.Volatile);
                                        
-                               f.SetAssigned ();
-                       }
+                       spec.MemberDefinition.SetIsAssigned ();
 
                        if (IsStatic)
-                               ig.Emit (OpCodes.Stsfld, GetConstructedFieldInfo ());
+                               ec.Emit (OpCodes.Stsfld, spec);
                        else
-                               ig.Emit (OpCodes.Stfld, GetConstructedFieldInfo ());
+                               ec.Emit (OpCodes.Stfld, spec);
                        
                        if (temp != null) {
                                temp.Emit (ec);
@@ -5248,8 +4672,7 @@ namespace Mono.CSharp {
 
                public override void EmitSideEffect (EmitContext ec)
                {
-                       FieldBase f = TypeManager.GetField (spec.MetaInfo);
-                       bool is_volatile = f != null && (f.ModFlags & Modifiers.VOLATILE) != 0;
+                       bool is_volatile = (spec.Modifiers & Modifiers.VOLATILE) != 0;
 
                        if (is_volatile || is_marshal_by_ref ())
                                base.EmitSideEffect (ec);
@@ -5264,15 +4687,10 @@ namespace Mono.CSharp {
 
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
-                       ILGenerator ig = ec.ig;
-
-                       FieldBase f = TypeManager.GetField (spec.MetaInfo);
-                       if (f != null){                         
-                               if ((mode & AddressOp.Store) != 0)
-                                       f.SetAssigned ();
-                               if ((mode & AddressOp.Load) != 0)
-                                       f.SetIsUsed ();
-                       }
+                       if ((mode & AddressOp.Store) != 0)
+                               spec.MemberDefinition.SetIsAssigned ();
+                       if ((mode & AddressOp.Load) != 0)
+                               spec.MemberDefinition.SetIsUsed ();
 
                        //
                        // Handle initonly fields specially: make a copy and then
@@ -5294,30 +4712,22 @@ namespace Mono.CSharp {
                        if (need_copy){
                                LocalBuilder local;
                                Emit (ec);
-                               local = ig.DeclareLocal (type);
-                               ig.Emit (OpCodes.Stloc, local);
-                               ig.Emit (OpCodes.Ldloca, local);
+                               local = ec.DeclareLocal (type, false);
+                               ec.Emit (OpCodes.Stloc, local);
+                               ec.Emit (OpCodes.Ldloca, local);
                                return;
                        }
 
 
                        if (IsStatic){
-                               ig.Emit (OpCodes.Ldsflda, GetConstructedFieldInfo ());
+                               ec.Emit (OpCodes.Ldsflda, spec);
                        } else {
                                if (!prepared)
                                        EmitInstance (ec, false);
-                               ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
+                               ec.Emit (OpCodes.Ldflda, spec);
                        }
                }
 
-               FieldInfo GetConstructedFieldInfo ()
-               {
-                       if (constructed_generic_type == null)
-                               return spec.MetaInfo;
-
-                       return TypeBuilder.GetField (constructed_generic_type, spec.MetaInfo);
-               }
-
                public SLE.Expression MakeAssignExpression (BuilderContext ctx)
                {
                        return MakeExpression (ctx);
@@ -5325,14 +4735,8 @@ namespace Mono.CSharp {
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), spec.MetaInfo);
+                       return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), spec.GetMetaInfo ());
                }
-               
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       storey.MutateField (spec);
-                       base.MutateHoistedGenericType (storey);
-               }               
        }
 
        
@@ -5346,24 +4750,21 @@ namespace Mono.CSharp {
        public class PropertyExpr : MemberExpr, IDynamicAssign
        {
                PropertySpec spec;
-               MethodSpec getter, setter;
-               bool is_static;
-
                TypeArguments targs;
                
                LocalTemporary temp;
                bool prepared;
 
-               public PropertyExpr (Type container_type, PropertySpec spec, Location l)
+               public PropertyExpr (TypeSpec container_type, PropertySpec spec, Location l)
                {
                        this.spec = spec;
                        loc = l;
 
-                       type = TypeManager.TypeToCoreType (spec.PropertyType);
-
-                       ResolveAccessors (container_type);
+                       type = spec.MemberType;
                }
 
+               #region Properties
+
                public override string Name {
                        get {
                                return spec.Name;
@@ -5372,16 +4773,18 @@ namespace Mono.CSharp {
 
                public override bool IsInstance {
                        get {
-                               return !is_static;
+                               return !IsStatic;
                        }
                }
 
                public override bool IsStatic {
                        get {
-                               return is_static;
+                               return spec.IsStatic;
                        }
                }
 
+               #endregion
+
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        Arguments args;
@@ -5401,16 +4804,16 @@ namespace Mono.CSharp {
                                args.Add (new Argument (new NullLiteral (loc)));
                        else
                                args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
-                       args.Add (new Argument (new TypeOfMethod (getter, loc)));
+                       args.Add (new Argument (new TypeOfMethod (spec.Get, loc)));
                        return CreateExpressionFactoryCall (ec, "Property", args);
                }
 
                public Expression CreateSetterTypeOfExpression ()
                {
-                       return new TypeOfMethod (setter, loc);
+                       return new TypeOfMethod (spec.Set, loc);
                }
 
-               public override Type DeclaringType {
+               public override TypeSpec DeclaringType {
                        get {
                                return spec.DeclaringType;
                        }
@@ -5418,108 +4821,28 @@ namespace Mono.CSharp {
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.GetFullNameSignature (spec.MetaInfo);
-               }
-
-               void FindAccessors (Type invocation_type)
-               {
-                       const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
-                               BindingFlags.Static | BindingFlags.Instance |
-                               BindingFlags.DeclaredOnly;
-
-                       Type current = spec.DeclaringType;
-                       for (; current != null; current = current.BaseType) {
-                               MemberInfo[] group = TypeManager.MemberLookup (
-                                       invocation_type, invocation_type, current,
-                                       MemberTypes.Property, flags, spec.Name, null);
-
-                               if (group == null)
-                                       continue;
-
-                               if (group.Length != 1)
-                                       // Oooops, can this ever happen ?
-                                       return;
-
-                               PropertyInfo pi = (PropertyInfo) group [0];
-
-                               if (getter == null) {
-                                       var m = pi.GetGetMethod (true);
-                                       if (m != null)
-                                               getter = Import.CreateMethod (m);
-                               }
-
-                               if (setter == null) {
-                                       var m = pi.GetSetMethod (true);
-                                       if (m != null)
-                                               setter = Import.CreateMethod (m);
-                               }
-
-                               var accessor = getter != null ? getter : setter;
-
-                               if (!accessor.IsVirtual)
-                                       return;
-                       }
-               }
-
-               //
-               // We also perform the permission checking here, as the PropertyInfo does not
-               // hold the information for the accessibility of its setter/getter
-               //
-               // TODO: Refactor to use some kind of cache together with GetPropertyFromAccessor
-               void ResolveAccessors (Type container_type)
-               {
-                       FindAccessors (container_type);
-
-                       if (getter != null) {
-                               MethodBase the_getter = TypeManager.DropGenericMethodArguments (getter);
-                               IMethodData md = TypeManager.GetMethod (the_getter);
-                               if (md != null)
-                                       md.SetIsUsed ();
-
-                               is_static = getter.IsStatic;
-                       }
-
-                       if (setter != null) {
-                               MethodBase the_setter = TypeManager.DropGenericMethodArguments (setter);
-                               IMethodData md = TypeManager.GetMethod (the_setter);
-                               if (md != null)
-                                       md.SetIsUsed ();
-
-                               is_static = setter.IsStatic;
-                       }
+                       return TypeManager.GetFullNameSignature (spec);
                }
 
                public SLE.Expression MakeAssignExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) setter.MetaInfo);
+                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) spec.Set.GetMetaInfo ());
                }
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) getter.MetaInfo);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (InstanceExpression != null)
-                               InstanceExpression.MutateHoistedGenericType (storey);
-
-                       type = storey.MutateType (type);
-                       if (getter != null)
-                               storey.MutateGenericMethod (getter);
-                       if (setter != null)
-                               storey.MutateGenericMethod (setter);
+                       return SLE.Expression.Property (InstanceExpression.MakeExpression (ctx), (MethodInfo) spec.Get.GetMetaInfo ());
                }
 
-               public PropertyInfo PropertyInfo {
+               public PropertySpec PropertyInfo {
                        get {
-                               return spec.MetaInfo;
+                               return spec;
                        }
                }
 
                bool InstanceResolve (ResolveContext ec, bool lvalue_instance, bool must_do_cs1540_check)
                {
-                       if (is_static) {
+                       if (IsStatic) {
                                InstanceExpression = null;
                                return true;
                        }
@@ -5542,51 +4865,37 @@ namespace Mono.CSharp {
                            !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
                            !TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
                            !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
-                               ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
-                               Error_CannotAccessProtected (ec, loc, spec.MetaInfo, InstanceExpression.Type, ec.CurrentType);
+                               ec.Report.SymbolRelatedToPreviousError (spec);
+                               Error_CannotAccessProtected (ec, loc, spec, InstanceExpression.Type, ec.CurrentType);
                                return false;
                        }
 
                        return true;
                }
 
-               void Error_PropertyNotFound (ResolveContext ec, MethodSpec mi, bool getter)
+               void Error_PropertyNotValid (ResolveContext ec)
                {
-                       // TODO: correctly we should compare arguments but it will lead to bigger changes
-                       if (mi.MetaInfo is MethodBuilder) {
-                               Error_TypeDoesNotContainDefinition (ec, loc, spec.DeclaringType, Name);
-                               return;
-                       }
-                       
-                       StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
-                       sig.Append ('.');
-                       AParametersCollection iparams = mi.Parameters;
-                       sig.Append (getter ? "get_" : "set_");
-                       sig.Append (Name);
-                       sig.Append (iparams.GetSignatureForError ());
-
-                       ec.Report.SymbolRelatedToPreviousError (mi.MetaInfo);
-                       ec.Report.Error (1546, loc, "Property `{0}' is not supported by the C# language. Try to call the accessor method `{1}' directly",
-                               Name, sig.ToString ());
+                       ec.Report.SymbolRelatedToPreviousError (spec);
+                       ec.Report.Error (1546, loc, "Property or event `{0}' is not supported by the C# language",
+                               GetSignatureForError ());
                }
 
-               public bool IsAccessibleFrom (Type invocation_type, bool lvalue)
+               public bool IsAccessibleFrom (TypeSpec invocation_type, bool lvalue)
                {
                        bool dummy;
-                       var accessor = lvalue ? setter : getter;
+                       var accessor = lvalue ? spec.Set : spec.Get;
                        if (accessor == null && lvalue)
-                               accessor = getter;
-                       return accessor != null && IsAccessorAccessible (invocation_type, accessor, out dummy);
+                               accessor = spec.Get;
+                       return accessor != null && IsMemberAccessible (invocation_type, accessor, out dummy);
                }
 
                bool IsSingleDimensionalArrayLength ()
                {
-                       if (DeclaringType != TypeManager.array_type || getter == null || Name != "Length")
+                       if (DeclaringType != TypeManager.array_type || !spec.HasGet || Name != "Length")
                                return false;
 
-                       string t_name = InstanceExpression.Type.Name;
-                       int t_name_len = t_name.Length;
-                       return t_name_len > 2 && t_name [t_name_len - 2] == '[';
+                       ArrayContainer ac = InstanceExpression.Type as ArrayContainer;
+                       return ac != null && ac.Rank == 1;
                }
 
                protected override Expression DoResolve (ResolveContext ec)
@@ -5600,8 +4909,8 @@ namespace Mono.CSharp {
 
                        if (!res) {
                                if (InstanceExpression != null) {
-                                       Type expr_type = InstanceExpression.Type;
-                                       ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, loc);
+                                       TypeSpec expr_type = InstanceExpression.Type;
+                                       ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, 0, loc);
                                        if (ex_method_lookup != null) {
                                                ex_method_lookup.ExtensionExpression = InstanceExpression;
                                                ex_method_lookup.SetTypeArguments (ec, targs);
@@ -5619,23 +4928,18 @@ namespace Mono.CSharp {
                        //
                        // Only base will allow this invocation to happen.
                        //
-                       if (IsBase && getter.IsAbstract) {
-                               Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec.MetaInfo));
+                       if (IsBase && spec.IsAbstract) {
+                               Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec));
                        }
 
-                       if (spec.PropertyType.IsPointer && !ec.IsUnsafe){
+                       if (spec.MemberType.IsPointer && !ec.IsUnsafe){
                                UnsafeError (ec, loc);
                        }
 
                        if (!ec.IsObsolete) {
-                               PropertyBase pb = TypeManager.GetProperty (spec.MetaInfo);
-                               if (pb != null) {
-                                       pb.CheckObsoleteness (loc);
-                               } else {
-                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
-                                       if (oa != null)
-                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
-                               }
+                               ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
                        }
 
                        return this;
@@ -5659,16 +4963,12 @@ namespace Mono.CSharp {
                                Error_CannotModifyIntermediateExpressionValue (ec);
                        }
 
-                       if (setter == null){
-                               //
-                               // The following condition happens if the PropertyExpr was
-                               // created, but is invalid (ie, the property is inaccessible),
-                               // and we did not want to embed the knowledge about this in
-                               // the caller routine.  This only avoids double error reporting.
-                               //
-                               if (getter == null)
-                                       return null;
+                       if (spec.IsNotRealProperty) {
+                               Error_PropertyNotValid (ec);
+                               return null;
+                       }
 
+                       if (!spec.HasSet){
                                if (ec.CurrentBlock.Toplevel.GetParameterReference (spec.Name, loc) is MemberAccess) {
                                        ec.Report.Error (1947, loc, "A range variable `{0}' cannot be assigned to. Consider using `let' clause to store the value",
                                                spec.Name);
@@ -5684,22 +4984,15 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (setter.Parameters.Count != 1){
-                               Error_PropertyNotFound (ec, setter, false);
-                               return null;
-                       }
-
                        bool must_do_cs1540_check;
-                       if (!IsAccessorAccessible (ec.CurrentType, setter, out must_do_cs1540_check)) {
-                               PropertyBase.PropertyMethod pm = TypeManager.GetMethod (setter.MetaInfo) as PropertyBase.PropertyMethod;
-                               if (pm != null && pm.HasCustomAccessModifier) {
-                                       ec.Report.SymbolRelatedToPreviousError (pm);
+                       if (!IsMemberAccessible (ec.CurrentType, spec.Set, out must_do_cs1540_check)) {
+                               if (spec.HasDifferentAccessibility) {
+                                       ec.Report.SymbolRelatedToPreviousError (spec.Set);
                                        ec.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
-                                               TypeManager.CSharpSignature (setter));
-                               }
-                               else {
-                                       ec.Report.SymbolRelatedToPreviousError (setter.MetaInfo);
-                                       ErrorIsInaccesible (loc, TypeManager.CSharpSignature (setter), ec.Report);
+                                               TypeManager.CSharpSignature (spec));
+                               } else {
+                                       ec.Report.SymbolRelatedToPreviousError (spec.Set);
+                                       ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.Set), ec.Report);
                                }
                                return null;
                        }
@@ -5710,23 +5003,18 @@ namespace Mono.CSharp {
                        //
                        // Only base will allow this invocation to happen.
                        //
-                       if (IsBase && setter.IsAbstract){
-                               Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec.MetaInfo));
+                       if (IsBase && spec.IsAbstract){
+                               Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (spec));
                        }
 
-                       if (spec.PropertyType.IsPointer && !ec.IsUnsafe) {
+                       if (spec.MemberType.IsPointer && !ec.IsUnsafe) {
                                UnsafeError (ec, loc);
                        }
 
                        if (!ec.IsObsolete) {
-                               PropertyBase pb = TypeManager.GetProperty (spec.MetaInfo);
-                               if (pb != null) {
-                                       pb.CheckObsoleteness (loc);
-                               } else {
-                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (spec.MetaInfo);
-                                       if (oa != null)
-                                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
-                               }
+                               ObsoleteAttribute oa = spec.GetAttributeObsolete ();
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
                        }
 
                        return this;
@@ -5745,16 +5033,16 @@ namespace Mono.CSharp {
                        if (IsSingleDimensionalArrayLength ()) {
                                if (!prepared)
                                        EmitInstance (ec, false);
-                               ec.ig.Emit (OpCodes.Ldlen);
-                               ec.ig.Emit (OpCodes.Conv_I4);
+                               ec.Emit (OpCodes.Ldlen);
+                               ec.Emit (OpCodes.Conv_I4);
                                return;
                        }
 
-                       Invocation.EmitCall (ec, IsBase, InstanceExpression, getter, null, loc, prepared, false);
+                       Invocation.EmitCall (ec, IsBase, InstanceExpression, spec.Get, null, loc, prepared, false);
                        
                        if (leave_copy) {
-                               ec.ig.Emit (OpCodes.Dup);
-                               if (!is_static) {
+                               ec.Emit (OpCodes.Dup);
+                               if (!IsStatic) {
                                        temp = new LocalTemporary (this.Type);
                                        temp.Store (ec);
                                }
@@ -5773,8 +5061,8 @@ namespace Mono.CSharp {
                                source.Emit (ec);
                                
                                if (leave_copy) {
-                                       ec.ig.Emit (OpCodes.Dup);
-                                       if (!is_static) {
+                                       ec.Emit (OpCodes.Dup);
+                                       if (!IsStatic) {
                                                temp = new LocalTemporary (this.Type);
                                                temp.Store (ec);
                                        }
@@ -5789,7 +5077,7 @@ namespace Mono.CSharp {
                        Arguments args = new Arguments (1);
                        args.Add (new Argument (my_source));
                        
-                       Invocation.EmitCall (ec, IsBase, InstanceExpression, setter, args, loc, false, prepared);
+                       Invocation.EmitCall (ec, IsBase, InstanceExpression, spec.Set, args, loc, false, prepared);
                        
                        if (temp != null) {
                                temp.Emit (ec);
@@ -5804,40 +5092,28 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       if (getter != null) {
-                               if (!getter.Parameters.IsEmpty) {
-                                       Error_PropertyNotFound (ec, getter, true);
-                                       return false;
-                               }
+                       if (spec.IsNotRealProperty) {
+                               Error_PropertyNotValid (ec);
+                               return false;
                        }
 
-                       if (getter == null) {
-                               //
-                               // The following condition happens if the PropertyExpr was
-                               // created, but is invalid (ie, the property is inaccessible),
-                               // and we did not want to embed the knowledge about this in
-                               // the caller routine.  This only avoids double error reporting.
-                               //
-                               if (setter == null)
-                                       return false;
-
+                       if (!spec.HasGet) {
                                if (InstanceExpression != EmptyExpression.Null) {
+                                       ec.Report.SymbolRelatedToPreviousError (spec);
                                        ec.Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks the `get' accessor",
-                                               TypeManager.GetFullNameSignature (spec.MetaInfo));
+                                               spec.GetSignatureForError ());
                                        return false;
                                }
                        }
 
-                       if (getter != null &&
-                               !IsAccessorAccessible (ec.CurrentType, getter, out must_do_cs1540_check)) {
-                               PropertyBase.PropertyMethod pm = TypeManager.GetMethod (getter.MetaInfo) as PropertyBase.PropertyMethod;
-                               if (pm != null && pm.HasCustomAccessModifier) {
-                                       ec.Report.SymbolRelatedToPreviousError (pm);
+                       if (spec.HasGet && !IsMemberAccessible (ec.CurrentType, spec.Get, out must_do_cs1540_check)) {
+                               if (spec.HasDifferentAccessibility) {
+                                       ec.Report.SymbolRelatedToPreviousError (spec.Get);
                                        ec.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because the get accessor is inaccessible",
-                                               TypeManager.CSharpSignature (getter.MetaInfo));
+                                               TypeManager.CSharpSignature (spec));
                                } else {
-                                       ec.Report.SymbolRelatedToPreviousError (getter.MetaInfo);
-                                       ErrorIsInaccesible (loc, TypeManager.CSharpSignature (getter.MetaInfo), ec.Report);
+                                       ec.Report.SymbolRelatedToPreviousError (spec.Get);
+                                       ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.Get), ec.Report);
                                }
 
                                return false;
@@ -5883,7 +5159,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Type DeclaringType {
+               public override TypeSpec DeclaringType {
                        get {
                                return spec.DeclaringType;
                        }
@@ -5906,7 +5182,7 @@ namespace Mono.CSharp {
                            TypeManager.IsNestedChildOf(ec.CurrentType, spec.DeclaringType)) {
                                        
                                // TODO: Breaks dynamic binder as currect context fields are imported and not compiled
-                               EventField mi = TypeManager.GetEventField (spec.MetaInfo).MemberDefinition as EventField;
+                               EventField mi = spec.MemberDefinition as EventField;
 
                                if (mi != null && mi.HasBackingField) {
                                        mi.SetIsUsed ();
@@ -5947,7 +5223,7 @@ namespace Mono.CSharp {
                                return false;
 
                        if (IsBase && spec.IsAbstract) {
-                               Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature(spec.MetaInfo));
+                               Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature(spec));
                                return false;
                        }
 
@@ -5961,19 +5237,19 @@ namespace Mono.CSharp {
                            !TypeManager.IsInstantiationOfSameGenericType (InstanceExpression.Type, ec.CurrentType) &&
                            !TypeManager.IsNestedChildOf (ec.CurrentType, InstanceExpression.Type) &&
                            !TypeManager.IsSubclassOf (InstanceExpression.Type, ec.CurrentType)) {
-                               ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
-                               ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.MetaInfo), ec.Report);
+                               ec.Report.SymbolRelatedToPreviousError (spec);
+                               ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec), ec.Report);
                                return false;
                        }
 
                        return true;
                }
 
-               public bool IsAccessibleFrom (Type invocation_type)
+               public bool IsAccessibleFrom (TypeSpec invocation_type)
                {
                        bool dummy;
-                       return IsAccessorAccessible (invocation_type, spec.AccessorAdd, out dummy) &&
-                               IsAccessorAccessible (invocation_type, spec.AccessorRemove, out dummy);
+                       return IsMemberAccessible (invocation_type, spec.AccessorAdd, out dummy) &&
+                               IsMemberAccessible (invocation_type, spec.AccessorRemove, out dummy);
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
@@ -5993,10 +5269,10 @@ namespace Mono.CSharp {
                        eclass = ExprClass.EventAccess;
 
                        bool must_do_cs1540_check;
-                       if (!(IsAccessorAccessible (ec.CurrentType, spec.AccessorAdd, out must_do_cs1540_check) &&
-                             IsAccessorAccessible (ec.CurrentType, spec.AccessorRemove, out must_do_cs1540_check))) {
-                               ec.Report.SymbolRelatedToPreviousError (spec.MetaInfo);
-                               ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec.MetaInfo), ec.Report);
+                       if (!(IsMemberAccessible (ec.CurrentType, spec.AccessorAdd, out must_do_cs1540_check) &&
+                             IsMemberAccessible (ec.CurrentType, spec.AccessorRemove, out must_do_cs1540_check))) {
+                               ec.Report.SymbolRelatedToPreviousError (spec);
+                               ErrorIsInaccesible (loc, TypeManager.CSharpSignature (spec), ec.Report);
                                return null;
                        }
 
@@ -6009,13 +5285,13 @@ namespace Mono.CSharp {
                        }
 
                        if (!ec.IsObsolete) {
-                               var oa = spec.GetObsoleteAttribute ();
+                               var oa = spec.GetAttributeObsolete ();
                                if (oa != null)
                                        AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
                        }
 
                        spec.MemberDefinition.SetIsUsed ();
-                       type = spec.EventType;
+                       type = spec.MemberType;
                        
                        return this;
                }               
@@ -6035,7 +5311,7 @@ namespace Mono.CSharp {
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.CSharpSignature (spec.MetaInfo);
+                       return TypeManager.CSharpSignature (spec);
                }
 
                public void EmitAddOrRemove (EmitContext ec, bool is_add, Expression source)
@@ -6052,7 +5328,7 @@ namespace Mono.CSharp {
        {
                LocalInfo li;
 
-               public TemporaryVariable (Type type, Location loc)
+               public TemporaryVariable (TypeSpec type, Location loc)
                {
                        this.type = type;
                        this.loc = loc;
index 1aa4e361f90f92f01f80494d38b54444d709f715..d323e062d02ce2db1676b70944d5eeffe79a3510 100644 (file)
@@ -23,16 +23,9 @@ namespace Mono.CSharp {
        {
                class EnumTypeExpr : TypeExpr
                {
-                       public readonly Enum Enum;
-
-                       public EnumTypeExpr (Enum e)
-                       {
-                               this.Enum = e;
-                       }
-
                        protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
                        {
-                               type = Enum.CurrentType != null ? Enum.CurrentType : Enum.TypeBuilder;
+                               type = ec.CurrentType;
                                return this;
                        }
 
@@ -44,13 +37,13 @@ namespace Mono.CSharp {
 
                public EnumMember (Enum parent, EnumMember prev_member, string name, Expression expr,
                                   Attributes attrs, Location loc)
-                       : base (parent, new EnumTypeExpr (parent), name, null, Modifiers.PUBLIC,
+                       : base (parent, new EnumTypeExpr (), name, null, Modifiers.PUBLIC,
                                attrs, loc)
                {
                        initializer = new EnumInitializer (this, expr, prev_member);
                }
 
-               static bool IsValidEnumType (Type t)
+               static bool IsValidEnumType (TypeSpec t)
                {
                        return (t == TypeManager.int32_type || t == TypeManager.uint32_type || t == TypeManager.int64_type ||
                                t == TypeManager.byte_type || t == TypeManager.sbyte_type || t == TypeManager.short_type ||
@@ -84,12 +77,10 @@ namespace Mono.CSharp {
                                return false;
 
                        const FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
-                       FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, attr);
-                       spec = new ConstSpec (this, FieldBuilder, ModFlags, initializer);
-
-                       Parent.MemberCache.AddMember (FieldBuilder, spec);
-                       TypeManager.RegisterConstant (FieldBuilder, (ConstSpec) spec);
+                       FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType.GetMetaInfo (), attr);
+                       spec = new ConstSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags, initializer);
 
+                       Parent.MemberCache.AddMember (spec);
                        return true;
                }
        }
@@ -113,7 +104,7 @@ namespace Mono.CSharp {
                                return field.ConvertInitializer (rc, null);
 
                        try {
-                               var ec = prev.Initializer.Resolve (rc) as EnumConstant;
+                               var ec = prev.DefineValue () as EnumConstant;
                                expr = ec.Increment ().Resolve (rc);
                        } catch (OverflowException) {
                                rc.Report.Error (543, field.Location,
@@ -151,6 +142,7 @@ namespace Mono.CSharp {
                        this.base_type = type;
                        var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
                        ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod_flags, accmods, Location, Report);
+                       spec = new EnumSpec (null, this, null, null, ModFlags);
                }
 
                public void AddEnumMember (EnumMember em)
@@ -175,19 +167,19 @@ namespace Mono.CSharp {
                        if (!base.DefineNestedTypes ())
                                return false;
 
-                       //
-                       // Call MapToInternalType for corlib
-                       //
-                       TypeBuilder.DefineField (UnderlyingValueField, UnderlyingType,
-                                                FieldAttributes.Public | FieldAttributes.SpecialName
-                                                | FieldAttributes.RTSpecialName);
+                       ((EnumSpec) spec).UnderlyingType = UnderlyingType;
+
+                       TypeBuilder.DefineField (UnderlyingValueField, UnderlyingType.GetMetaInfo (),
+                               FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
+
+                       if (!RootContext.StdLib)
+                               RootContext.hack_corlib_enums.Add (this);
 
                        return true;
                }
 
                protected override bool DoDefineMembers ()
                {
-                       member_cache = new MemberCache (TypeManager.enum_type, this);
                        DefineContainerMembers (constants);
                        return true;
                }
@@ -197,7 +189,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public Type UnderlyingType {
+               public TypeSpec UnderlyingType {
                        get {
                                return base_type.Type;
                        }
@@ -231,14 +223,31 @@ namespace Mono.CSharp {
                }
        }
 
-       public class EnumSpec : TypeSpec
+       class EnumSpec : TypeSpec
        {
-               public EnumSpec (MemberKind kind, ITypeDefinition definition, TypeSpec underlyingType, Type info, string name, Modifiers modifiers)
-                       : base (kind, definition, info, name, modifiers)
+               TypeSpec underlying;
+
+               public EnumSpec (TypeSpec declaringType, ITypeDefinition definition, TypeSpec underlyingType, Type info, Modifiers modifiers)
+                       : base (MemberKind.Enum, declaringType, definition, info, modifiers | Modifiers.SEALED)
                {
-                       this.UnderlyingType = underlyingType;
+                       this.underlying = underlyingType;
                }
 
-               public TypeSpec UnderlyingType { get; private set; }
+               public TypeSpec UnderlyingType {
+                       get {
+                               return underlying;
+                       }
+                       set {
+                               if (underlying != null)
+                                       throw new InternalErrorException ("UnderlyingType reset");
+
+                               underlying = value;
+                       }
+               }
+
+               public static TypeSpec GetUnderlyingType (TypeSpec t)
+               {
+                       return ((EnumSpec) t.GetDefinition ()).UnderlyingType;
+               }
        }
 }
index a1ba9e235371cb7d79b0420af2067d871c645d43..66fc039a53ee0ff2a5d76777cc3b8b8dabe2ec06 100644 (file)
@@ -59,7 +59,7 @@ namespace Mono.CSharp {
                internal static List<NamespaceEntry.UsingEntry> using_list = new List<NamespaceEntry.UsingEntry> ();
                static Dictionary<string, FieldInfo> fields = new Dictionary<string, FieldInfo> ();
 
-               static Type   interactive_base_class = typeof (InteractiveBase);
+               static TypeSpec interactive_base_class;
                static Driver driver;
                static bool inited;
 
@@ -127,7 +127,10 @@ namespace Mono.CSharp {
                                
                                CompilerCallableEntryPoint.Reset ();
                                RootContext.ToplevelTypes = new ModuleCompiled (ctx, true);
+                               /*var ctypes = */TypeManager.InitCoreTypes ();
+                               TypeManager.InitExpressionTypes ();
 
+                               Import.Initialize ();
                                driver.LoadReferences ();
                                RootContext.EvalMode = true;
                                inited = true;
@@ -144,6 +147,7 @@ namespace Mono.CSharp {
                static void Reset ()
                {
                        CompilerCallableEntryPoint.PartialReset ();
+                       RootContext.PartialReset ();
                        
                        // Workaround for API limitation where full message printer cannot be passed
                        ReportPrinter printer;
@@ -160,8 +164,8 @@ namespace Mono.CSharp {
                        //
                        // PartialReset should not reset the core types, this is very redundant.
                        //
-                       if (!TypeManager.InitCoreTypes (ctx))
-                               throw new Exception ("Failed to InitCoreTypes");
+//                     if (!TypeManager.InitCoreTypes (ctx, null))
+//                             throw new Exception ("Failed to InitCoreTypes");
                        TypeManager.InitOptionalCoreTypes (ctx);
                        
                        Location.AddFile (null, "{interactive}");
@@ -188,9 +192,12 @@ namespace Mono.CSharp {
                ///   base class and the static members that are
                ///   available to your evaluated code.
                /// </remarks>
-               static public Type InteractiveBaseClass {
+               static public TypeSpec InteractiveBaseClass {
                        get {
-                               return interactive_base_class;
+                               if (interactive_base_class != null)
+                                       return interactive_base_class;
+
+                               return interactive_base_class = Import.ImportType (typeof (InteractiveBase));
                        }
 
                        set {
@@ -743,7 +750,7 @@ namespace Mono.CSharp {
                        // Unlike Mono, .NET requires that the MethodInfo is fetched, it cant
                        // work from MethodBuilders.   Retarded, I know.
                        //
-                       Type tt = CodeGen.Assembly.Builder.GetType (tb.Name);
+                       var tt = CodeGen.Assembly.Builder.GetType (tb.Name);
                        MethodInfo mi = tt.GetMethod (mb.Name);
                        
                        // Pull the FieldInfos from the type, and keep track of them
@@ -755,7 +762,7 @@ namespace Mono.CSharp {
                                // If a previous value was set, nullify it, so that we do
                                // not leak memory
                                if (fields.TryGetValue (field.Name, out old)){
-                                       if (TypeManager.IsStruct (old.FieldType)){
+                                       if (old.FieldType.IsValueType){
                                                //
                                                // TODO: Clear fields for structs
                                                //
@@ -861,7 +868,7 @@ namespace Mono.CSharp {
                                foreach (var de in fields){
                                        FieldInfo fi = LookupField (de.Key);
                                        object value = null;
-                                       bool error = false;
+                                       //bool error = false;
                                        
                                        try {
                                                if (value == null)
@@ -870,13 +877,14 @@ namespace Mono.CSharp {
                                                if (value is string)
                                                        value = Quote ((string)value);
                                        } catch {
-                                               error = true;
+                                               //error = true;
                                        }
-                                       
-                                       if (error)
-                                               sb.Append (String.Format ("{0} {1} <error reading value>", TypeManager.CSharpName(fi.FieldType), de.Key));
-                                       else
-                                               sb.Append (String.Format ("{0} {1} = {2}", TypeManager.CSharpName(fi.FieldType), de.Key, value));
+
+                                       throw new NotImplementedException ("net");
+                                       //if (error)
+                                       //    sb.Append (String.Format ("{0} {1} <error reading value>", TypeManager.CSharpName(fi.FieldType), de.Key));
+                                       //else
+                                       //    sb.Append (String.Format ("{0} {1} = {2}", TypeManager.CSharpName(fi.FieldType), de.Key, value));
                                }
                                
                                return sb.ToString ();
@@ -900,8 +908,9 @@ namespace Mono.CSharp {
                static public void ReferenceAssembly (Assembly a)
                {
                        lock (evaluator_lock){
-                               GlobalRootNamespace.Instance.AddAssemblyReference (a);
-                               GlobalRootNamespace.Instance.ComputeNamespaces (ctx);
+//                             GlobalRootNamespace.Instance.AddAssemblyReference (a);
+//                             GlobalRootNamespace.Instance.ComputeNamespaces (ctx);
+                               GlobalRootNamespace.Instance.ImportAssembly (a);
                        }
                }
 
@@ -1086,12 +1095,12 @@ namespace Mono.CSharp {
                        if (x == null)
                                return "";
                        
-                       Type t = x as Type;
-                       if (t == null)
-                               t = x.GetType ();
+                       TypeSpec t = x as TypeSpec;
+//                     if (t == null)
+//                             t = x.GetType ();
 
                        StringWriter sw = new StringWriter ();
-                       new Outline (t, sw, true, false, false).OutlineType ();
+                       new Outline (t.GetMetaInfo (), sw, true, false, false).OutlineType ();
                        return sw.ToString ();
                }
 #endif
index 18a3062dd82df3bb4fc298d54c7047d9571deb83..233f9295ebfc03c02109681509afbd85c43a7d9d 100644 (file)
@@ -36,7 +36,7 @@ namespace Mono.CSharp {
                        this.arguments = args;
                        this.expr_tree = expr_tree;
 
-                       type = TypeManager.TypeToCoreType (((MethodSpec) mg).ReturnType);
+                       type = mg.BestCandidate.ReturnType;
                        eclass = ExprClass.Value;
                        this.loc = loc;
                }
@@ -73,19 +73,13 @@ namespace Mono.CSharp {
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       var method = ((MethodSpec) mg).MetaInfo as MethodInfo;
+                       var method = mg.BestCandidate.GetMetaInfo () as MethodInfo;
                        return SLE.Expression.Call (method, Arguments.MakeExpression (arguments, ctx));
                }
 
                public MethodGroupExpr Method {
                        get { return mg; }
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       arguments.MutateHoistedGenericType (storey);
-                       mg.MutateHoistedGenericType (storey);
-               }
        }
 
        public class ParenthesizedExpression : ShimExpression
@@ -117,7 +111,7 @@ namespace Mono.CSharp {
                        AddressOf,  TOP
                }
 
-               static Type [] [] predefined_operators;
+               static TypeSpec[][] predefined_operators;
 
                public readonly Operator Oper;
                public Expression Expr;
@@ -144,7 +138,7 @@ namespace Mono.CSharp {
                                return r == null ? null : new SideEffectConstant (r, e, r.Location);
                        }
 
-                       Type expr_type = e.Type;
+                       TypeSpec expr_type = e.Type;
                        
                        switch (Oper){
                        case Operator.UnaryPlus:
@@ -293,7 +287,7 @@ namespace Mono.CSharp {
                        if (predefined_operators == null)
                                CreatePredefinedOperatorsTable ();
 
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
                        Expression best_expr;
 
                        //
@@ -320,7 +314,7 @@ namespace Mono.CSharp {
 
                protected virtual Expression ResolveEnumOperator (ResolveContext ec, Expression expr)
                {
-                       Type underlying_type = TypeManager.GetEnumUnderlyingType (expr.Type);
+                       TypeSpec underlying_type = EnumSpec.GetUnderlyingType (expr.Type);
                        Expression best_expr = ResolvePrimitivePredefinedType (EmptyCast.Create (expr, underlying_type));
                        if (best_expr == null)
                                return null;
@@ -369,12 +363,12 @@ namespace Mono.CSharp {
 
                static void CreatePredefinedOperatorsTable ()
                {
-                       predefined_operators = new Type [(int) Operator.TOP] [];
+                       predefined_operators = new TypeSpec [(int) Operator.TOP] [];
 
                        //
                        // 7.6.1 Unary plus operator
                        //
-                       predefined_operators [(int) Operator.UnaryPlus] = new Type [] {
+                       predefined_operators [(int) Operator.UnaryPlus] = new TypeSpec [] {
                                TypeManager.int32_type, TypeManager.uint32_type,
                                TypeManager.int64_type, TypeManager.uint64_type,
                                TypeManager.float_type, TypeManager.double_type,
@@ -384,7 +378,7 @@ namespace Mono.CSharp {
                        //
                        // 7.6.2 Unary minus operator
                        //
-                       predefined_operators [(int) Operator.UnaryNegation] = new Type [] {
+                       predefined_operators [(int) Operator.UnaryNegation] = new TypeSpec [] {
                                TypeManager.int32_type, 
                                TypeManager.int64_type,
                                TypeManager.float_type, TypeManager.double_type,
@@ -394,14 +388,14 @@ namespace Mono.CSharp {
                        //
                        // 7.6.3 Logical negation operator
                        //
-                       predefined_operators [(int) Operator.LogicalNot] = new Type [] {
+                       predefined_operators [(int) Operator.LogicalNot] = new TypeSpec [] {
                                TypeManager.bool_type
                        };
 
                        //
                        // 7.6.4 Bitwise complement operator
                        //
-                       predefined_operators [(int) Operator.OnesComplement] = new Type [] {
+                       predefined_operators [(int) Operator.OnesComplement] = new TypeSpec [] {
                                TypeManager.int32_type, TypeManager.uint32_type,
                                TypeManager.int64_type, TypeManager.uint64_type
                        };
@@ -412,7 +406,7 @@ namespace Mono.CSharp {
                //
                static Expression DoNumericPromotion (Operator op, Expression expr)
                {
-                       Type expr_type = expr.Type;
+                       TypeSpec expr_type = expr.Type;
                        if ((op == Operator.UnaryPlus || op == Operator.UnaryNegation || op == Operator.OnesComplement) &&
                                expr_type == TypeManager.byte_type || expr_type == TypeManager.sbyte_type ||
                                expr_type == TypeManager.short_type || expr_type == TypeManager.ushort_type ||
@@ -435,7 +429,7 @@ namespace Mono.CSharp {
                        if (Expr == null)
                                return null;
 
-                       if (TypeManager.IsDynamicType (Expr.Type)) {
+                       if (Expr.Type == InternalType.Dynamic) {
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (Expr));
                                return new DynamicUnaryConversion (GetOperatorExpressionTypeName (), args, loc).Resolve (ec);
@@ -477,10 +471,8 @@ namespace Mono.CSharp {
                        EmitOperator (ec, type);
                }
 
-               protected void EmitOperator (EmitContext ec, Type type)
+               protected void EmitOperator (EmitContext ec, TypeSpec type)
                {
-                       ILGenerator ig = ec.ig;
-
                        switch (Oper) {
                        case Operator.UnaryPlus:
                                Expr.Emit (ec);
@@ -488,27 +480,27 @@ namespace Mono.CSharp {
                                
                        case Operator.UnaryNegation:
                                if (ec.HasSet (EmitContext.Options.CheckedScope) && !IsFloat (type)) {
-                                       ig.Emit (OpCodes.Ldc_I4_0);
+                                       ec.Emit (OpCodes.Ldc_I4_0);
                                        if (type == TypeManager.int64_type)
-                                               ig.Emit (OpCodes.Conv_U8);
+                                               ec.Emit (OpCodes.Conv_U8);
                                        Expr.Emit (ec);
-                                       ig.Emit (OpCodes.Sub_Ovf);
+                                       ec.Emit (OpCodes.Sub_Ovf);
                                } else {
                                        Expr.Emit (ec);
-                                       ig.Emit (OpCodes.Neg);
+                                       ec.Emit (OpCodes.Neg);
                                }
                                
                                break;
                                
                        case Operator.LogicalNot:
                                Expr.Emit (ec);
-                               ig.Emit (OpCodes.Ldc_I4_0);
-                               ig.Emit (OpCodes.Ceq);
+                               ec.Emit (OpCodes.Ldc_I4_0);
+                               ec.Emit (OpCodes.Ceq);
                                break;
                                
                        case Operator.OnesComplement:
                                Expr.Emit (ec);
-                               ig.Emit (OpCodes.Not);
+                               ec.Emit (OpCodes.Not);
                                break;
                                
                        case Operator.AddressOf:
@@ -540,7 +532,7 @@ namespace Mono.CSharp {
                        Expr.EmitSideEffect (ec);
                }
 
-               public static void Error_OperatorCannotBeApplied (ResolveContext ec, Location loc, string oper, Type t)
+               public static void Error_OperatorCannotBeApplied (ResolveContext ec, Location loc, string oper, TypeSpec t)
                {
                        ec.Report.Error (23, loc, "The `{0}' operator cannot be applied to operand of type `{1}'",
                                oper, TypeManager.CSharpName (t));
@@ -565,7 +557,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               static bool IsFloat (Type t)
+               static bool IsFloat (TypeSpec t)
                {
                        return t == TypeManager.float_type || t == TypeManager.double_type;
                }
@@ -610,10 +602,9 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               public static void Reset ()
                {
-                       type = storey.MutateType (type);
-                       Expr.MutateHoistedGenericType (storey);
+                       predefined_operators = null;
                }
 
                Expression ResolveAddressOf (ResolveContext ec)
@@ -660,7 +651,7 @@ namespace Mono.CSharp {
                                ec.Report.Error (212, loc, "You can only take the address of unfixed expression inside of a fixed statement initializer");
                        }
 
-                       type = TypeManager.GetPointerType (Expr.Type);
+                       type = PointerContainer.MakeType (Expr.Type);
                        eclass = ExprClass.Value;
                        return this;
                }
@@ -668,9 +659,9 @@ namespace Mono.CSharp {
                Expression ResolvePrimitivePredefinedType (Expression expr)
                {
                        expr = DoNumericPromotion (Oper, expr);
-                       Type expr_type = expr.Type;
-                       Type[] predefined = predefined_operators [(int) Oper];
-                       foreach (Type t in predefined) {
+                       TypeSpec expr_type = expr.Type;
+                       TypeSpec[] predefined = predefined_operators [(int) Oper];
+                       foreach (TypeSpec t in predefined) {
                                if (t == expr_type)
                                        return expr;
                        }
@@ -697,7 +688,7 @@ namespace Mono.CSharp {
                        }
 
                        string op_name = CSharp.Operator.GetMetadataName (op_type);
-                       MethodGroupExpr user_op = MemberLookup (ec.Compiler, ec.CurrentType, expr.Type, op_name, MemberTypes.Method, AllBindingFlags, expr.Location) as MethodGroupExpr;
+                       MethodGroupExpr user_op = MethodLookup (ec.Compiler, ec.CurrentType, expr.Type, MemberKind.Operator, op_name, 0, expr.Location);
                        if (user_op == null)
                                return null;
 
@@ -721,8 +712,8 @@ namespace Mono.CSharp {
                        if (best_expr != null)
                                return best_expr;
 
-                       Type[] predefined = predefined_operators [(int) Oper];
-                       foreach (Type t in predefined) {
+                       TypeSpec[] predefined = predefined_operators [(int) Oper];
+                       foreach (TypeSpec t in predefined) {
                                Expression oper_expr = Convert.UserDefinedConversion (ec, expr, t, expr.Location, false, false);
                                if (oper_expr == null)
                                        continue;
@@ -809,14 +800,14 @@ namespace Mono.CSharp {
                        if (!prepared)
                                expr.Emit (ec);
                        
-                       LoadFromPtr (ec.ig, Type);
+                       ec.EmitLoadFromPtr (Type);
                }
 
                public void Emit (EmitContext ec, bool leave_copy)
                {
                        Emit (ec);
                        if (leave_copy) {
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                                temporary = new LocalTemporary (expr.Type);
                                temporary.Store (ec);
                        }
@@ -829,16 +820,16 @@ namespace Mono.CSharp {
                        expr.Emit (ec);
 
                        if (prepare_for_load)
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                        
                        source.Emit (ec);
                        if (leave_copy) {
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                                temporary = new LocalTemporary (expr.Type);
                                temporary.Store (ec);
                        }
                        
-                       StoreFromPtr (ec.ig, type);
+                       ec.EmitStoreFromPtr (type);
                        
                        if (temporary != null) {
                                temporary.Emit (ec);
@@ -1007,7 +998,7 @@ namespace Mono.CSharp {
                        if (expr == null)
                                return null;
 
-                       if (TypeManager.IsDynamicType (expr.Type)) {
+                       if (expr.Type == InternalType.Dynamic) {
                                //
                                // Handle postfix unary operators using local
                                // temporary variable
@@ -1077,7 +1068,7 @@ namespace Mono.CSharp {
                //   use pre-post incr-decr operations on it, but it is not a
                //   System.Decimal, which we require operator overloading to catch)
                //
-               static bool IsPredefinedOperator (Type t)
+               static bool IsPredefinedOperator (TypeSpec t)
                {
                        return (TypeManager.IsPrimitiveType (t) && t != TypeManager.bool_type) ||
                                TypeManager.IsEnumType (t) ||
@@ -1141,7 +1132,6 @@ namespace Mono.CSharp {
                        //
                        // Step 2: Perform Operator Overload location
                        //
-                       MethodGroupExpr mg;
                        string op_name;
 
                        if (IsDecrement)
@@ -1149,7 +1139,7 @@ namespace Mono.CSharp {
                        else
                                op_name = Operator.GetMetadataName (Operator.OpType.Increment);
 
-                       mg = MemberLookup (ec.Compiler, ec.CurrentType, type, op_name, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+                       var mg = MethodLookup (ec.Compiler, ec.CurrentType, type, MemberKind.Operator, op_name, 0, loc);
 
                        if (mg != null) {
                                Arguments args = new Arguments (1);
@@ -1209,7 +1199,7 @@ namespace Mono.CSharp {
                        if (expr == null)
                                return null;
 
-                       if ((probe_type_expr.Type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+                       if (probe_type_expr.Type.IsStatic) {
                                ec.Report.Error (-244, loc, "The `{0}' operator cannot be applied to an operand of a static type",
                                        OperatorName);
                        }
@@ -1229,12 +1219,6 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       probe_type_expr.MutateHoistedGenericType (storey);
-               }
-
                protected abstract string OperatorName { get; }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -1269,28 +1253,26 @@ namespace Mono.CSharp {
                
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
                        if (expr_unwrap != null) {
                                expr_unwrap.EmitCheck (ec);
                                return;
                        }
 
                        expr.Emit (ec);
-                       ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
-                       ig.Emit (OpCodes.Ldnull);
-                       ig.Emit (OpCodes.Cgt_Un);
+                       ec.Emit (OpCodes.Isinst, probe_type_expr.Type);
+                       ec.Emit (OpCodes.Ldnull);
+                       ec.Emit (OpCodes.Cgt_Un);
                }
 
                public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
                {
-                       ILGenerator ig = ec.ig;
                        if (expr_unwrap != null) {
                                expr_unwrap.EmitCheck (ec);
                        } else {
                                expr.Emit (ec);
-                               ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
+                               ec.Emit (OpCodes.Isinst, probe_type_expr.Type);
                        }                       
-                       ig.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+                       ec.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
                }
                
                Expression CreateConstantResult (ResolveContext ec, bool result)
@@ -1310,7 +1292,7 @@ namespace Mono.CSharp {
                        if (base.DoResolve (ec) == null)
                                return null;
 
-                       Type d = expr.Type;
+                       TypeSpec d = expr.Type;
                        bool d_is_nullable = false;
 
                        //
@@ -1320,18 +1302,24 @@ namespace Mono.CSharp {
                        if (expr.IsNull || expr.eclass == ExprClass.MethodGroup)
                                return CreateConstantResult (ec, false);
 
-                       if (TypeManager.IsNullableType (d) && !TypeManager.ContainsGenericParameters (d)) {
-                               d = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (d) [0]);
-                               d_is_nullable = true;
+                       if (TypeManager.IsNullableType (d)) {
+                               var ut = Nullable.NullableInfo.GetUnderlyingType (d);
+                               if (!ut.IsGenericParameter) {
+                                       d = ut;
+                                       d_is_nullable = true;
+                               }
                        }
 
                        type = TypeManager.bool_type;
                        eclass = ExprClass.Value;
-                       Type t = probe_type_expr.Type;
+                       TypeSpec t = probe_type_expr.Type;
                        bool t_is_nullable = false;
-                       if (TypeManager.IsNullableType (t) && !TypeManager.ContainsGenericParameters (t)) {
-                               t = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (t) [0]);
-                               t_is_nullable = true;
+                       if (TypeManager.IsNullableType (t)) {
+                               var ut = Nullable.NullableInfo.GetUnderlyingType (t);
+                               if (!ut.IsGenericParameter) {
+                                       t = ut;
+                                       t_is_nullable = true;
+                               }
                        }
 
                        if (TypeManager.IsStruct (t)) {
@@ -1350,8 +1338,9 @@ namespace Mono.CSharp {
                                        return CreateConstantResult (ec, true);
                                }
 
-                               if (TypeManager.IsGenericParameter (d))
-                                       return ResolveGenericParameter (ec, t, d);
+                               var tp = d as TypeParameterSpec;
+                               if (tp != null)
+                                       return ResolveGenericParameter (ec, t, tp);
 
                                //
                                // An unboxing conversion exists
@@ -1360,7 +1349,7 @@ namespace Mono.CSharp {
                                        return this;
                        } else {
                                if (TypeManager.IsGenericParameter (t))
-                                       return ResolveGenericParameter (ec, d, t);
+                                       return ResolveGenericParameter (ec, d, (TypeParameterSpec) t);
 
                                if (TypeManager.IsStruct (d)) {
                                        bool temp;
@@ -1368,7 +1357,7 @@ namespace Mono.CSharp {
                                                return CreateConstantResult (ec, true);
                                } else {
                                        if (TypeManager.IsGenericParameter (d))
-                                               return ResolveGenericParameter (ec, t, d);
+                                               return ResolveGenericParameter (ec, t, (TypeParameterSpec) d);
 
                                        if (TypeManager.ContainsGenericParameters (d))
                                                return this;
@@ -1383,16 +1372,15 @@ namespace Mono.CSharp {
                        return CreateConstantResult (ec, false);
                }
 
-               Expression ResolveGenericParameter (ResolveContext ec, Type d, Type t)
+               Expression ResolveGenericParameter (ResolveContext ec, TypeSpec d, TypeParameterSpec t)
                {
-                       GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
-                       if (constraints != null) {
-                               if (constraints.IsReferenceType && TypeManager.IsStruct (d))
+                       if (t.IsReferenceType) {
+                               if (TypeManager.IsStruct (d))
                                        return CreateConstantResult (ec, false);
                        }
 
                        if (TypeManager.IsGenericParameter (expr.Type)) {
-                               if (constraints != null && constraints.IsValueType && expr.Type == t)
+                               if (t.IsValueType && expr.Type == t)
                                        return CreateConstantResult (ec, true);
 
                                expr = new BoxedCast (expr, d);
@@ -1429,15 +1417,13 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        expr.Emit (ec);
 
                        if (do_isinst)
-                               ig.Emit (OpCodes.Isinst, type);
+                               ec.Emit (OpCodes.Isinst, type);
 
                        if (TypeManager.IsGenericParameter (type) || TypeManager.IsNullableType (type))
-                               ig.Emit (OpCodes.Unbox_Any, type);
+                               ec.Emit (OpCodes.Unbox_Any, type);
                }
 
                protected override Expression DoResolve (ResolveContext ec)
@@ -1451,7 +1437,7 @@ namespace Mono.CSharp {
 
                        type = probe_type_expr.Type;
                        eclass = ExprClass.Value;
-                       Type etype = expr.Type;
+                       TypeSpec etype = expr.Type;
 
                        if (!TypeManager.IsReferenceType (type) && !TypeManager.IsNullableType (type)) {
                                if (TypeManager.IsGenericParameter (type)) {
@@ -1501,12 +1487,6 @@ namespace Mono.CSharp {
                protected override string OperatorName {
                        get { return "as"; }
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-                       base.MutateHoistedGenericType (storey);
-               }
        }
        
        /// <summary>
@@ -1546,7 +1526,7 @@ namespace Mono.CSharp {
 
                        type = target.Type;
 
-                       if (type.IsAbstract && type.IsSealed) {
+                       if (type.IsStatic) {
                                ec.Report.Error (716, loc, "Cannot convert to static type `{0}'", TypeManager.CSharpName (type));
                                return null;
                        }
@@ -1562,7 +1542,7 @@ namespace Mono.CSharp {
 
                        if (type.IsPointer && !ec.IsUnsafe) {
                                UnsafeError (ec, loc);
-                       } else if (TypeManager.IsDynamicType (expr.Type)) {
+                       } else if (expr.Type == InternalType.Dynamic) {
                                Arguments arg = new Arguments (1);
                                arg.Add (new Argument (expr));
                                return new DynamicConversion (type, CSharpBinderFlags.ConvertExplicit, arg, loc).Resolve (ec);
@@ -1585,7 +1565,7 @@ namespace Mono.CSharp {
        {
                bool arrayAccess;
 
-               public ImplicitCast (Expression expr, Type target, bool arrayAccess)
+               public ImplicitCast (Expression expr, TypeSpec target, bool arrayAccess)
                        : base (expr)
                {
                        this.loc = expr.Location;
@@ -1637,7 +1617,7 @@ namespace Mono.CSharp {
 
                        type = texpr.Type;
 
-                       if ((type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+                       if (type.IsStatic) {
                                ec.Report.Error (-244, loc, "The `default value' operator cannot be applied to an operand of a static type");
                        }
 
@@ -1660,15 +1640,10 @@ namespace Mono.CSharp {
                        LocalTemporary temp_storage = new LocalTemporary(type);
 
                        temp_storage.AddressOf(ec, AddressOp.LoadStore);
-                       ec.ig.Emit(OpCodes.Initobj, type);
+                       ec.Emit(OpCodes.Initobj, type);
                        temp_storage.Emit(ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-               }
-               
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        DefaultValueExpression target = (DefaultValueExpression) t;
@@ -1683,27 +1658,27 @@ namespace Mono.CSharp {
        public class Binary : Expression, IDynamicBinder
        {
                protected class PredefinedOperator {
-                       protected readonly Type left;
-                       protected readonly Type right;
+                       protected readonly TypeSpec left;
+                       protected readonly TypeSpec right;
                        public readonly Operator OperatorsMask;
-                       public Type ReturnType;
+                       public TypeSpec ReturnType;
 
-                       public PredefinedOperator (Type ltype, Type rtype, Operator op_mask)
+                       public PredefinedOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask)
                                : this (ltype, rtype, op_mask, ltype)
                        {
                        }
 
-                       public PredefinedOperator (Type type, Operator op_mask, Type return_type)
+                       public PredefinedOperator (TypeSpec type, Operator op_mask, TypeSpec return_type)
                                : this (type, type, op_mask, return_type)
                        {
                        }
 
-                       public PredefinedOperator (Type type, Operator op_mask)
+                       public PredefinedOperator (TypeSpec type, Operator op_mask)
                                : this (type, type, op_mask, type)
                        {
                        }
 
-                       public PredefinedOperator (Type ltype, Type rtype, Operator op_mask, Type return_type)
+                       public PredefinedOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask, TypeSpec return_type)
                        {
                                if ((op_mask & Operator.ValuesOnlyMask) != 0)
                                        throw new InternalErrorException ("Only masked values can be used");
@@ -1750,7 +1725,7 @@ namespace Mono.CSharp {
                                return b;
                        }
 
-                       public bool IsPrimitiveApplicable (Type ltype, Type rtype)
+                       public bool IsPrimitiveApplicable (TypeSpec ltype, TypeSpec rtype)
                        {
                                //
                                // We are dealing with primitive types only
@@ -1790,13 +1765,13 @@ namespace Mono.CSharp {
                }
 
                class PredefinedStringOperator : PredefinedOperator {
-                       public PredefinedStringOperator (Type type, Operator op_mask)
+                       public PredefinedStringOperator (TypeSpec type, Operator op_mask)
                                : base (type, op_mask, type)
                        {
                                ReturnType = TypeManager.string_type;
                        }
 
-                       public PredefinedStringOperator (Type ltype, Type rtype, Operator op_mask)
+                       public PredefinedStringOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask)
                                : base (ltype, rtype, op_mask)
                        {
                                ReturnType = TypeManager.string_type;
@@ -1826,7 +1801,7 @@ namespace Mono.CSharp {
                }
 
                class PredefinedShiftOperator : PredefinedOperator {
-                       public PredefinedShiftOperator (Type ltype, Operator op_mask) :
+                       public PredefinedShiftOperator (TypeSpec ltype, Operator op_mask) :
                                base (ltype, TypeManager.int32_type, op_mask)
                        {
                        }
@@ -1863,17 +1838,17 @@ namespace Mono.CSharp {
                }
 
                class PredefinedPointerOperator : PredefinedOperator {
-                       public PredefinedPointerOperator (Type ltype, Type rtype, Operator op_mask)
+                       public PredefinedPointerOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask)
                                : base (ltype, rtype, op_mask)
                        {
                        }
 
-                       public PredefinedPointerOperator (Type ltype, Type rtype, Operator op_mask, Type retType)
+                       public PredefinedPointerOperator (TypeSpec ltype, TypeSpec rtype, Operator op_mask, TypeSpec retType)
                                : base (ltype, rtype, op_mask, retType)
                        {
                        }
 
-                       public PredefinedPointerOperator (Type type, Operator op_mask, Type return_type)
+                       public PredefinedPointerOperator (TypeSpec type, Operator op_mask, TypeSpec return_type)
                                : base (type, op_mask, return_type)
                        {
                        }
@@ -1907,7 +1882,7 @@ namespace Mono.CSharp {
                                        b.right = EmptyCast.Create (b.right, right);
                                }
 
-                               Type r_type = ReturnType;
+                               TypeSpec r_type = ReturnType;
                                Expression left_arg, right_arg;
                                if (r_type == null) {
                                        if (left == null) {
@@ -1973,8 +1948,8 @@ namespace Mono.CSharp {
                readonly bool is_compound;
                Expression enum_conversion;
 
-               static PredefinedOperator [] standard_operators;
-               static PredefinedOperator [] pointer_operators;
+               static PredefinedOperator[] standard_operators;
+               static PredefinedOperator[] pointer_operators;
                
                public Binary (Operator oper, Expression left, Expression right, bool isCompound, Location loc)
                        : this (oper, left, right, loc)
@@ -2178,10 +2153,9 @@ namespace Mono.CSharp {
                        return CSharp.Operator.GetMetadataName (op_type);
                }
 
-               public static void EmitOperatorOpcode (EmitContext ec, Operator oper, Type l)
+               public static void EmitOperatorOpcode (EmitContext ec, Operator oper, TypeSpec l)
                {
                        OpCode opcode;
-                       ILGenerator ig = ec.ig;
 
                        switch (oper){
                        case Operator.Multiply:
@@ -2251,8 +2225,8 @@ namespace Mono.CSharp {
                                break;
 
                        case Operator.Inequality:
-                               ig.Emit (OpCodes.Ceq);
-                               ig.Emit (OpCodes.Ldc_I4_0);
+                               ec.Emit (OpCodes.Ceq);
+                               ec.Emit (OpCodes.Ldc_I4_0);
                                
                                opcode = OpCodes.Ceq;
                                break;
@@ -2273,21 +2247,21 @@ namespace Mono.CSharp {
 
                        case Operator.LessThanOrEqual:
                                if (IsUnsigned (l) || IsFloat (l))
-                                       ig.Emit (OpCodes.Cgt_Un);
+                                       ec.Emit (OpCodes.Cgt_Un);
                                else
-                                       ig.Emit (OpCodes.Cgt);
-                               ig.Emit (OpCodes.Ldc_I4_0);
+                                       ec.Emit (OpCodes.Cgt);
+                               ec.Emit (OpCodes.Ldc_I4_0);
                                
                                opcode = OpCodes.Ceq;
                                break;
 
                        case Operator.GreaterThanOrEqual:
                                if (IsUnsigned (l) || IsFloat (l))
-                                       ig.Emit (OpCodes.Clt_Un);
+                                       ec.Emit (OpCodes.Clt_Un);
                                else
-                                       ig.Emit (OpCodes.Clt);
+                                       ec.Emit (OpCodes.Clt);
                                
-                               ig.Emit (OpCodes.Ldc_I4_0);
+                               ec.Emit (OpCodes.Ldc_I4_0);
                                
                                opcode = OpCodes.Ceq;
                                break;
@@ -2308,10 +2282,10 @@ namespace Mono.CSharp {
                                throw new InternalErrorException (oper.ToString ());
                        }
 
-                       ig.Emit (opcode);
+                       ec.Emit (opcode);
                }
 
-               static bool IsUnsigned (Type t)
+               static bool IsUnsigned (TypeSpec t)
                {
                        if (t.IsPointer)
                                return true;
@@ -2320,15 +2294,20 @@ namespace Mono.CSharp {
                                t == TypeManager.ushort_type || t == TypeManager.byte_type);
                }
 
-               static bool IsFloat (Type t)
+               static bool IsFloat (TypeSpec t)
                {
                        return t == TypeManager.float_type || t == TypeManager.double_type;
                }
 
+               public static void Reset ()
+               {
+                       pointer_operators = standard_operators = null;
+               }
+
                Expression ResolveOperator (ResolveContext ec)
                {
-                       Type l = left.Type;
-                       Type r = right.Type;
+                       TypeSpec l = left.Type;
+                       TypeSpec r = right.Type;
                        Expression expr;
                        bool primitives_only = false;
 
@@ -2493,7 +2472,7 @@ namespace Mono.CSharp {
                static void CreateStandardOperatorsTable ()
                {
                        var temp = new List<PredefinedOperator> ();
-                       Type bool_type = TypeManager.bool_type;
+                       TypeSpec bool_type = TypeManager.bool_type;
 
                        temp.Add (new PredefinedOperator (TypeManager.int32_type, Operator.ArithmeticMask | Operator.BitwiseMask));
                        temp.Add (new PredefinedOperator (TypeManager.uint32_type, Operator.ArithmeticMask | Operator.BitwiseMask));
@@ -2531,10 +2510,10 @@ namespace Mono.CSharp {
                //
                // Rules used during binary numeric promotion
                //
-               static bool DoNumericPromotion (ResolveContext rc, ref Expression prim_expr, ref Expression second_expr, Type type)
+               static bool DoNumericPromotion (ResolveContext rc, ref Expression prim_expr, ref Expression second_expr, TypeSpec type)
                {
                        Expression temp;
-                       Type etype;
+                       TypeSpec etype;
 
                        Constant c = prim_expr as Constant;
                        if (c != null) {
@@ -2583,11 +2562,11 @@ namespace Mono.CSharp {
                //
                public bool DoBinaryOperatorPromotion (ResolveContext ec)
                {
-                       Type ltype = left.Type;
-                       Type rtype = right.Type;
+                       TypeSpec ltype = left.Type;
+                       TypeSpec rtype = right.Type;
                        Expression temp;
 
-                       foreach (Type t in ConstantFold.binary_promotions) {
+                       foreach (TypeSpec t in ConstantFold.BinaryPromotionsTypes) {
                                if (t == ltype)
                                        return t == rtype || DoNumericPromotion (ec, ref right, ref left, t);
 
@@ -2595,7 +2574,7 @@ namespace Mono.CSharp {
                                        return t == ltype || DoNumericPromotion (ec, ref left, ref right, t);
                        }
 
-                       Type int32 = TypeManager.int32_type;
+                       TypeSpec int32 = TypeManager.int32_type;
                        if (ltype != int32) {
                                Constant c = left as Constant;
                                if (c != null)
@@ -2690,7 +2669,7 @@ namespace Mono.CSharp {
                                CheckUselessComparison (ec, rc, left.Type);
                        }
 
-                       if (TypeManager.IsDynamicType (left.Type) || TypeManager.IsDynamicType (right.Type)) {
+                       if (left.Type == InternalType.Dynamic || right.Type == InternalType.Dynamic) {
                                Arguments args = new Arguments (2);
                                args.Add (new Argument (left));
                                args.Add (new Argument (right));
@@ -2770,22 +2749,16 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       left.MutateHoistedGenericType (storey);
-                       right.MutateHoistedGenericType (storey);
-               }
-
                //
                // D operator + (D x, D y)
                // D operator - (D x, D y)
                // bool operator == (D x, D y)
                // bool operator != (D x, D y)
                //
-               Expression ResolveOperatorDelegate (ResolveContext ec, Type l, Type r)
+               Expression ResolveOperatorDelegate (ResolveContext ec, TypeSpec l, TypeSpec r)
                {
                        bool is_equality = (oper & Operator.EqualityMask) != 0;
-                       if (!TypeManager.IsEqual (l, r) && !TypeManager.IsVariantOf (r, l)) {
+                       if (!TypeManager.IsEqual (l, r) && !TypeSpecComparer.Variant.IsEqual (r, l)) {
                                Expression tmp;
                                if (right.eclass == ExprClass.MethodGroup || (r == InternalType.AnonymousMethod && !is_equality)) {
                                        tmp = Convert.ImplicitConversionRequired (ec, right, l, loc);
@@ -2831,7 +2804,10 @@ namespace Mono.CSharp {
                                method = TypeManager.delegate_remove_delegate_delegate;
                        }
 
-                       MethodGroupExpr mg = new MethodGroupExpr (new [] { method }, TypeManager.delegate_type, loc);
+                       if (method == null)
+                               return new EmptyExpression (TypeManager.decimal_type);
+
+                       MethodGroupExpr mg = new MethodGroupExpr (method, TypeManager.delegate_type, loc);
                        mg = mg.OverloadResolve (ec, ref args, false, loc);
 
                        return new ClassCast (new UserOperatorCall (mg, args, CreateExpressionTree, loc), l);
@@ -2840,7 +2816,7 @@ namespace Mono.CSharp {
                //
                // Enumeration operators
                //
-               Expression ResolveOperatorEnum (ResolveContext ec, bool lenum, bool renum, Type ltype, Type rtype)
+               Expression ResolveOperatorEnum (ResolveContext ec, bool lenum, bool renum, TypeSpec ltype, TypeSpec rtype)
                {
                        //
                        // bool operator == (E x, E y);
@@ -2867,7 +2843,7 @@ namespace Mono.CSharp {
 
                        Expression ltemp = left;
                        Expression rtemp = right;
-                       Type underlying_type;
+                       TypeSpec underlying_type;
                        Expression expr;
                        
                        if ((oper & (Operator.ComparisonMask | Operator.BitwiseMask)) != 0) {
@@ -2887,7 +2863,7 @@ namespace Mono.CSharp {
                        }                       
 
                        if (TypeManager.IsEqual (ltype, rtype)) {
-                               underlying_type = TypeManager.GetEnumUnderlyingType (ltype);
+                               underlying_type = EnumSpec.GetUnderlyingType (ltype);
 
                                if (left is Constant)
                                        left = ((Constant) left).ConvertExplicitly (false, underlying_type).Resolve (ec);
@@ -2899,7 +2875,7 @@ namespace Mono.CSharp {
                                else
                                        right = EmptyCast.Create (right, underlying_type);
                        } else if (lenum) {
-                               underlying_type = TypeManager.GetEnumUnderlyingType (ltype);
+                               underlying_type = EnumSpec.GetUnderlyingType (ltype);
 
                                if (oper != Operator.Subtraction && oper != Operator.Addition) {
                                        Constant c = right as Constant;
@@ -2918,7 +2894,7 @@ namespace Mono.CSharp {
                                        left = EmptyCast.Create (left, underlying_type);
 
                        } else if (renum) {
-                               underlying_type = TypeManager.GetEnumUnderlyingType (rtype);
+                               underlying_type = EnumSpec.GetUnderlyingType (rtype);
 
                                if (oper != Operator.Addition) {
                                        Constant c = left as Constant;
@@ -2950,9 +2926,9 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       Type res_type = null;
+                       TypeSpec res_type = null;
                        if ((oper & Operator.BitwiseMask) != 0 || oper == Operator.Subtraction || oper == Operator.Addition) {
-                               Type promoted_type = lenum ? left.Type : right.Type;
+                               TypeSpec promoted_type = lenum ? left.Type : right.Type;
                                enum_conversion = Convert.ExplicitNumericConversion (
                                        new EmptyExpression (promoted_type), underlying_type);
 
@@ -2997,7 +2973,7 @@ namespace Mono.CSharp {
                //
                // 7.9.6 Reference type equality operators
                //
-               Binary ResolveOperatorEqualityRerefence (ResolveContext ec, Type l, Type r)
+               Binary ResolveOperatorEqualityRerefence (ResolveContext ec, TypeSpec l, TypeSpec r)
                {
                        //
                        // operator != (object a, object b)
@@ -3010,12 +2986,14 @@ namespace Mono.CSharp {
                                return null;
 
                        type = TypeManager.bool_type;
-                       GenericConstraints constraints;
 
-                       bool lgen = TypeManager.IsGenericParameter (l);
+                       var lgen = l as TypeParameterSpec;
+
+                       if (l == r) {
+                               if (l is InternalType)
+                                       return null;
 
-                       if (TypeManager.IsEqual (l, r)) {
-                               if (lgen) {
+                               if (lgen != null) {
                                        //
                                        // Only allow to compare same reference type parameter
                                        //
@@ -3028,16 +3006,13 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               if (l == InternalType.AnonymousMethod)
-                                       return null;
-
                                if (TypeManager.IsValueType (l))
                                        return null;
 
                                return this;
                        }
 
-                       bool rgen = TypeManager.IsGenericParameter (r);
+                       var rgen = r as TypeParameterSpec;
 
                        //
                        // a, Both operands are reference-type values or the value null
@@ -3046,18 +3021,16 @@ namespace Mono.CSharp {
                        // value type constrain
                        //
                        if (left is NullLiteral || right is NullLiteral) {
-                               if (lgen) {
-                                       constraints = TypeManager.GetTypeParameterConstraints (l);
-                                       if (constraints != null && constraints.HasValueTypeConstraint)
+                               if (lgen != null) {
+                                       if (lgen.HasSpecialStruct)
                                                return null;
 
                                        left = new BoxedCast (left, TypeManager.object_type);
                                        return this;
                                }
 
-                               if (rgen) {
-                                       constraints = TypeManager.GetTypeParameterConstraints (r);
-                                       if (constraints != null && constraints.HasValueTypeConstraint)
+                               if (rgen != null) {
+                                       if (rgen.HasSpecialStruct)
                                                return null;
 
                                        right = new BoxedCast (right, TypeManager.object_type);
@@ -3070,7 +3043,7 @@ namespace Mono.CSharp {
                        // standard conversion is applied. It's not clear from the
                        // standard but it looks like it works like that.
                        //
-                       if (lgen) {
+                       if (lgen != null) {
                                if (!TypeManager.IsReferenceType (l))
                                        return null;
 
@@ -3082,7 +3055,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (rgen) {
+                       if (rgen != null) {
                                if (!TypeManager.IsReferenceType (r))
                                        return null;
 
@@ -3120,7 +3093,7 @@ namespace Mono.CSharp {
                }
 
 
-               Expression ResolveOperatorPointer (ResolveContext ec, Type l, Type r)
+               Expression ResolveOperatorPointer (ResolveContext ec, TypeSpec l, TypeSpec r)
                {
                        //
                        // bool operator == (void* x, void* y);
@@ -3159,11 +3132,11 @@ namespace Mono.CSharp {
                //
                // Build-in operators method overloading
                //
-               protected virtual Expression ResolveOperatorPredefined (ResolveContext ec, PredefinedOperator [] operators, bool primitives_only, Type enum_type)
+               protected virtual Expression ResolveOperatorPredefined (ResolveContext ec, PredefinedOperator [] operators, bool primitives_only, TypeSpec enum_type)
                {
                        PredefinedOperator best_operator = null;
-                       Type l = left.Type;
-                       Type r = right.Type;
+                       TypeSpec l = left.Type;
+                       TypeSpec r = right.Type;
                        Operator oper_mask = oper & ~Operator.ValuesOnlyMask;
 
                        foreach (PredefinedOperator po in operators) {
@@ -3233,7 +3206,7 @@ namespace Mono.CSharp {
                //
                // Performs user-operator overloading
                //
-               protected virtual Expression ResolveUserOperator (ResolveContext ec, Type l, Type r)
+               protected virtual Expression ResolveUserOperator (ResolveContext ec, TypeSpec l, TypeSpec r)
                {
                        Operator user_oper;
                        if (oper == Operator.LogicalAnd)
@@ -3245,11 +3218,11 @@ namespace Mono.CSharp {
 
                        string op = GetOperatorMetadataName (user_oper);
 
-                       MethodGroupExpr left_operators = MemberLookup (ec.Compiler, ec.CurrentType, l, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+                       MethodGroupExpr left_operators = MethodLookup (ec.Compiler, ec.CurrentType, l, MemberKind.Operator, op, 0, loc);
                        MethodGroupExpr right_operators = null;
 
                        if (!TypeManager.IsEqual (r, l)) {
-                               right_operators = MemberLookup (ec.Compiler, ec.CurrentType, r, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+                               right_operators = MethodLookup (ec.Compiler, ec.CurrentType, r, MemberKind.Operator, op, 0, loc);
                                if (right_operators == null && left_operators == null)
                                        return null;
                        } else if (left_operators == null) {
@@ -3331,7 +3304,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               private void CheckUselessComparison (ResolveContext ec, Constant c, Type type)
+               private void CheckUselessComparison (ResolveContext ec, Constant c, TypeSpec type)
                {
                        if (c == null || !IsTypeIntegral (type)
                                || c is StringConstant
@@ -3384,7 +3357,7 @@ namespace Mono.CSharp {
                                WarnUselessComparison (ec, type);
                }
 
-               static bool IsValueOutOfRange (long value, Type type)
+               static bool IsValueOutOfRange (long value, TypeSpec type)
                {
                        if (IsTypeUnsigned (type) && value < 0)
                                return true;
@@ -3396,13 +3369,13 @@ namespace Mono.CSharp {
                                type == TypeManager.uint32_type && value >= 0x100000000;
                }
 
-               static bool IsBuildInEqualityOperator (Type t)
+               static bool IsBuildInEqualityOperator (TypeSpec t)
                {
                        return t == TypeManager.object_type || t == TypeManager.string_type ||
                                t == TypeManager.delegate_type || TypeManager.IsDelegateType (t);
                }
 
-               static bool IsPredefinedUserOperator (Type t, Operator op)
+               static bool IsPredefinedUserOperator (TypeSpec t, Operator op)
                {
                        //
                        // Some predefined types have user operators
@@ -3410,7 +3383,7 @@ namespace Mono.CSharp {
                        return (op & Operator.EqualityMask) != 0 && (t == TypeManager.string_type || t == TypeManager.decimal_type);
                }
 
-               private static bool IsTypeIntegral (Type type)
+               private static bool IsTypeIntegral (TypeSpec type)
                {
                        return type == TypeManager.uint64_type ||
                                type == TypeManager.int64_type ||
@@ -3423,7 +3396,7 @@ namespace Mono.CSharp {
                                type == TypeManager.char_type;
                }
 
-               private static bool IsTypeUnsigned (Type type)
+               private static bool IsTypeUnsigned (TypeSpec type)
                {
                        return type == TypeManager.uint64_type ||
                                type == TypeManager.uint32_type ||
@@ -3432,7 +3405,7 @@ namespace Mono.CSharp {
                                type == TypeManager.char_type;
                }
 
-               private void WarnUselessComparison (ResolveContext ec, Type type)
+               private void WarnUselessComparison (ResolveContext ec, TypeSpec type)
                {
                        ec.Report.Warning (652, 2, loc, "A comparison between a constant and a variable is useless. The constant is out of the range of the variable type `{0}'",
                                TypeManager.CSharpName (type));
@@ -3448,8 +3421,6 @@ namespace Mono.CSharp {
                /// </remarks>
                public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
                {
-                       ILGenerator ig = ec.ig;
-
                        //
                        // This is more complicated than it looks, but its just to avoid
                        // duplicated tests: basically, we allow ==, !=, >, <, >= and <=
@@ -3481,11 +3452,11 @@ namespace Mono.CSharp {
                        } else if (oper == Operator.LogicalAnd) {
 
                                if (on_true) {
-                                       Label tests_end = ig.DefineLabel ();
+                                       Label tests_end = ec.DefineLabel ();
                                        
                                        left.EmitBranchable (ec, tests_end, false);
                                        right.EmitBranchable (ec, target, true);
-                                       ig.MarkLabel (tests_end);                                       
+                                       ec.MarkLabel (tests_end);                                       
                                } else {
                                        //
                                        // This optimizes code like this 
@@ -3506,10 +3477,10 @@ namespace Mono.CSharp {
                                        right.EmitBranchable (ec, target, true);
                                        
                                } else {
-                                       Label tests_end = ig.DefineLabel ();
+                                       Label tests_end = ec.DefineLabel ();
                                        left.EmitBranchable (ec, tests_end, true);
                                        right.EmitBranchable (ec, target, false);
-                                       ig.MarkLabel (tests_end);
+                                       ec.MarkLabel (tests_end);
                                }
                                
                                return;
@@ -3524,76 +3495,76 @@ namespace Mono.CSharp {
                        left.Emit (ec);
                        right.Emit (ec);
 
-                       Type t = left.Type;
+                       TypeSpec t = left.Type;
                        bool is_float = IsFloat (t);
                        bool is_unsigned = is_float || IsUnsigned (t);
                        
                        switch (oper){
                        case Operator.Equality:
                                if (on_true)
-                                       ig.Emit (OpCodes.Beq, target);
+                                       ec.Emit (OpCodes.Beq, target);
                                else
-                                       ig.Emit (OpCodes.Bne_Un, target);
+                                       ec.Emit (OpCodes.Bne_Un, target);
                                break;
 
                        case Operator.Inequality:
                                if (on_true)
-                                       ig.Emit (OpCodes.Bne_Un, target);
+                                       ec.Emit (OpCodes.Bne_Un, target);
                                else
-                                       ig.Emit (OpCodes.Beq, target);
+                                       ec.Emit (OpCodes.Beq, target);
                                break;
 
                        case Operator.LessThan:
                                if (on_true)
                                        if (is_unsigned && !is_float)
-                                               ig.Emit (OpCodes.Blt_Un, target);
+                                               ec.Emit (OpCodes.Blt_Un, target);
                                        else
-                                               ig.Emit (OpCodes.Blt, target);
+                                               ec.Emit (OpCodes.Blt, target);
                                else
                                        if (is_unsigned)
-                                               ig.Emit (OpCodes.Bge_Un, target);
+                                               ec.Emit (OpCodes.Bge_Un, target);
                                        else
-                                               ig.Emit (OpCodes.Bge, target);
+                                               ec.Emit (OpCodes.Bge, target);
                                break;
 
                        case Operator.GreaterThan:
                                if (on_true)
                                        if (is_unsigned && !is_float)
-                                               ig.Emit (OpCodes.Bgt_Un, target);
+                                               ec.Emit (OpCodes.Bgt_Un, target);
                                        else
-                                               ig.Emit (OpCodes.Bgt, target);
+                                               ec.Emit (OpCodes.Bgt, target);
                                else
                                        if (is_unsigned)
-                                               ig.Emit (OpCodes.Ble_Un, target);
+                                               ec.Emit (OpCodes.Ble_Un, target);
                                        else
-                                               ig.Emit (OpCodes.Ble, target);
+                                               ec.Emit (OpCodes.Ble, target);
                                break;
 
                        case Operator.LessThanOrEqual:
                                if (on_true)
                                        if (is_unsigned && !is_float)
-                                               ig.Emit (OpCodes.Ble_Un, target);
+                                               ec.Emit (OpCodes.Ble_Un, target);
                                        else
-                                               ig.Emit (OpCodes.Ble, target);
+                                               ec.Emit (OpCodes.Ble, target);
                                else
                                        if (is_unsigned)
-                                               ig.Emit (OpCodes.Bgt_Un, target);
+                                               ec.Emit (OpCodes.Bgt_Un, target);
                                        else
-                                               ig.Emit (OpCodes.Bgt, target);
+                                               ec.Emit (OpCodes.Bgt, target);
                                break;
 
 
                        case Operator.GreaterThanOrEqual:
                                if (on_true)
                                        if (is_unsigned && !is_float)
-                                               ig.Emit (OpCodes.Bge_Un, target);
+                                               ec.Emit (OpCodes.Bge_Un, target);
                                        else
-                                               ig.Emit (OpCodes.Bge, target);
+                                               ec.Emit (OpCodes.Bge, target);
                                else
                                        if (is_unsigned)
-                                               ig.Emit (OpCodes.Blt_Un, target);
+                                               ec.Emit (OpCodes.Blt_Un, target);
                                        else
-                                               ig.Emit (OpCodes.Blt, target);
+                                               ec.Emit (OpCodes.Blt, target);
                                break;
                        default:
                                throw new InternalErrorException (oper.ToString ());
@@ -3605,26 +3576,24 @@ namespace Mono.CSharp {
                        EmitOperator (ec, left.Type);
                }
 
-               protected virtual void EmitOperator (EmitContext ec, Type l)
+               protected virtual void EmitOperator (EmitContext ec, TypeSpec l)
                {
-                       ILGenerator ig = ec.ig;
-
                        //
                        // Handle short-circuit operators differently
                        // than the rest
                        //
                        if ((oper & Operator.LogicalMask) != 0) {
-                               Label load_result = ig.DefineLabel ();
-                               Label end = ig.DefineLabel ();
+                               Label load_result = ec.DefineLabel ();
+                               Label end = ec.DefineLabel ();
 
                                bool is_or = oper == Operator.LogicalOr;
                                left.EmitBranchable (ec, load_result, is_or);
                                right.Emit (ec);
-                               ig.Emit (OpCodes.Br_S, end);
+                               ec.Emit (OpCodes.Br_S, end);
                                
-                               ig.MarkLabel (load_result);
-                               ig.Emit (is_or ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
-                               ig.MarkLabel (end);
+                               ec.MarkLabel (load_result);
+                               ec.Emit (is_or ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
+                               ec.MarkLabel (end);
                                return;
                        }
 
@@ -3635,7 +3604,7 @@ namespace Mono.CSharp {
                                var lc = left as IntegralConstant;
                                if (lc != null && lc.IsDefaultValue) {
                                        right.Emit (ec);
-                                       ig.Emit (OpCodes.Neg);
+                                       ec.Emit (OpCodes.Neg);
                                        return;
                                }
                        }
@@ -3910,14 +3879,9 @@ namespace Mono.CSharp {
                        if (arguments.Count != 2)
                                throw new NotImplementedException ("arguments.Count != 2");
 
-                       var concat = TypeManager.string_type.GetMethod ("Concat", new[] { typeof (object), typeof (object) });
+                       var concat = typeof (string).GetMethod ("Concat", new[] { typeof (object), typeof (object) });
                        return SLE.Expression.Add (arguments[0].Expr.MakeExpression (ctx), arguments[1].Expr.MakeExpression (ctx), concat);
                }
-               
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       arguments.MutateHoistedGenericType (storey);
-               }               
        }
 
        //
@@ -3938,12 +3902,12 @@ namespace Mono.CSharp {
                protected override Expression DoResolve (ResolveContext ec)
                {
                        var method = mg.BestCandidate;
-                       type = TypeManager.TypeToCoreType (method.ReturnType);
+                       type = method.ReturnType;
                        AParametersCollection pd = method.Parameters;
                        if (!TypeManager.IsEqual (type, type) || !TypeManager.IsEqual (type, pd.Types [0]) || !TypeManager.IsEqual (type, pd.Types [1])) {
                                ec.Report.Error (217, loc,
                                        "A user-defined operator `{0}' must have parameters and return values of the same type in order to be applicable as a short circuit operator",
-                                       TypeManager.CSharpSignature (method.MetaInfo));
+                                       TypeManager.CSharpSignature (method));
                                return null;
                        }
 
@@ -3953,7 +3917,7 @@ namespace Mono.CSharp {
                        if (op_true == null || op_false == null) {
                                ec.Report.Error (218, loc,
                                        "The type `{0}' must have operator `true' and operator `false' defined when `{1}' is used as a short circuit operator",
-                                       TypeManager.CSharpName (type), TypeManager.CSharpSignature (method.MetaInfo));
+                                       TypeManager.CSharpName (type), TypeManager.CSharpSignature (method));
                                return null;
                        }
 
@@ -3964,19 +3928,18 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label end_target = ig.DefineLabel ();
+                       Label end_target = ec.DefineLabel ();
 
                        //
                        // Emit and duplicate left argument
                        //
                        arguments [0].Expr.Emit (ec);
-                       ig.Emit (OpCodes.Dup);
+                       ec.Emit (OpCodes.Dup);
                        arguments.RemoveAt (0);
 
                        oper.EmitBranchable (ec, end_target, true);
                        base.Emit (ec);
-                       ig.MarkLabel (end_target);
+                       ec.MarkLabel (end_target);
                }
        }
 
@@ -3987,7 +3950,7 @@ namespace Mono.CSharp {
                //
                // We assume that `l' is always a pointer
                //
-               public PointerArithmetic (Binary.Operator op, Expression l, Expression r, Type t, Location loc)
+               public PointerArithmetic (Binary.Operator op, Expression l, Expression r, TypeSpec t, Location loc)
                {
                        type = t;
                        this.loc = loc;
@@ -4016,11 +3979,10 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       Type op_type = left.Type;
-                       ILGenerator ig = ec.ig;
+                       TypeSpec op_type = left.Type;
                        
                        // It must be either array or fixed buffer
-                       Type element;
+                       TypeSpec element;
                        if (TypeManager.HasElementType (op_type)) {
                                element = TypeManager.GetElementType (op_type);
                        } else {
@@ -4032,7 +3994,7 @@ namespace Mono.CSharp {
                        }
 
                        int size = GetTypeSize (element);
-                       Type rtype = right.Type;
+                       TypeSpec rtype = right.Type;
                        
                        if ((op & Binary.Operator.SubtractionMask) != 0 && rtype.IsPointer){
                                //
@@ -4040,16 +4002,16 @@ namespace Mono.CSharp {
                                //
                                left.Emit (ec);
                                right.Emit (ec);
-                               ig.Emit (OpCodes.Sub);
+                               ec.Emit (OpCodes.Sub);
 
                                if (size != 1){
                                        if (size == 0)
-                                               ig.Emit (OpCodes.Sizeof, element);
+                                               ec.Emit (OpCodes.Sizeof, element);
                                        else 
-                                               IntLiteral.EmitInt (ig, size);
-                                       ig.Emit (OpCodes.Div);
+                                               ec.EmitInt (size);
+                                       ec.Emit (OpCodes.Div);
                                }
-                               ig.Emit (OpCodes.Conv_I8);
+                               ec.Emit (OpCodes.Conv_I8);
                        } else {
                                //
                                // handle + and - on (pointer op int)
@@ -4091,27 +4053,27 @@ namespace Mono.CSharp {
                                right.Emit (ec);
                                if (rtype == TypeManager.sbyte_type || rtype == TypeManager.byte_type ||
                                        rtype == TypeManager.short_type || rtype == TypeManager.ushort_type) {
-                                       ig.Emit (OpCodes.Conv_I);
+                                       ec.Emit (OpCodes.Conv_I);
                                } else if (rtype == TypeManager.uint32_type) {
-                                       ig.Emit (OpCodes.Conv_U);
+                                       ec.Emit (OpCodes.Conv_U);
                                }
 
                                if (right_const == null && size != 1){
                                        if (size == 0)
-                                               ig.Emit (OpCodes.Sizeof, element);
+                                               ec.Emit (OpCodes.Sizeof, element);
                                        else 
-                                               IntLiteral.EmitInt (ig, size);
+                                               ec.EmitInt (size);
                                        if (rtype == TypeManager.int64_type || rtype == TypeManager.uint64_type)
-                                               ig.Emit (OpCodes.Conv_I8);
+                                               ec.Emit (OpCodes.Conv_I8);
 
                                        Binary.EmitOperatorOpcode (ec, Binary.Operator.Multiply, rtype);
                                }
 
                                if (left_const == null) {
                                        if (rtype == TypeManager.int64_type)
-                                               ig.Emit (OpCodes.Conv_I);
+                                               ec.Emit (OpCodes.Conv_I);
                                        else if (rtype == TypeManager.uint64_type)
-                                               ig.Emit (OpCodes.Conv_U);
+                                               ec.Emit (OpCodes.Conv_U);
 
                                        Binary.EmitOperatorOpcode (ec, op, op_type);
                                }
@@ -4157,7 +4119,7 @@ namespace Mono.CSharp {
                        if (expr.Type == TypeManager.bool_type)
                                return expr;
 
-                       if (TypeManager.IsDynamicType (expr.Type)) {
+                       if (expr.Type == InternalType.Dynamic) {
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (expr));
                                return new DynamicUnaryConversion ("IsTrue", args, loc).Resolve (ec);
@@ -4232,8 +4194,8 @@ namespace Mono.CSharp {
                                return null;
 
                        eclass = ExprClass.Value;
-                       Type true_type = true_expr.Type;
-                       Type false_type = false_expr.Type;
+                       TypeSpec true_type = true_expr.Type;
+                       TypeSpec false_type = false_expr.Type;
                        type = true_type;
 
                        //
@@ -4275,14 +4237,6 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       true_expr.MutateHoistedGenericType (storey);
-                       false_expr.MutateHoistedGenericType (storey);
-                       type = storey.MutateType (type);
-               }
-
                public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
                {
                        return null;
@@ -4290,24 +4244,23 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label false_target = ig.DefineLabel ();
-                       Label end_target = ig.DefineLabel ();
+                       Label false_target = ec.DefineLabel ();
+                       Label end_target = ec.DefineLabel ();
 
                        expr.EmitBranchable (ec, false_target, false);
                        true_expr.Emit (ec);
 
                        if (type.IsInterface) {
                                LocalBuilder temp = ec.GetTemporaryLocal (type);
-                               ig.Emit (OpCodes.Stloc, temp);
-                               ig.Emit (OpCodes.Ldloc, temp);
+                               ec.Emit (OpCodes.Stloc, temp);
+                               ec.Emit (OpCodes.Ldloc, temp);
                                ec.FreeTemporaryLocal (temp, type);
                        }
 
-                       ig.Emit (OpCodes.Br, end_target);
-                       ig.MarkLabel (false_target);
+                       ec.Emit (OpCodes.Br, end_target);
+                       ec.MarkLabel (false_target);
                        false_expr.Emit (ec);
-                       ig.MarkLabel (end_target);
+                       ec.MarkLabel (end_target);
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -4405,11 +4358,11 @@ namespace Mono.CSharp {
                                // If we are a reference, we loaded on the stack a pointer
                                // Now lets load the real value
                                //
-                               LoadFromPtr (ec.ig, type);
+                               ec.EmitLoadFromPtr (type);
                        }
 
                        if (leave_copy) {
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
 
                                if (IsRef) {
                                        temp = new LocalTemporary (Type);
@@ -4442,7 +4395,7 @@ namespace Mono.CSharp {
                        }
 
                        if (leave_copy) {
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                                if (IsRef) {
                                        temp = new LocalTemporary (Type);
                                        temp.Store (ec);
@@ -4450,7 +4403,7 @@ namespace Mono.CSharp {
                        }
 
                        if (IsRef)
-                               StoreFromPtr (ec.ig, type);
+                               ec.EmitStoreFromPtr (type);
                        else
                                Variable.EmitAssign (ec);
 
@@ -4463,11 +4416,6 @@ namespace Mono.CSharp {
                public bool IsHoisted {
                        get { return GetHoistedVariable ((AnonymousExpression) null) != null; }
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-               }
        }
 
        /// <summary>
@@ -4872,18 +4820,18 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               static public void EmitLdArg (ILGenerator ig, int x)
+               static public void EmitLdArg (EmitContext ec, int x)
                {
                        switch (x) {
-                       case 0: ig.Emit (OpCodes.Ldarg_0); break;
-                       case 1: ig.Emit (OpCodes.Ldarg_1); break;
-                       case 2: ig.Emit (OpCodes.Ldarg_2); break;
-                       case 3: ig.Emit (OpCodes.Ldarg_3); break;
+                       case 0: ec.Emit (OpCodes.Ldarg_0); break;
+                       case 1: ec.Emit (OpCodes.Ldarg_1); break;
+                       case 2: ec.Emit (OpCodes.Ldarg_2); break;
+                       case 3: ec.Emit (OpCodes.Ldarg_3); break;
                        default:
                                if (x > byte.MaxValue)
-                                       ig.Emit (OpCodes.Ldarg, x);
+                                       ec.Emit (OpCodes.Ldarg, x);
                                else
-                                       ig.Emit (OpCodes.Ldarg_S, (byte) x);
+                                       ec.Emit (OpCodes.Ldarg_S, (byte) x);
                                break;
                        }
                }
@@ -4951,10 +4899,10 @@ namespace Mono.CSharp {
                        if (arguments != null && !arguments_resolved)
                                arguments.Resolve (ec, out dynamic_arg);
 
-                       Type expr_type = member_expr.Type;
+                       TypeSpec expr_type = member_expr.Type;
                        mg = member_expr as MethodGroupExpr;
 
-                       bool dynamic_member = TypeManager.IsDynamicType (expr_type);
+                       bool dynamic_member = expr_type == InternalType.Dynamic;
 
                        if (!dynamic_member) {
                                Expression invoke = null;
@@ -4972,7 +4920,7 @@ namespace Mono.CSharp {
                                                        return null;
                                                }
 
-                                               mg = ec.LookupExtensionMethod (me.Type, me.Name, loc);
+                                               mg = ec.LookupExtensionMethod (me.Type, me.Name, -1, loc);
                                                if (mg == null) {
                                                        ec.Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate",
                                                                member_expr.GetSignatureForError ());
@@ -4995,7 +4943,7 @@ namespace Mono.CSharp {
 
                        var method = mg.BestCandidate;
                        if (method != null) {
-                               type = TypeManager.TypeToCoreType (method.ReturnType);
+                               type = method.ReturnType;
 
                                // TODO: this is a copy of mg.ResolveMemberAccess method
                                Expression iexpr = mg.InstanceExpression;
@@ -5092,15 +5040,15 @@ namespace Mono.CSharp {
 
                public static bool IsSpecialMethodInvocation (ResolveContext ec, MethodSpec method, Location loc)
                {
-                       if (!TypeManager.IsSpecialMethod (method.MetaInfo))
+                       if (!method.IsReservedMethod)
                                return false;
 
                        if (ec.HasSet (ResolveContext.Options.InvokeSpecialName))
                                return false;
 
-                       ec.Report.SymbolRelatedToPreviousError (method.MetaInfo);
+                       ec.Report.SymbolRelatedToPreviousError (method);
                        ec.Report.Error (571, loc, "`{0}': cannot explicitly call operator or accessor",
-                               TypeManager.CSharpSignature (method.MetaInfo, true));
+                               method.GetSignatureForError ());
        
                        return true;
                }
@@ -5115,28 +5063,6 @@ namespace Mono.CSharp {
                        return list.ArgumentTypes;
                }
 
-               /// <summary>
-               /// This checks the ConditionalAttribute on the method 
-               /// </summary>
-               public static bool IsMethodExcluded (MethodSpec method, Location loc)
-               {
-                       if (method.IsConstructor)
-                               return false;
-
-                       var mb = TypeManager.DropGenericMethodArguments (method.MetaInfo);
-                       if (TypeManager.IsBeingCompiled (mb)) {
-                               IMethodData md = TypeManager.GetMethod (mb);
-                               if (md != null)
-                                       return md.IsExcluded ();
-
-                               // For some methods (generated by delegate class) GetMethod returns null
-                               // because they are not included in builder_to_method table
-                               return false;
-                       }
-
-                       return AttributeTester.IsConditionalMethodExcluded (mb, loc);
-               }
-
                /// <remarks>
                ///   is_base tells whether we want to force the use of the `call'
                ///   opcode instead of using callvirt.  Call is required to call
@@ -5170,14 +5096,14 @@ namespace Mono.CSharp {
                                             MethodSpec method, Arguments Arguments, Location loc,
                                             bool dup_args, bool omit_args)
                {
-                       ILGenerator ig = ec.ig;
                        bool struct_call = false;
                        bool this_call = false;
                        LocalTemporary this_arg = null;
 
-                       Type decl_type = method.DeclaringType;
+                       TypeSpec decl_type = method.DeclaringType;
 
-                       if (IsMethodExcluded (method, loc))
+                       // Speed up the check by not doing it on not allowed targets
+                       if (method.ReturnType == TypeManager.void_type && method.IsConditionallyExcluded (loc))
                                return;
                        
                        bool is_static = method.IsStatic;
@@ -5190,8 +5116,8 @@ namespace Mono.CSharp {
                                // If this is ourselves, push "this"
                                //
                                if (!omit_args) {
-                                       Type t = null;
-                                       Type iexpr_type = instance_expr.Type;
+                                       TypeSpec t = null;
+                                       TypeSpec iexpr_type = instance_expr.Type;
 
                                        //
                                        // Push the instance expression
@@ -5222,13 +5148,13 @@ namespace Mono.CSharp {
 
                                                        // avoid the overhead of doing this all the time.
                                                        if (dup_args)
-                                                               t = TypeManager.GetReferenceType (iexpr_type);
+                                                               t = ReferenceContainer.MakeType (iexpr_type);
                                                } else {
                                                        instance_expr.Emit (ec);
                                                        
                                                        // FIXME: should use instance_expr is IMemoryLocation + constraint.
                                                        // to help JIT to produce better code
-                                                       ig.Emit (OpCodes.Box, instance_expr.Type);
+                                                       ec.Emit (OpCodes.Box, instance_expr.Type);
                                                        t = TypeManager.object_type;
                                                }
                                        } else {
@@ -5237,7 +5163,7 @@ namespace Mono.CSharp {
                                        }
 
                                        if (dup_args) {
-                                               ig.Emit (OpCodes.Dup);
+                                               ec.Emit (OpCodes.Dup);
                                                if (Arguments != null && Arguments.Count != 0) {
                                                        this_arg = new LocalTemporary (t);
                                                        this_arg.Store (ec);
@@ -5256,12 +5182,12 @@ namespace Mono.CSharp {
                                call_op = OpCodes.Callvirt;
                                
                                if ((instance_expr != null) && (instance_expr.Type.IsGenericParameter))
-                                       ig.Emit (OpCodes.Constrained, instance_expr.Type);
+                                       ec.Emit (OpCodes.Constrained, instance_expr.Type);
                        }
 
-                       if ((method.MetaInfo.CallingConvention & CallingConventions.VarArgs) != 0) {
+                       if (method.Parameters.HasArglist) {
                                Type[] varargs_types = GetVarargsTypes (method, Arguments);
-                               ig.EmitCall (call_op, (MethodInfo) method.MetaInfo, varargs_types);
+                               ec.Emit (call_op, method, varargs_types);
                                return;
                        }
 
@@ -5271,10 +5197,7 @@ namespace Mono.CSharp {
                        // and DoFoo is not virtual, you can omit the callvirt,
                        // because you don't need the null checking behavior.
                        //
-                       if (method.IsConstructor)
-                               ig.Emit (call_op, (ConstructorInfo) method.MetaInfo);
-                       else
-                               ig.Emit (call_op, (MethodInfo) method.MetaInfo);
+                       ec.Emit (call_op, method);
                }
 
                public override void Emit (EmitContext ec)
@@ -5289,8 +5212,8 @@ namespace Mono.CSharp {
                        // 
                        // Pop the return value if there is one
                        //
-                       if (TypeManager.TypeToCoreType (type) != TypeManager.void_type)
-                               ec.ig.Emit (OpCodes.Pop);
+                       if (type != TypeManager.void_type)
+                               ec.Emit (OpCodes.Pop);
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -5311,16 +5234,7 @@ namespace Mono.CSharp {
                public static SLE.Expression MakeExpression (BuilderContext ctx, Expression instance, MethodSpec mi, Arguments args)
                {
                        var instance_expr = instance == null ? null : instance.MakeExpression (ctx);
-                       return SLE.Expression.Call (instance_expr, (MethodInfo) mi.MetaInfo, Arguments.MakeExpression (args, ctx));
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       mg.MutateHoistedGenericType (storey);
-                       type = storey.MutateType (type);
-                       if (arguments != null) {
-                               arguments.MutateHoistedGenericType (storey);
-                       }
+                       return SLE.Expression.Call (instance_expr, (MethodInfo) mi.GetMetaInfo (), Arguments.MakeExpression (args, ctx));
                }
        }
 
@@ -5339,8 +5253,6 @@ namespace Mono.CSharp {
 
                protected MethodGroupExpr method;
 
-               bool is_type_parameter;
-
                public New (Expression requested_type, Arguments arguments, Location l)
                {
                        RequestedType = requested_type;
@@ -5351,7 +5263,7 @@ namespace Mono.CSharp {
                /// <summary>
                /// Converts complex core type syntax like 'new int ()' to simple constant
                /// </summary>
-               public static Constant Constantify (Type t)
+               public static Constant Constantify (TypeSpec t)
                {
                        if (t == TypeManager.int32_type)
                                return new IntConstant (0, Location.Null);
@@ -5380,7 +5292,7 @@ namespace Mono.CSharp {
                        if (t == TypeManager.decimal_type)
                                return new DecimalConstant (0, Location.Null);
                        if (TypeManager.IsEnumType (t))
-                               return new EnumConstant (Constantify (TypeManager.GetEnumUnderlyingType (t)), t);
+                               return new EnumConstant (Constantify (EnumSpec.GetUnderlyingType (t)), t);
                        if (TypeManager.IsNullableType (t))
                                return Nullable.LiftedNull.Create (t, Location.Null);
 
@@ -5401,7 +5313,7 @@ namespace Mono.CSharp {
                        // Turn the call into:
                        // (the-interface-stated) (new class-referenced-in-coclassattribute ())
                        //
-                       Type real_class = AttributeTester.GetCoClassAttribute (type);
+                       var real_class = type.MemberDefinition.GetAttributeCoClass ();
                        if (real_class == null)
                                return null;
 
@@ -5463,37 +5375,33 @@ namespace Mono.CSharp {
                                return (new NewDelegate (type, Arguments, loc)).Resolve (ec);
                        }
 
-                       if (TypeManager.IsGenericParameter (type)) {
-                               GenericConstraints gc = TypeManager.GetTypeParameterConstraints (type);
-
-                               if ((gc == null) || (!gc.HasConstructorConstraint && !gc.IsValueType)) {
+                       var tparam = type as TypeParameterSpec;
+                       if (tparam != null) {
+                               if (!tparam.HasSpecialConstructor && !tparam.HasSpecialStruct) {
                                        ec.Report.Error (304, loc,
-                                               "Cannot create an instance of the variable type '{0}' because it doesn't have the new() constraint",
+                                               "Cannot create an instance of the variable type `{0}' because it does not have the new() constraint",
                                                TypeManager.CSharpName (type));
-                                       return null;
                                }
 
                                if ((Arguments != null) && (Arguments.Count != 0)) {
                                        ec.Report.Error (417, loc,
                                                "`{0}': cannot provide arguments when creating an instance of a variable type",
                                                TypeManager.CSharpName (type));
-                                       return null;
                                }
 
                                if (TypeManager.activator_create_instance == null) {
-                                       Type activator_type = TypeManager.CoreLookupType (ec.Compiler, "System", "Activator", MemberKind.Class, true);
+                                       TypeSpec activator_type = TypeManager.CoreLookupType (ec.Compiler, "System", "Activator", MemberKind.Class, true);
                                        if (activator_type != null) {
                                                TypeManager.activator_create_instance = TypeManager.GetPredefinedMethod (
-                                                       activator_type, "CreateInstance", loc, Type.EmptyTypes);
+                                                       activator_type, MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null), loc);
                                        }
                                }
 
-                               is_type_parameter = true;
                                eclass = ExprClass.Value;
                                return this;
                        }
 
-                       if (type.IsAbstract && type.IsSealed) {
+                       if (type.IsStatic) {
                                ec.Report.SymbolRelatedToPreviousError (type);
                                ec.Report.Error (712, loc, "Cannot create an instance of the static class `{0}'", TypeManager.CSharpName (type));
                                return null;
@@ -5522,8 +5430,8 @@ namespace Mono.CSharp {
                                return this;
 
                        // For member-lookup, treat 'new Foo (bar)' as call to 'foo.ctor (bar)', where 'foo' is of type 'Foo'.
-                       Expression ml = MemberLookupFinal (ec, type, type, ConstructorInfo.ConstructorName,
-                               MemberTypes.Constructor, AllBindingFlags | BindingFlags.DeclaredOnly, loc);
+                       Expression ml = MemberLookupFinal (ec, type, type, ConstructorInfo.ConstructorName, 0,
+                               MemberKind.Constructor, BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly, loc);
 
                        bool dynamic;
                        if (Arguments != null) {
@@ -5555,14 +5463,11 @@ namespace Mono.CSharp {
 
                bool DoEmitTypeParameter (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
+                       var ctor_factory = TypeManager.activator_create_instance.MakeGenericMethod (type);
+                       var tparam = (TypeParameterSpec) type;
 
-                       MethodInfo ci = (MethodInfo) TypeManager.activator_create_instance.MetaInfo;
-                       ci = ci.MakeGenericMethod (new Type [] { type });
-
-                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (type);
-                       if (gc.HasReferenceTypeConstraint || gc.HasClassConstraint) {
-                               ig.Emit (OpCodes.Call, ci);
+                       if (tparam.IsReferenceType) {
+                               ec.Emit (OpCodes.Call, ctor_factory);
                                return true;
                        }
 
@@ -5571,25 +5476,25 @@ namespace Mono.CSharp {
                        // you can't share LocalBuilders among ILGeneators.
                        LocalTemporary temp = new LocalTemporary (type);
 
-                       Label label_activator = ig.DefineLabel ();
-                       Label label_end = ig.DefineLabel ();
+                       Label label_activator = ec.DefineLabel ();
+                       Label label_end = ec.DefineLabel ();
 
                        temp.AddressOf (ec, AddressOp.Store);
-                       ig.Emit (OpCodes.Initobj, type);
+                       ec.Emit (OpCodes.Initobj, type);
 
                        temp.Emit (ec);
-                       ig.Emit (OpCodes.Box, type);
-                       ig.Emit (OpCodes.Brfalse, label_activator);
+                       ec.Emit (OpCodes.Box, type);
+                       ec.Emit (OpCodes.Brfalse, label_activator);
 
                        temp.AddressOf (ec, AddressOp.Store);
-                       ig.Emit (OpCodes.Initobj, type);
+                       ec.Emit (OpCodes.Initobj, type);
                        temp.Emit (ec);
-                       ig.Emit (OpCodes.Br_S, label_end);
+                       ec.Emit (OpCodes.Br_S, label_end);
 
-                       ig.MarkLabel (label_activator);
+                       ec.MarkLabel (label_activator);
 
-                       ig.Emit (OpCodes.Call, ci);
-                       ig.MarkLabel (label_end);
+                       ec.Emit (OpCodes.Call, ctor_factory);
+                       ec.MarkLabel (label_end);
                        return true;
                }
 
@@ -5623,7 +5528,6 @@ namespace Mono.CSharp {
                public virtual bool Emit (EmitContext ec, IMemoryLocation target)
                {
                        bool is_value_type = TypeManager.IsValueType (type);
-                       ILGenerator ig = ec.ig;
                        VariableReference vr = target as VariableReference;
 
                        if (target != null && is_value_type && (vr != null || method == null)) {
@@ -5637,26 +5541,20 @@ namespace Mono.CSharp {
 
                        if (is_value_type) {
                                if (method == null) {
-                                       ig.Emit (OpCodes.Initobj, type);
+                                       ec.Emit (OpCodes.Initobj, type);
                                        return false;
                                }
 
                                if (vr != null) {
-                                       ig.Emit (OpCodes.Call, (ConstructorInfo) method.BestCandidate.MetaInfo);
+                                       ec.Emit (OpCodes.Call, method.BestCandidate);
                                        return false;
                                }
                        }
                        
-                       if (is_type_parameter)
+                       if (type is TypeParameterSpec)
                                return DoEmitTypeParameter (ec);                        
 
-                       ConstructorInfo ci = (ConstructorInfo) method.BestCandidate.MetaInfo;
-#if MS_COMPATIBLE
-                       if (TypeManager.IsGenericType (type) && type.IsGenericTypeDefinition)
-                               ci = TypeBuilder.GetConstructor (type, ci);
-#endif
-
-                       ig.Emit (OpCodes.Newobj, ci);
+                       ec.Emit (OpCodes.Newobj, method.BestCandidate);
                        return true;
                }
 
@@ -5681,7 +5579,7 @@ namespace Mono.CSharp {
                        }
 
                        if (Emit (ec, v))
-                               ec.ig.Emit (OpCodes.Pop);
+                               ec.Emit (OpCodes.Pop);
                }
 
                public virtual bool HasInitializer {
@@ -5699,7 +5597,7 @@ namespace Mono.CSharp {
                {
                        LocalTemporary value_target = new LocalTemporary (type);
 
-                       if (is_type_parameter) {
+                       if (type is TypeParameterSpec) {
                                DoEmitTypeParameter (ec);
                                value_target.Store (ec);
                                value_target.AddressOf (ec, mode);
@@ -5719,12 +5617,12 @@ namespace Mono.CSharp {
                        value_target.AddressOf (ec, AddressOp.Store);
 
                        if (method == null) {
-                               ec.ig.Emit (OpCodes.Initobj, type);
+                               ec.Emit (OpCodes.Initobj, type);
                        } else {
                                if (Arguments != null)
                                        Arguments.Emit (ec);
 
-                               ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method.BestCandidate.MetaInfo);
+                               ec.Emit (OpCodes.Call, method.BestCandidate);
                        }
                        
                        value_target.AddressOf (ec, mode);
@@ -5743,19 +5641,7 @@ namespace Mono.CSharp {
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.New ((ConstructorInfo) method.BestCandidate.MetaInfo, Arguments.MakeExpression (Arguments, ctx));
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (method != null) {
-                               method.MutateHoistedGenericType (storey);
-                               if (Arguments != null) {
-                                       Arguments.MutateHoistedGenericType (storey);
-                               }
-                       }
-
-                       type = storey.MutateType (type);
+                       return SLE.Expression.New ((ConstructorInfo) method.BestCandidate.GetMetaInfo (), Arguments.MakeExpression (Arguments, ctx));
                }
        }
 
@@ -5831,7 +5717,7 @@ namespace Mono.CSharp {
                //
                protected List<Expression> arguments;
                
-               protected Type array_element_type;
+               protected TypeSpec array_element_type;
                bool expect_initializers = false;
                int num_arguments = 0;
                protected int dimensions;
@@ -5899,7 +5785,7 @@ namespace Mono.CSharp {
                                int value = (int) c.GetValue ();
                                
                                if (value != probe.Count) {
-                                       ec.Report.Error (847, loc, "An array initializer of length `{0}' was expected", value);
+                                       ec.Report.Error (847, loc, "An array initializer of length `{0}' was expected", value.ToString ());
                                        return false;
                                }
                                
@@ -6048,7 +5934,7 @@ namespace Mono.CSharp {
                                return false;
                        }
                        
-                       StringBuilder array_qualifier = new StringBuilder (rank);
+                       StringBuilder array_qualifier = new StringBuilder ();
 
                        //
                        // `In the first form allocates an array instace of the type that results
@@ -6061,6 +5947,8 @@ namespace Mono.CSharp {
                                array_qualifier.Append ("]");
                        }
 
+                       array_qualifier.Append (rank);
+
                        //
                        // Lookup the type
                        //
@@ -6071,13 +5959,14 @@ namespace Mono.CSharp {
                                return false;
 
                        type = array_type_expr.Type;
-                       if (!type.IsArray) {
+                       var ac = type as ArrayContainer;
+                       if (ac == null) {
                                ec.Report.Error (622, loc, "Can only use array initializer expressions to assign to array types. Try using a new expression instead");
                                return false;
                        }
 
-                       array_element_type = TypeManager.GetElementType (type);
-                       dimensions = type.GetArrayRank ();
+                       array_element_type = ac.Element;
+                       dimensions = ac.Rank;
 
                        return true;
                }
@@ -6109,26 +5998,6 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               MethodInfo GetArrayMethod (EmitContext ec, int arguments)
-               {
-                       ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
-
-                       Type[] arg_types = new Type[arguments];
-                       for (int i = 0; i < arguments; i++)
-                               arg_types[i] = TypeManager.int32_type;
-
-                       MethodInfo mi = mb.GetArrayMethod (type, ".ctor", CallingConventions.HasThis, null,
-                                                       arg_types);
-
-                       if (mi == null) {
-                               ec.Report.Error (-6, "New invocation: Can not find a constructor for " +
-                                                 "this argument list");
-                               return null;
-                       }
-
-                       return mi; 
-               }
-
                byte [] MakeByteBlob ()
                {
                        int factor;
@@ -6136,9 +6005,9 @@ namespace Mono.CSharp {
                        byte [] element;
                        int count = array_data.Count;
 
-                       Type element_type = array_element_type;
+                       TypeSpec element_type = array_element_type;
                        if (TypeManager.IsEnumType (element_type))
-                               element_type = TypeManager.GetEnumUnderlyingType (element_type);
+                               element_type = EnumSpec.GetUnderlyingType (element_type);
 
                        factor = GetTypeSize (element_type);
                        if (factor == 0)
@@ -6287,35 +6156,14 @@ namespace Mono.CSharp {
                        var initializers = new SLE.Expression [array_data.Count];
                        for (var i = 0; i < initializers.Length; i++) {
                                if (array_data [i] == null)
-                                       initializers [i] = SLE.Expression.Default (array_element_type);
+                                       initializers [i] = SLE.Expression.Default (array_element_type.GetMetaInfo ());
                                else
                                        initializers [i] = array_data [i].MakeExpression (ctx);
                        }
 
-                       return SLE.Expression.NewArrayInit (array_element_type, initializers);
+                       return SLE.Expression.NewArrayInit (array_element_type.GetMetaInfo (), initializers);
                }
 #endif
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       array_element_type = storey.MutateType (array_element_type);
-                       type = storey.MutateType (type);
-                       if (arguments != null) {
-                               foreach (Expression e in arguments)
-                                       e.MutateHoistedGenericType (storey);
-                       }
-                       
-                       if (array_data != null) {
-                               foreach (Expression e in array_data) {
-                                       // Don't mutate values optimized away
-                                       if (e == null)
-                                               continue;
-
-                                       e.MutateHoistedGenericType (storey);
-                               }
-                       }
-               }
-
                //
                // Emits the initializers for the array
                //
@@ -6334,15 +6182,14 @@ namespace Mono.CSharp {
                        // First, the static data
                        //
                        FieldBuilder fb;
-                       ILGenerator ig = ec.ig;
                        
                        byte [] data = MakeByteBlob ();
 
                        fb = RootContext.MakeStaticData (data);
 
-                       ig.Emit (OpCodes.Dup);
-                       ig.Emit (OpCodes.Ldtoken, fb);
-                       ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.void_initializearray_array_fieldhandle.MetaInfo);
+                       ec.Emit (OpCodes.Dup);
+                       ec.Emit (OpCodes.Ldtoken, fb);
+                       ec.Emit (OpCodes.Call, TypeManager.void_initializearray_array_fieldhandle);
                }
 
                //
@@ -6353,25 +6200,9 @@ namespace Mono.CSharp {
                //
                void EmitDynamicInitializers (EmitContext ec, bool emitConstants)
                {
-                       ILGenerator ig = ec.ig;
                        int dims = bounds.Count;
                        int [] current_pos = new int [dims];
 
-                       MethodInfo set = null;
-
-                       if (dims != 1){
-                               Type [] args = new Type [dims + 1];
-
-                               for (int j = 0; j < dims; j++)
-                                       args [j] = TypeManager.int32_type;
-                               args [dims] = array_element_type;
-
-                               set = RootContext.ToplevelTypes.Builder.GetArrayMethod (
-                                       type, "Set",
-                                       CallingConventions.HasThis | CallingConventions.Standard,
-                                       TypeManager.void_type, args);
-                       }
-
                        for (int i = 0; i < array_data.Count; i++){
 
                                Expression e = array_data [i];
@@ -6379,12 +6210,12 @@ namespace Mono.CSharp {
 
                                // Constant can be initialized via StaticInitializer
                                if (c == null || (c != null && emitConstants && !c.IsDefaultInitializer (array_element_type))) {
-                                       Type etype = e.Type;
+                                       TypeSpec etype = e.Type;
 
-                                       ig.Emit (OpCodes.Dup);
+                                       ec.Emit (OpCodes.Dup);
 
                                        for (int idx = 0; idx < dims; idx++) 
-                                               IntConstant.EmitInt (ig, current_pos [idx]);
+                                               ec.EmitInt (current_pos [idx]);
 
                                        //
                                        // If we are dealing with a struct, get the
@@ -6394,23 +6225,12 @@ namespace Mono.CSharp {
                                            (!TypeManager.IsBuiltinOrEnum (etype) ||
                                             etype == TypeManager.decimal_type)) {
 
-                                               ig.Emit (OpCodes.Ldelema, etype);
+                                               ec.Emit (OpCodes.Ldelema, etype);
                                        }
 
                                        e.Emit (ec);
 
-                                       if (dims == 1) {
-                                               bool is_stobj, has_type_arg;
-                                               OpCode op = ArrayAccess.GetStoreOpcode (etype, out is_stobj, out has_type_arg);
-                                               if (is_stobj)
-                                                       ig.Emit (OpCodes.Stobj, etype);
-                                               else if (has_type_arg)
-                                                       ig.Emit (op, etype);
-                                               else
-                                                       ig.Emit (op);
-                                       } else 
-                                               ig.Emit (OpCodes.Call, set);
-
+                                       ec.EmitArrayStore ((ArrayContainer) type);
                                }
                                
                                //
@@ -6427,8 +6247,6 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        if (first_emit != null) {
                                first_emit.Emit (ec);
                                first_emit_temp.Store (ec);
@@ -6437,11 +6255,7 @@ namespace Mono.CSharp {
                        foreach (Expression e in arguments)
                                e.Emit (ec);
 
-                       if (arguments.Count == 1)
-                               ig.Emit (OpCodes.Newarr, TypeManager.TypeToReflectionType (array_element_type));
-                       else {
-                               ig.Emit (OpCodes.Newobj, GetArrayMethod (ec, arguments.Count));
-                       }
+                       ec.EmitArrayNew ((ArrayContainer) type);
                        
                        if (initializers == null)
                                return;
@@ -6463,7 +6277,7 @@ namespace Mono.CSharp {
                                first_emit_temp.Release (ec);
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        // no multi dimensional or jagged arrays
                        if (arguments.Count != 1 || array_element_type.IsArray) {
@@ -6614,7 +6428,7 @@ namespace Mono.CSharp {
                {
                }
 
-               public CompilerGeneratedThis (Type type, Location loc)
+               public CompilerGeneratedThis (TypeSpec type, Location loc)
                        : base (loc)
                {
                        this.type = type;
@@ -6626,7 +6440,7 @@ namespace Mono.CSharp {
                        if (type == null)
                                type = ec.CurrentType;
 
-                       is_struct = type.IsValueType;
+                       is_struct = TypeManager.IsStruct (type);
                        return this;
                }
 
@@ -6648,7 +6462,7 @@ namespace Mono.CSharp {
 
                        public void Emit (EmitContext ec)
                        {
-                               ec.ig.Emit (OpCodes.Ldarg_0);
+                               ec.Emit (OpCodes.Ldarg_0);
                        }
 
                        public void EmitAssign (EmitContext ec)
@@ -6658,7 +6472,7 @@ namespace Mono.CSharp {
 
                        public void EmitAddressOf (EmitContext ec)
                        {
-                               ec.ig.Emit (OpCodes.Ldarg_0);
+                               ec.Emit (OpCodes.Ldarg_0);
                        }
                }
 
@@ -6718,7 +6532,7 @@ namespace Mono.CSharp {
                        if (ec.CurrentAnonymousMethod == null)
                                return true;
 
-                       if (ec.CurrentType.IsValueType && ec.CurrentIterator == null)
+                       if (TypeManager.IsStruct (ec.CurrentType) && ec.CurrentIterator == null)
                                return false;
 
                        return true;
@@ -6741,7 +6555,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       is_struct = type.IsValueType;
+                       is_struct = TypeManager.IsStruct (type);
 
                        if (block != null) {
                                if (block.Toplevel.ThisVariable != null)
@@ -6866,7 +6680,7 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Arglist);
+                       ec.Emit (OpCodes.Arglist);
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression target)
@@ -6896,11 +6710,11 @@ namespace Mono.CSharp {
                public Type[] ArgumentTypes {
                    get {
                                if (Arguments == null)
-                                       return Type.EmptyTypes;
+                                       return System.Type.EmptyTypes;
 
-                       Type[] retval = new Type [Arguments.Count];
+                       var retval = new Type [Arguments.Count];
                        for (int i = 0; i < retval.Length; i++)
-                           retval [i] = Arguments [i].Expr.Type;
+                                       retval[i] = Arguments[i].Expr.Type.GetMetaInfo ();
 
                        return retval;
                    }
@@ -6930,12 +6744,6 @@ namespace Mono.CSharp {
                                Arguments.Emit (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (Arguments != null)
-                               Arguments.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        Arglist target = (Arglist) t;
@@ -6950,7 +6758,7 @@ namespace Mono.CSharp {
        /// </summary>
        public class TypeOf : Expression {
                Expression QueriedType;
-               protected Type typearg;
+               protected TypeSpec typearg;
                
                public TypeOf (Expression queried_type, Location l)
                {
@@ -7001,13 +6809,30 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, Type targetType)
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
                {
                        // Target type is not System.Type therefore must be object
                        // and we need to use different encoding sequence
                        if (targetType != type)
                                enc.Encode (type);
 
+/*
+                       var gi = typearg as InflatedTypeSpec;
+                       if (gi != null) {
+                               // TODO: This has to be recursive, handle arrays, etc.
+                               // I could probably do it after CustomAttribute encoder rewrite
+                               foreach (var ta in gi.TypeArguments) {
+                                       if (ta.IsGenericParameter) {
+                                               ec.Report.SymbolRelatedToPreviousError (typearg);
+                                               ec.Report.Error (416, loc, "`{0}': an attribute argument cannot use type parameters",
+                                                                TypeManager.CSharpName (typearg));
+                                               value = null;
+                                               return false;
+                                       }
+                               }
+                       }
+ */
+
                        if (!enc.EncodeTypeName (typearg)) {
                                rc.Compiler.Report.SymbolRelatedToPreviousError (typearg);
                                rc.Compiler.Report.Error (416, loc, "`{0}': an attribute argument cannot use type parameters",
@@ -7017,17 +6842,11 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldtoken, TypeManager.TypeToReflectionType (typearg));
-                       ec.ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.system_type_get_type_from_handle.MetaInfo);
+                       ec.Emit (OpCodes.Ldtoken, typearg);
+                       ec.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (!TypeManager.IsGenericTypeDefinition (typearg))
-                               typearg = storey.MutateType (typearg);
-               }
-
-               public Type TypeArgument {
+               public TypeSpec TypeArgument {
                        get {
                                return typearg;
                        }
@@ -7083,13 +6902,10 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       if (member.IsConstructor)
-                               ec.ig.Emit (OpCodes.Ldtoken, (ConstructorInfo) member.MetaInfo);
-                       else
-                               ec.ig.Emit (OpCodes.Ldtoken, (MethodInfo) member.MetaInfo);
+                       ec.Emit (OpCodes.Ldtoken, member);
 
                        base.Emit (ec);
-                       ec.ig.Emit (OpCodes.Castclass, type);
+                       ec.Emit (OpCodes.Castclass, type);
                }
 
                protected override string GetMethodName {
@@ -7143,20 +6959,20 @@ namespace Mono.CSharp {
 
                protected override Expression DoResolve (ResolveContext ec)
                {
-                       bool is_generic = TypeManager.IsGenericType (member.DeclaringType);
+                       bool is_generic = member.DeclaringType.IsGenericOrParentIsGeneric;
                        var mi = is_generic ? TypeFromHandleGeneric : TypeFromHandle;
 
                        if (mi == null) {
-                               Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, MemberKind.Class, true);
-                               Type handle_type = TypeManager.CoreLookupType (ec.Compiler, "System", RuntimeHandleName, MemberKind.Class, true);
+                               TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Reflection", TypeName, MemberKind.Class, true);
+                               TypeSpec handle_type = TypeManager.CoreLookupType (ec.Compiler, "System", RuntimeHandleName, MemberKind.Struct, true);
 
                                if (t == null || handle_type == null)
                                        return null;
 
                                mi = TypeManager.GetPredefinedMethod (t, GetMethodName, loc,
                                        is_generic ?
-                                       new Type[] { handle_type, TypeManager.runtime_handle_type } :
-                                       new Type[] { handle_type } );
+                                       new TypeSpec[] { handle_type, TypeManager.runtime_handle_type } :
+                                       new TypeSpec[] { handle_type } );
 
                                if (is_generic)
                                        TypeFromHandleGeneric = mi;
@@ -7170,16 +6986,16 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       bool is_generic = TypeManager.IsGenericType (member.DeclaringType);
+                       bool is_generic = member.DeclaringType.IsGenericOrParentIsGeneric;
                        MethodSpec mi;
                        if (is_generic) {
                                mi = TypeFromHandleGeneric;
-                               ec.ig.Emit (OpCodes.Ldtoken, member.DeclaringType);
+                               ec.Emit (OpCodes.Ldtoken, member.DeclaringType);
                        } else {
                                mi = TypeFromHandle;
                        }
 
-                       ec.ig.Emit (OpCodes.Call, (MethodInfo) mi.MetaInfo);
+                       ec.Emit (OpCodes.Call, mi);
                }
 
                protected abstract string GetMethodName { get; }
@@ -7207,7 +7023,7 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldtoken, member.MetaInfo);
+                       ec.Emit (OpCodes.Ldtoken, member);
                        base.Emit (ec);
                }
 
@@ -7247,7 +7063,7 @@ namespace Mono.CSharp {
        /// </summary>
        public class SizeOf : Expression {
                readonly Expression QueriedType;
-               Type type_queried;
+               TypeSpec type_queried;
                
                public SizeOf (Expression queried_type, Location l)
                {
@@ -7269,7 +7085,7 @@ namespace Mono.CSharp {
 
                        type_queried = texpr.Type;
                        if (TypeManager.IsEnumType (type_queried))
-                               type_queried = TypeManager.GetEnumUnderlyingType (type_queried);
+                               type_queried = EnumSpec.GetUnderlyingType (type_queried);
 
                        int size_of = GetTypeSize (type_queried);
                        if (size_of > 0) {
@@ -7293,7 +7109,7 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Sizeof, type_queried);
+                       ec.Emit (OpCodes.Sizeof, type_queried);
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -7309,14 +7125,20 @@ namespace Mono.CSharp {
                readonly string alias;
                public static readonly string GlobalAlias = "global";
 
+               public QualifiedAliasMember (string alias, string identifier, Location l)
+                       : base (null, identifier, l)
+               {
+                       this.alias = alias;
+               }
+
                public QualifiedAliasMember (string alias, string identifier, TypeArguments targs, Location l)
                        : base (null, identifier, targs, l)
                {
                        this.alias = alias;
                }
 
-               public QualifiedAliasMember (string alias, string identifier, Location l)
-                       : base (null, identifier, l)
+               public QualifiedAliasMember (string alias, string identifier, int arity, Location l)
+                       : base (null, identifier, arity, l)
                {
                        this.alias = alias;
                }
@@ -7356,7 +7178,7 @@ namespace Mono.CSharp {
                        return ResolveAsTypeStep (ec, false);
                }
 
-               protected override void Error_IdentifierNotFound (IMemberContext rc, FullNamedExpression expr_type, string identifier)
+               protected override void Error_IdentifierNotFound (IMemberContext rc, TypeSpec expr_type, string identifier)
                {
                        rc.Compiler.Report.Error (687, loc,
                                "A namespace alias qualifier `{0}' did not resolve to a namespace or a type",
@@ -7367,8 +7189,7 @@ namespace Mono.CSharp {
                {
                        string name = Name;
                        if (targs != null) {
-                               name = TypeManager.RemoveGenericArity (Name) + "<" +
-                                       targs.GetSignatureForError () + ">";
+                               name = Name + "<" + targs.GetSignatureForError () + ">";
                        }
 
                        return alias + "::" + name;
@@ -7404,6 +7225,12 @@ namespace Mono.CSharp {
                        this.expr = expr;
                }
 
+               public MemberAccess (Expression expr, string identifier, int arity, Location loc)
+                       : base (identifier, arity, loc)
+               {
+                       this.expr = expr;
+               }
+
                Expression DoResolve (ResolveContext ec, Expression right_side)
                {
                        if (type != null)
@@ -7425,22 +7252,20 @@ namespace Mono.CSharp {
                        if (expr_resolved == null)
                                return null;
 
-                       string LookupIdentifier = MemberName.MakeName (Name, targs);
-
                        Namespace ns = expr_resolved as Namespace;
                        if (ns != null) {
-                               FullNamedExpression retval = ns.Lookup (ec.Compiler, LookupIdentifier, loc);
+                               FullNamedExpression retval = ns.Lookup (ec.Compiler, Name, Arity, loc);
 
                                if (retval == null)
-                                       ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, ec);
-                               else if (targs != null)
+                                       ns.Error_NamespaceDoesNotExist (loc, Name, Arity, ec);
+                               else if (HasTypeArguments)
                                        retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (ec, false);
 
                                return retval;
                        }
 
-                       Type expr_type = expr_resolved.Type;
-                       if (TypeManager.IsDynamicType (expr_type)) {
+                       TypeSpec expr_type = expr_resolved.Type;
+                       if (expr_type == InternalType.Dynamic) {
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (expr_resolved.Resolve (ec)));
                                expr = new DynamicMemberBinder (Name, args, loc);
@@ -7462,19 +7287,10 @@ namespace Mono.CSharp {
                                        "System.NullReferenceException");
                        }
 
-                       if (targs != null) {
-                               if (!targs.Resolve (ec))
-                                       return null;
-                       }
+                       var arity = HasTypeArguments ? targs.Count : -1;
 
-                       Expression member_lookup;
-                       member_lookup = MemberLookup (ec.Compiler,
-                               ec.CurrentType, expr_type, expr_type, Name, loc);
-
-                       if (member_lookup == null && targs != null) {
-                               member_lookup = MemberLookup (ec.Compiler,
-                                       ec.CurrentType, expr_type, expr_type, LookupIdentifier, loc);
-                       }
+                       var member_lookup = MemberLookup (ec.Compiler,
+                               ec.CurrentType, expr_type, expr_type, Name, arity, BindingRestriction.NoOverrides, loc);
 
                        if (member_lookup == null) {
                                ExprClass expr_eclass = expr_resolved.eclass;
@@ -7485,11 +7301,14 @@ namespace Mono.CSharp {
                                if (expr_eclass == ExprClass.Value || expr_eclass == ExprClass.Variable ||
                                        expr_eclass == ExprClass.IndexerAccess || expr_eclass == ExprClass.PropertyAccess ||
                                        expr_eclass == ExprClass.EventAccess) {
-                                       ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, loc);
+                                       ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, arity, loc);
                                        if (ex_method_lookup != null) {
                                                ex_method_lookup.ExtensionExpression = expr_resolved;
 
-                                               if (targs != null) {
+                                               if (HasTypeArguments) {
+                                                       if (!targs.Resolve (ec))
+                                                               return null;
+
                                                        ex_method_lookup.SetTypeArguments (ec, targs);
                                                }
 
@@ -7499,8 +7318,8 @@ namespace Mono.CSharp {
 
                                expr = expr_resolved;
                                member_lookup = Error_MemberLookupFailed (ec,
-                                       ec.CurrentType, expr_type, expr_type, Name, null,
-                                       AllMemberTypes, AllBindingFlags);
+                                       ec.CurrentType, expr_type, expr_type, Name, arity, null,
+                                       MemberKind.All, BindingRestriction.AccessibleOnly);
                                if (member_lookup == null)
                                        return null;
                        }
@@ -7521,25 +7340,8 @@ namespace Mono.CSharp {
                                }
 
                                GenericTypeExpr ct = expr_resolved as GenericTypeExpr;
-                               if (ct != null) {
-                                       //
-                                       // When looking up a nested type in a generic instance
-                                       // via reflection, we always get a generic type definition
-                                       // and not a generic instance - so we have to do this here.
-                                       //
-                                       // See gtest-172-lib.cs and gtest-172.cs for an example.
-                                       //
-
-                                       TypeArguments nested_targs;
-                                       if (HasTypeArguments) {
-                                               nested_targs = ct.TypeArguments.Clone ();
-                                               nested_targs.Add (targs);
-                                       } else {
-                                               nested_targs = ct.TypeArguments;
-                                       }
-
-                                       ct = new GenericTypeExpr (member_lookup.Type, nested_targs, loc);
-
+                               if (ct != null && Arity > 0) {
+                                       ct = new GenericTypeExpr (member_lookup.Type, targs, loc);
                                        return ct.ResolveAsTypeStep (ec, false);
                                }
 
@@ -7551,7 +7353,10 @@ namespace Mono.CSharp {
                        if (me == null)
                                return null;
 
-                       if (targs != null) {
+                       if (HasTypeArguments) {
+                               if (!targs.Resolve (ec))
+                                       return null;
+
                                me.SetTypeArguments (ec, targs);
                        }
 
@@ -7594,16 +7399,16 @@ namespace Mono.CSharp {
                        if (expr_resolved == null)
                                return null;
 
-                       string LookupIdentifier = MemberName.MakeName (Name, targs);
-
                        Namespace ns = expr_resolved as Namespace;
                        if (ns != null) {
-                               FullNamedExpression retval = ns.Lookup (rc.Compiler, LookupIdentifier, loc);
+                               FullNamedExpression retval = ns.Lookup (rc.Compiler, Name, Arity, loc);
 
-                               if (retval == null && !silent)
-                                       ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, rc);
-                               else if (targs != null)
+                               if (retval == null) {
+                                       if (!silent)
+                                               ns.Error_NamespaceDoesNotExist (loc, Name, Arity, rc);
+                               } else if (HasTypeArguments) {
                                        retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (rc, silent);
+                               }
 
                                return retval;
                        }
@@ -7612,71 +7417,49 @@ namespace Mono.CSharp {
                        if (tnew_expr == null)
                                return null;
 
-                       Type expr_type = tnew_expr.Type;
+                       TypeSpec expr_type = tnew_expr.Type;
                        if (TypeManager.IsGenericParameter (expr_type)) {
                                rc.Compiler.Report.Error (704, loc, "A nested type cannot be specified through a type parameter `{0}'",
                                        tnew_expr.GetSignatureForError ());
                                return null;
                        }
 
-                       Expression member_lookup = MemberLookup (rc.Compiler,
-                               rc.CurrentType, expr_type, expr_type, LookupIdentifier,
-                               MemberTypes.NestedType, BindingFlags.Public | BindingFlags.NonPublic, loc);
-                       if (member_lookup == null) {
+                       var nested = MemberCache.FindNestedType (expr_type, Name, Arity);
+                       if (nested == null) {
                                if (silent)
                                        return null;
 
-                               Error_IdentifierNotFound (rc, expr_resolved, LookupIdentifier);
+                               Error_IdentifierNotFound (rc, expr_type, Name);
                                return null;
                        }
 
-                       TypeExpr texpr = member_lookup.ResolveAsTypeTerminal (rc, false);
-                       if (texpr == null)
-                               return null;
-
-                       TypeArguments the_args = targs;
-                       Type declaring_type = texpr.Type.DeclaringType;
-                       if (TypeManager.HasGenericArguments (declaring_type) && !TypeManager.IsGenericTypeDefinition (expr_type)) {
-                               while (!TypeManager.IsEqual (TypeManager.DropGenericTypeArguments (expr_type), declaring_type)) {
-                                       expr_type = expr_type.BaseType;
-                               }
-                               
-                               TypeArguments new_args = new TypeArguments ();
-                               foreach (Type decl in TypeManager.GetTypeArguments (expr_type))
-                                       new_args.Add (new TypeExpression (TypeManager.TypeToCoreType (decl), loc));
-
-                               if (targs != null)
-                                       new_args.Add (targs);
-
-                               the_args = new_args;
+                       bool extra_check;
+                       if (!IsMemberAccessible (rc.CurrentType ?? InternalType.FakeInternalType, nested, out extra_check)) {
+                               ErrorIsInaccesible (loc, nested.GetSignatureForError (), rc.Compiler.Report);
                        }
-
-                       if (the_args != null) {
-                               GenericTypeExpr ctype = new GenericTypeExpr (texpr.Type, the_args, loc);
-                               return ctype.ResolveAsTypeStep (rc, false);
+                       
+                       TypeExpr texpr;
+                       if (HasTypeArguments) {
+                               texpr = new GenericTypeExpr (nested, targs, loc);
+                       } else {
+                               texpr = new TypeExpression (nested, loc);
                        }
 
-                       return texpr;
+                       return texpr.ResolveAsTypeStep (rc, false);
                }
 
-               protected virtual void Error_IdentifierNotFound (IMemberContext rc, FullNamedExpression expr_type, string identifier)
+               protected virtual void Error_IdentifierNotFound (IMemberContext rc, TypeSpec expr_type, string identifier)
                {
-                       Expression member_lookup = MemberLookup (rc.Compiler,
-                               rc.CurrentType, expr_type.Type, expr_type.Type, SimpleName.RemoveGenericArity (identifier),
-                               MemberTypes.NestedType, BindingFlags.Public | BindingFlags.NonPublic, loc);
-
-                       if (member_lookup != null) {
-                               expr_type = member_lookup.ResolveAsTypeTerminal (rc, false);
-                               if (expr_type == null)
-                                       return;
+                       var nested = MemberCache.FindNestedType (expr_type, Name, -System.Math.Max (1, Arity));
 
-                               expr_type.Error_TypeArgumentsCannotBeUsed (rc.Compiler.Report, loc);
+                       if (nested != null) {
+                               Error_TypeArgumentsCannotBeUsed (rc.Compiler.Report, expr.Location, nested, Arity);
                                return;
                        }
 
-                       member_lookup = MemberLookup (rc.Compiler,
-                               rc.CurrentType, expr_type.Type, expr_type.Type, identifier,
-                                       MemberTypes.All, BindingFlags.Public | BindingFlags.NonPublic, loc);
+                       var member_lookup = MemberLookup (rc.Compiler,
+                               rc.CurrentType, expr_type, expr_type, identifier, -1,
+                                       MemberKind.All, BindingRestriction.None, loc);
 
                        if (member_lookup == null) {
                                rc.Compiler.Report.Error (426, loc, "The nested type `{0}' does not exist in the type `{1}'",
@@ -7687,7 +7470,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
+               protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, TypeSpec type, string name)
                {
                        if (RootContext.Version > LanguageVersion.ISO_2 && !ec.Compiler.IsRuntimeBinder &&
                                ((expr.eclass & (ExprClass.Value | ExprClass.Variable)) != 0)) {
@@ -7774,11 +7557,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Expr.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        CheckedExpr target = (CheckedExpr) t;
@@ -7834,11 +7612,6 @@ namespace Mono.CSharp {
                                Expr.EmitBranchable (ec, target, on_true);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Expr.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        UnCheckedExpr target = (UnCheckedExpr) t;
@@ -7872,7 +7645,7 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "ArrayIndex", args);
                }
 
-               Expression MakePointerAccess (ResolveContext ec, Type t)
+               Expression MakePointerAccess (ResolveContext ec, TypeSpec t)
                {
                        if (Arguments.Count != 1){
                                ec.Report.Error (196, loc, "A pointer must be indexed by only one value");
@@ -7898,7 +7671,7 @@ namespace Mono.CSharp {
                        //
                        // I am experimenting with this pattern.
                        //
-                       Type t = Expr.Type;
+                       TypeSpec t = Expr.Type;
 
                        if (t == TypeManager.array_type){
                                ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `System.Array'");
@@ -7999,11 +7772,11 @@ namespace Mono.CSharp {
                        bool dynamic;
                        ea.Arguments.Resolve (ec, out dynamic);
 
-                       Type t = ea.Expr.Type;
+                       TypeSpec t = ea.Expr.Type;
                        int rank = ea.Arguments.Count;
-                       if (t.GetArrayRank () != rank) {
+                       if (t.GetMetaInfo ().GetArrayRank () != rank) {
                                ec.Report.Error (22, ea.Location, "Wrong number of indexes `{0}' inside [], expected `{1}'",
-                                         ea.Arguments.Count.ToString (), t.GetArrayRank ().ToString ());
+                                         ea.Arguments.Count.ToString (), t.GetMetaInfo ().GetArrayRank ().ToString ());
                                return null;
                        }
 
@@ -8024,137 +7797,27 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               /// <summary>
-               ///    Emits the right opcode to load an object of Type `t'
-               ///    from an array of T
-               /// </summary>
-               void EmitLoadOpcode (ILGenerator ig, Type type, int rank)
-               {
-                       if (rank > 1) {
-                               MethodInfo get = FetchGetMethod ();
-                               ig.Emit (OpCodes.Call, get);
-                               return;
-                       }
-
-                       if (type == TypeManager.byte_type || type == TypeManager.bool_type)
-                               ig.Emit (OpCodes.Ldelem_U1);
-                       else if (type == TypeManager.sbyte_type)
-                               ig.Emit (OpCodes.Ldelem_I1);
-                       else if (type == TypeManager.short_type)
-                               ig.Emit (OpCodes.Ldelem_I2);
-                       else if (type == TypeManager.ushort_type || type == TypeManager.char_type)
-                               ig.Emit (OpCodes.Ldelem_U2);
-                       else if (type == TypeManager.int32_type)
-                               ig.Emit (OpCodes.Ldelem_I4);
-                       else if (type == TypeManager.uint32_type)
-                               ig.Emit (OpCodes.Ldelem_U4);
-                       else if (type == TypeManager.uint64_type)
-                               ig.Emit (OpCodes.Ldelem_I8);
-                       else if (type == TypeManager.int64_type)
-                               ig.Emit (OpCodes.Ldelem_I8);
-                       else if (type == TypeManager.float_type)
-                               ig.Emit (OpCodes.Ldelem_R4);
-                       else if (type == TypeManager.double_type)
-                               ig.Emit (OpCodes.Ldelem_R8);
-                       else if (type == TypeManager.intptr_type)
-                               ig.Emit (OpCodes.Ldelem_I);
-                       else if (TypeManager.IsEnumType (type)){
-                               EmitLoadOpcode (ig, TypeManager.GetEnumUnderlyingType (type), rank);
-                       } else if (TypeManager.IsStruct (type)){
-                               ig.Emit (OpCodes.Ldelema, type);
-                               ig.Emit (OpCodes.Ldobj, type);
-                       } else if (type.IsGenericParameter) {
-                               ig.Emit (OpCodes.Ldelem, type);
-                       } else if (type.IsPointer)
-                               ig.Emit (OpCodes.Ldelem_I);
-                       else
-                               ig.Emit (OpCodes.Ldelem_Ref);
-               }
-
                protected override void Error_NegativeArrayIndex (ResolveContext ec, Location loc)
                {
                        ec.Report.Warning (251, 2, loc, "Indexing an array with a negative index (array indices always start at zero)");
                }
 
-               /// <summary>
-               ///    Returns the right opcode to store an object of Type `t'
-               ///    from an array of T.  
-               /// </summary>
-               static public OpCode GetStoreOpcode (Type t, out bool is_stobj, out bool has_type_arg)
-               {
-                       has_type_arg = false; is_stobj = false;
-                       t = TypeManager.TypeToCoreType (t);
-                       if (TypeManager.IsEnumType (t))
-                               t = TypeManager.GetEnumUnderlyingType (t);
-                       if (t == TypeManager.byte_type || t == TypeManager.sbyte_type ||
-                           t == TypeManager.bool_type)
-                               return OpCodes.Stelem_I1;
-                       else if (t == TypeManager.short_type || t == TypeManager.ushort_type ||
-                                t == TypeManager.char_type)
-                               return OpCodes.Stelem_I2;
-                       else if (t == TypeManager.int32_type || t == TypeManager.uint32_type)
-                               return OpCodes.Stelem_I4;
-                       else if (t == TypeManager.int64_type || t == TypeManager.uint64_type)
-                               return OpCodes.Stelem_I8;
-                       else if (t == TypeManager.float_type)
-                               return OpCodes.Stelem_R4;
-                       else if (t == TypeManager.double_type)
-                               return OpCodes.Stelem_R8;
-                       else if (t == TypeManager.intptr_type) {
-                                has_type_arg = true;
-                               is_stobj = true;
-                                return OpCodes.Stobj;
-                       } else if (TypeManager.IsStruct (t)) {
-                               has_type_arg = true;
-                               is_stobj = true;
-                               return OpCodes.Stobj;
-                       } else if (t.IsGenericParameter) {
-                               has_type_arg = true;
-                               return OpCodes.Stelem;
-                       } else if (t.IsPointer)
-                               return OpCodes.Stelem_I;
-                       else
-                               return OpCodes.Stelem_Ref;
-               }
-
-               MethodInfo FetchGetMethod ()
-               {
-                       ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
-                       int arg_count = ea.Arguments.Count;
-                       Type [] args = new Type [arg_count];
-                       MethodInfo get;
-                       
-                       for (int i = 0; i < arg_count; i++){
-                               //args [i++] = a.Type;
-                               args [i] = TypeManager.int32_type;
-                       }
-                       
-                       get = mb.GetArrayMethod (
-                               ea.Expr.Type, "Get",
-                               CallingConventions.HasThis |
-                               CallingConventions.Standard,
-                               type, args);
-                       return get;
-               }
-                               
-
                MethodInfo FetchAddressMethod ()
                {
                        ModuleBuilder mb = RootContext.ToplevelTypes.Builder;
                        int arg_count = ea.Arguments.Count;
-                       Type [] args = new Type [arg_count];
+                       var args = new Type [arg_count];
                        MethodInfo address;
-                       Type ret_type;
                        
-                       ret_type = TypeManager.GetReferenceType (type);
+                       var ret_type = TypeManager.GetReferenceType (type);
                        
                        for (int i = 0; i < arg_count; i++){
                                //args [i++] = a.Type;
-                               args [i] = TypeManager.int32_type;
+                               args[i] = TypeManager.int32_type.GetMetaInfo ();
                        }
                        
                        address = mb.GetArrayMethod (
-                               ea.Expr.Type, "Address",
+                               ea.Expr.Type.GetMetaInfo (), "Address",
                                CallingConventions.HasThis |
                                CallingConventions.Standard,
                                ret_type, args);
@@ -8176,18 +7839,17 @@ namespace Mono.CSharp {
 
                public void Emit (EmitContext ec, bool leave_copy)
                {
-                       int rank = ea.Expr.Type.GetArrayRank ();
-                       ILGenerator ig = ec.ig;
+                       var ac = ea.Expr.Type as ArrayContainer;
 
                        if (prepared) {
-                               LoadFromPtr (ig, this.type);
+                               ec.EmitLoadFromPtr (type);
                        } else {
                                LoadArrayAndArguments (ec);
-                               EmitLoadOpcode (ig, type, rank);
+                               ec.EmitArrayLoad (ac);
                        }       
 
                        if (leave_copy) {
-                               ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                                temp = new LocalTemporary (this.type);
                                temp.Store (ec);
                        }
@@ -8200,74 +7862,43 @@ namespace Mono.CSharp {
 
                public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
                {
-                       int rank = ea.Expr.Type.GetArrayRank ();
-                       ILGenerator ig = ec.ig;
-                       Type t = source.Type;
+                       var ac = (ArrayContainer) ea.Expr.Type;
+                       TypeSpec t = source.Type;
                        prepared = prepare_for_load;
 
                        if (prepared) {
                                AddressOf (ec, AddressOp.LoadStore);
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                        } else {
                                LoadArrayAndArguments (ec);
-                       }
 
-                       if (rank == 1) {
-                               bool is_stobj, has_type_arg;
-                               OpCode op = GetStoreOpcode (t, out is_stobj, out has_type_arg);
+                               //
+                               // If we are dealing with a struct, get the
+                               // address of it, so we can store it.
+                               //
+                               // The stobj opcode used by value types will need
+                               // an address on the stack, not really an array/array
+                               // pair
+                               //
+                               if (ac.Rank == 1 && TypeManager.IsStruct (t) &&
+                                       (!TypeManager.IsBuiltinOrEnum (t) ||
+                                        t == TypeManager.decimal_type)) {
 
-                               if (!prepared) {
-                                       //
-                                       // The stobj opcode used by value types will need
-                                       // an address on the stack, not really an array/array
-                                       // pair
-                                       //
-                                       if (is_stobj)
-                                               ig.Emit (OpCodes.Ldelema, t);
+                                       ec.Emit (OpCodes.Ldelema, t);
                                }
-                               
-                               source.Emit (ec);
-                               if (leave_copy) {
-                                       ec.ig.Emit (OpCodes.Dup);
-                                       temp = new LocalTemporary (this.type);
-                                       temp.Store (ec);
-                               }
-                               
-                               if (prepared)
-                                       StoreFromPtr (ig, t);
-                               else if (is_stobj)
-                                       ig.Emit (OpCodes.Stobj, t);
-                               else if (has_type_arg)
-                                       ig.Emit (op, t);
-                               else
-                                       ig.Emit (op);
-                       } else {
-                               source.Emit (ec);
-                               if (leave_copy) {
-                                       ec.ig.Emit (OpCodes.Dup);
-                                       temp = new LocalTemporary (this.type);
-                                       temp.Store (ec);
-                               }
-
-                               if (prepared) {
-                                       StoreFromPtr (ig, t);
-                               } else {
-                                       int arg_count = ea.Arguments.Count;
-                                       Type [] args = new Type [arg_count + 1];
-                                       for (int i = 0; i < arg_count; i++) {
-                                               //args [i++] = a.Type;
-                                               args [i] = TypeManager.int32_type;
-                                       }
-                                       args [arg_count] = type;
+                       }
 
-                                       MethodInfo set = RootContext.ToplevelTypes.Builder.GetArrayMethod (
-                                               ea.Expr.Type, "Set",
-                                               CallingConventions.HasThis |
-                                               CallingConventions.Standard,
-                                               TypeManager.void_type, args);
+                       source.Emit (ec);
+                       if (leave_copy) {
+                               ec.Emit (OpCodes.Dup);
+                               temp = new LocalTemporary (this.type);
+                               temp.Store (ec);
+                       }
 
-                                       ig.Emit (OpCodes.Call, set);
-                               }
+                       if (prepared) {
+                               ec.EmitStoreFromPtr (t);
+                       } else {
+                               ec.EmitArrayStore (ac);
                        }
                        
                        if (temp != null) {
@@ -8290,16 +7921,15 @@ namespace Mono.CSharp {
 
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
-                       int rank = ea.Expr.Type.GetArrayRank ();
-                       ILGenerator ig = ec.ig;
+                       int rank = ea.Expr.Type.GetMetaInfo ().GetArrayRank ();
 
                        LoadArrayAndArguments (ec);
 
                        if (rank == 1){
-                               ig.Emit (OpCodes.Ldelema, type);
+                               ec.Emit (OpCodes.Ldelema, type);
                        } else {
                                MethodInfo address = FetchAddressMethod ();
-                               ig.Emit (OpCodes.Call, address);
+                               ec.Emit (OpCodes.Call, address);
                        }
                }
 
@@ -8318,12 +7948,6 @@ namespace Mono.CSharp {
                                ea.Expr.MakeExpression (ctx),
                                Arguments.MakeExpression (ea.Arguments, ctx));
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-                       ea.Expr.Type = storey.MutateType (ea.Expr.Type);
-               }
        }
 
        /// <summary>
@@ -8333,10 +7957,36 @@ namespace Mono.CSharp {
        {
                class IndexerMethodGroupExpr : MethodGroupExpr
                {
-                       public IndexerMethodGroupExpr (Indexers indexers, Location loc)
-                               : base (null, loc)
+                       IEnumerable<IndexerSpec> candidates;
+
+                       public IndexerMethodGroupExpr (IEnumerable<IndexerSpec> indexers, Location loc)
+                               : base (FilterAccessors (indexers).ToList (), null, loc)
                        {
-                               Methods = indexers.Methods.ToArray ();
+                               candidates = indexers;
+                       }
+
+                       public IndexerSpec BestIndexer ()
+                       {
+                               return candidates.Where (l => l.Get == BestCandidate || l.Set == BestCandidate).First ();
+                       }
+
+                       static IEnumerable<MemberSpec> FilterAccessors (IEnumerable<IndexerSpec> indexers)
+                       {
+                               foreach (IndexerSpec i in indexers) {
+                                       if (i.HasGet)
+                                               yield return i.Get;
+                                       else
+                                               yield return i.Set;
+                               }
+                       }
+
+                       protected override IList<MemberSpec> GetBaseTypeMethods (ResolveContext rc, TypeSpec type)
+                       {
+                               candidates = GetIndexersForType (type);
+                               if (candidates == null)
+                                       return null;
+
+                               return FilterAccessors (candidates).ToList ();
                        }
 
                        public override string Name {
@@ -8360,100 +8010,18 @@ namespace Mono.CSharp {
                        }
                }
 
-               class Indexers
-               {
-                       // Contains either property getter or setter
-                       public List<MethodSpec> Methods;
-                       public List<PropertyInfo> Properties;
-
-                       Indexers ()
-                       {
-                       }
-
-                       void Append (Type caller_type, MemberInfo [] mi)
-                       {
-                               if (mi == null)
-                                       return;
-
-                               foreach (PropertyInfo property in mi) {
-                                       MethodInfo accessor = property.GetGetMethod (true);
-                                       if (accessor == null)
-                                               accessor = property.GetSetMethod (true);
-
-                                       if (Methods == null) {
-                                               Methods = new List<MethodSpec> ();
-                                               Properties = new List<PropertyInfo> ();
-                                       }
-
-                                       Methods.Add (Import.CreateMethod (accessor));
-                                       Properties.Add (property);
-                               }
-                       }
-
-                       static MemberInfo [] GetIndexersForTypeOrInterface (Type caller_type, Type lookup_type)
-                       {
-                               string p_name = TypeManager.IndexerPropertyName (lookup_type);
-
-                               return TypeManager.MemberLookup (
-                                       caller_type, caller_type, lookup_type, MemberTypes.Property,
-                                       BindingFlags.Public | BindingFlags.Instance |
-                                       BindingFlags.DeclaredOnly, p_name, null);
-                       }
-                       
-                       public static Indexers GetIndexersForType (Type caller_type, Type lookup_type) 
-                       {
-                               Indexers ix = new Indexers ();
-
-                               if (TypeManager.IsGenericParameter (lookup_type)) {
-                                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (lookup_type);
-                                       if (gc == null)
-                                               return ix;
-
-                                       if (gc.HasClassConstraint) {
-                                               Type class_contraint = gc.ClassConstraint;
-                                               while (class_contraint != TypeManager.object_type && class_contraint != null) {
-                                                       ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, class_contraint));
-                                                       class_contraint = class_contraint.BaseType;
-                                               }
-                                       }
-
-                                       Type[] ifaces = gc.InterfaceConstraints;
-                                       foreach (Type itype in ifaces)
-                                               ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, itype));
-
-                                       return ix;
-                               }
-
-                               Type copy = lookup_type;
-                               while (copy != TypeManager.object_type && copy != null){
-                                       ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, copy));
-                                       copy = copy.BaseType;
-                               }
-
-                               if (lookup_type.IsInterface) {
-                                       Type [] ifaces = TypeManager.GetInterfaces (lookup_type);
-                                       if (ifaces != null) {
-                                               foreach (Type itype in ifaces)
-                                                       ix.Append (caller_type, GetIndexersForTypeOrInterface (caller_type, itype));
-                                       }
-                               }
-
-                               return ix;
-                       }
-               }
-
                //
                // Points to our "data" repository
                //
-               MethodSpec get, set;
+               IndexerSpec spec;
                bool is_base_indexer;
                bool prepared;
                LocalTemporary temp;
                LocalTemporary prepared_value;
                Expression set_expr;
 
-               protected Type indexer_type;
-               protected Type current_type;
+               protected TypeSpec indexer_type;
+               protected TypeSpec current_type;
                protected Expression instance_expr;
                protected Arguments arguments;
                
@@ -8480,11 +8048,16 @@ namespace Mono.CSharp {
                {
                        Arguments args = Arguments.CreateForExpressionTree (ec, arguments,
                                instance_expr.CreateExpressionTree (ec),
-                               new TypeOfMethod (get, loc));
+                               new TypeOfMethod (spec.Get, loc));
 
                        return CreateExpressionFactoryCall (ec, "Call", args);
                }
 
+               static IEnumerable<IndexerSpec> GetIndexersForType (TypeSpec lookup_type)
+               {
+                       return MemberCache.FindIndexers (lookup_type, BindingRestriction.AccessibleOnly | BindingRestriction.NoOverrides);
+               }
+
                protected virtual void CommonResolve (ResolveContext ec)
                {
                        indexer_type = instance_expr.Type;
@@ -8515,28 +8088,27 @@ namespace Mono.CSharp {
                {
                        CommonResolve (ec);
 
-                       MethodGroupExpr mg;
-                       Indexers ilist;
                        bool dynamic;
 
                        arguments.Resolve (ec, out dynamic);
 
-                       if (TypeManager.IsDynamicType (indexer_type)) {
+                       if (indexer_type == InternalType.Dynamic) {
                                dynamic = true;
-                               mg = null;
-                               ilist = null;
                        } else {
-                               ilist = Indexers.GetIndexersForType (current_type, indexer_type);
-                               if (ilist.Methods == null) {
+                               var ilist = GetIndexersForType (/*current_type,*/ indexer_type);
+                               if (ilist == null) {
                                        ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
                                                          TypeManager.CSharpName (indexer_type));
                                        return null;
                                }
 
-                               mg = new IndexerMethodGroupExpr (ilist, loc);
-                               mg = mg.OverloadResolve (ec, ref arguments, false, loc);
+                               var mg = new IndexerMethodGroupExpr (ilist, loc);
+                               mg = mg.OverloadResolve (ec, ref arguments, false, loc) as IndexerMethodGroupExpr;
                                if (mg == null)
                                        return null;
+
+                               if (!dynamic)
+                                       spec = mg.BestIndexer ();
                        }
 
                        if (dynamic) {
@@ -8555,72 +8127,48 @@ namespace Mono.CSharp {
                                return expr.Resolve (ec);
                        }
 
-                       var mi = (MethodSpec) mg;
-                       PropertyInfo pi = null;
-                       for (int i = 0; i < ilist.Methods.Count; ++i) {
-                               if (ilist.Methods [i].MetaInfo == mi.MetaInfo) {
-                                       pi = (PropertyInfo) ilist.Properties [i];
-                                       break;
-                               }
-                       }
-
-                       type = TypeManager.TypeToCoreType (pi.PropertyType);
+                       type = spec.MemberType;
                        if (type.IsPointer && !ec.IsUnsafe)
                                UnsafeError (ec, loc);
 
-                       MethodSpec accessor = null;
+                       MethodSpec accessor;
                        if (right_side == null) {
-                               var m = pi.GetGetMethod (true);
-                               if (m != null)
-                                       accessor = get = Import.CreateMethod (m);
+                               accessor = spec.Get;
                        } else {
-                               var m = pi.GetSetMethod (true);
-                               if (m != null)
-                                       accessor = set = Import.CreateMethod (m);
-                               if (accessor == null && pi.GetGetMethod (true) != null) {
-                                       ec.Report.SymbolRelatedToPreviousError (pi);
+                               accessor = spec.Set;
+                               if (!spec.HasSet && spec.HasGet) {
+                                       ec.Report.SymbolRelatedToPreviousError (spec);
                                        ec.Report.Error (200, loc, "The read only property or indexer `{0}' cannot be assigned to",
-                                               TypeManager.GetFullNameSignature (pi));
+                                               spec.GetSignatureForError ());
                                        return null;
                                }
 
                                set_expr = Convert.ImplicitConversion (ec, right_side, type, loc);
                        }
 
-                       if (accessor == null) {
-                               ec.Report.SymbolRelatedToPreviousError (pi);
+                       if (accessor == null || accessor.Kind == MemberKind.FakeMethod) {
+                               ec.Report.SymbolRelatedToPreviousError (spec);
                                ec.Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks a `{1}' accessor",
-                                       TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null));
+                                       spec.GetSignatureForError (), GetAccessorName (right_side != null));
                                return null;
                        }
 
                        //
                        // Only base will allow this invocation to happen.
                        //
-                       if (accessor.IsAbstract && this is BaseIndexerAccess) {
-                               Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (pi));
+                       if (spec.IsAbstract && this is BaseIndexerAccess) {
+                               Error_CannotCallAbstractBase (ec, spec.GetSignatureForError ());
                        }
 
                        bool must_do_cs1540_check;
-                       if (!IsAccessorAccessible (ec.CurrentType, accessor, out must_do_cs1540_check)) {
-                               if (set == null) {
-                                       var m = pi.GetSetMethod (true);
-                                       if (m != null)
-                                               set = Import.CreateMethod (m);
-                               } else {
-                                       var m = pi.GetGetMethod (true);
-                                       if (m != null)
-                                               get = Import.CreateMethod (m);
-                               }
-
-                               if (set != null && get != null &&
-                                       (set.MetaInfo.Attributes & MethodAttributes.MemberAccessMask) != (get.MetaInfo.Attributes & MethodAttributes.MemberAccessMask)) {
-                                       ec.Report.SymbolRelatedToPreviousError (accessor.MetaInfo);
+                       if (!IsMemberAccessible (ec.CurrentType, accessor, out must_do_cs1540_check)) {
+                               if (spec.HasDifferentAccessibility) {
+                                       ec.Report.SymbolRelatedToPreviousError (accessor);
                                        ec.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because a `{1}' accessor is inaccessible",
-                                               TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null));
+                                               TypeManager.GetFullNameSignature (spec), GetAccessorName (right_side != null));
                                } else {
-                                       ec.Report.SymbolRelatedToPreviousError (pi);
-                                       ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (pi), ec.Report);
+                                       ec.Report.SymbolRelatedToPreviousError (spec);
+                                       ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (spec), ec.Report);
                                }
                        }
 
@@ -8630,8 +8178,8 @@ namespace Mono.CSharp {
                            !TypeManager.IsInstantiationOfSameGenericType (instance_expr.Type, ec.CurrentType) &&
                            !TypeManager.IsNestedChildOf (ec.CurrentType, instance_expr.Type) &&
                            !TypeManager.IsSubclassOf (instance_expr.Type, ec.CurrentType)) {
-                               ec.Report.SymbolRelatedToPreviousError (accessor.MetaInfo);
-                               Error_CannotAccessProtected (ec, loc, accessor.MetaInfo, instance_expr.Type, ec.CurrentType);
+                               ec.Report.SymbolRelatedToPreviousError (accessor);
+                               Error_CannotAccessProtected (ec, loc, spec, instance_expr.Type, ec.CurrentType);
                                return null;
                        }
 
@@ -8649,12 +8197,12 @@ namespace Mono.CSharp {
                        if (prepared) {
                                prepared_value.Emit (ec);
                        } else {
-                               Invocation.EmitCall (ec, is_base_indexer, instance_expr, get,
+                               Invocation.EmitCall (ec, is_base_indexer, instance_expr, spec.Get,
                                        arguments, loc, false, false);
                        }
 
                        if (leave_copy) {
-                               ec.ig.Emit (OpCodes.Dup);
+                               ec.Emit (OpCodes.Dup);
                                temp = new LocalTemporary (Type);
                                temp.Store (ec);
                        }
@@ -8671,7 +8219,7 @@ namespace Mono.CSharp {
                        Expression value = set_expr;
 
                        if (prepared) {
-                               Invocation.EmitCall (ec, is_base_indexer, instance_expr, get,
+                               Invocation.EmitCall (ec, is_base_indexer, instance_expr, spec.Get,
                                        arguments, loc, true, false);
 
                                prepared_value = new LocalTemporary (type);
@@ -8680,7 +8228,7 @@ namespace Mono.CSharp {
                                prepared_value.Release (ec);
 
                                if (leave_copy) {
-                                       ec.ig.Emit (OpCodes.Dup);
+                                       ec.Emit (OpCodes.Dup);
                                        temp = new LocalTemporary (Type);
                                        temp.Store (ec);
                                }
@@ -8694,7 +8242,7 @@ namespace Mono.CSharp {
                        if (!prepared)
                                arguments.Add (new Argument (value));
 
-                       Invocation.EmitCall (ec, is_base_indexer, instance_expr, set, arguments, loc, false, prepared);
+                       Invocation.EmitCall (ec, is_base_indexer, instance_expr, spec.Set, arguments, loc, false, prepared);
                        
                        if (temp != null) {
                                temp.Emit (ec);
@@ -8704,7 +8252,7 @@ namespace Mono.CSharp {
                
                public override string GetSignatureForError ()
                {
-                       return TypeManager.CSharpSignature (get != null ? get.MetaInfo : set.MetaInfo, false);
+                       return spec.GetSignatureForError ();
                }
 
 #if NET_4_0
@@ -8714,7 +8262,7 @@ namespace Mono.CSharp {
                        var args = Arguments.MakeExpression (arguments, ctx).Concat (value);
 
                        return SLE.Expression.Block (
-                                       SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) set.MetaInfo, args),
+                                       SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) spec.Set.GetMetaInfo (), args),
                                        value [0]);
                }
 #endif
@@ -8722,21 +8270,7 @@ namespace Mono.CSharp {
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        var args = Arguments.MakeExpression (arguments, ctx);
-                       return SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) get.MetaInfo, args);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (get != null)
-                               storey.MutateGenericMethod (get);
-                       if (set != null)
-                               storey.MutateGenericMethod (set);
-
-                       instance_expr.MutateHoistedGenericType (storey);
-                       if (arguments != null)
-                               arguments.MutateHoistedGenericType (storey);
-
-                       type = storey.MutateType (type);
+                       return SLE.Expression.Call (instance_expr.MakeExpression (ctx), (MethodInfo) spec.Get.GetMetaInfo (), args);
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -8809,8 +8343,8 @@ namespace Mono.CSharp {
                Expression CommonResolve (ResolveContext ec)
                {
                        Expression member_lookup;
-                       Type current_type = ec.CurrentType;
-                       Type base_type = current_type.BaseType;
+                       TypeSpec current_type = ec.CurrentType;
+                       TypeSpec base_type = current_type.BaseType;
 
                        if (!This.IsThisAvailable (ec)) {
                                if (ec.IsStatic) {
@@ -8820,12 +8354,13 @@ namespace Mono.CSharp {
                                }
                                return null;
                        }
-                       
-                       member_lookup = MemberLookup (ec.Compiler, ec.CurrentType, null, base_type, Identifier,
-                                                     AllMemberTypes, AllBindingFlags, loc);
+
+                       var arity = args == null ? -1 : args.Count;
+                       member_lookup = MemberLookup (ec.Compiler, ec.CurrentType, null, base_type, Identifier, arity,
+                                                     MemberKind.All, BindingRestriction.AccessibleOnly, loc);
                        if (member_lookup == null) {
-                               Error_MemberLookupFailed (ec, ec.CurrentType, base_type, base_type, Identifier,
-                                       null, AllMemberTypes, AllBindingFlags);
+                               Error_MemberLookupFailed (ec, ec.CurrentType, base_type, base_type, Identifier, arity,
+                                       null, MemberKind.All, BindingRestriction.AccessibleOnly);
                                return null;
                        }
 
@@ -8952,7 +8487,7 @@ namespace Mono.CSharp {
                        loc = Location.Null;
                }
 
-               public EmptyExpression (Type t)
+               public EmptyExpression (TypeSpec t)
                {
                        type = t;
                        eclass = ExprClass.Value;
@@ -8983,7 +8518,7 @@ namespace Mono.CSharp {
                // instead of creating gazillions of EmptyExpressions.
                // (CanImplicitConversion uses it)
                //
-               public void SetType (Type t)
+               public void SetType (TypeSpec t)
                {
                        type = t;
                }
@@ -9032,7 +8567,7 @@ namespace Mono.CSharp {
                {
                        this.method = method;
                        this.source = source;
-                       type = TypeManager.TypeToCoreType (method.ReturnType);
+                       type = method.ReturnType;
                        loc = l;
                }
 
@@ -9053,7 +8588,7 @@ namespace Mono.CSharp {
                        
                protected override Expression DoResolve (ResolveContext ec)
                {
-                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (method.MetaInfo);
+                       ObsoleteAttribute oa = method.GetAttributeObsolete ();
                        if (oa != null)
                                AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc, ec.Report);
 
@@ -9064,23 +8599,17 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        source.Emit (ec);
-                       ec.ig.Emit (OpCodes.Call, (MethodInfo) method.MetaInfo);
+                       ec.Emit (OpCodes.Call, method);
                }
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.CSharpSignature (method.MetaInfo);
+                       return TypeManager.CSharpSignature (method);
                }
 
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
-                       return SLE.Expression.Convert (source.MakeExpression (ctx), type, (MethodInfo) method.MetaInfo);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       source.MutateHoistedGenericType (storey);
-                       storey.MutateGenericMethod (method);
+                       return SLE.Expression.Convert (source.MakeExpression (ctx), type.GetMetaInfo (), (MethodInfo) method.GetMetaInfo ());
                }
        }
 
@@ -9112,7 +8641,7 @@ namespace Mono.CSharp {
                        if (lexpr == null)
                                return null;
 
-                       Type ltype = lexpr.Type;
+                       TypeSpec ltype = lexpr.Type;
                        if ((dim.Length > 0) && (dim [0] == '?')) {
                                TypeExpr nullable = new Nullable.NullableType (lexpr, loc);
                                if (dim.Length > 1)
@@ -9129,7 +8658,7 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               if ((ltype.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+                               if (ltype.IsStatic) {
                                        ec.Compiler.Report.SymbolRelatedToPreviousError (ltype);
                                        ec.Compiler.Report.Error (719, loc, "Array elements cannot be of static type `{0}'", 
                                                TypeManager.CSharpName (ltype));
@@ -9156,22 +8685,17 @@ namespace Mono.CSharp {
                {
                        return left.GetSignatureForError () + dim;
                }
-
-               public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
-               {
-                       return ResolveAsBaseTerminal (ec, silent);
-               }               
        }
 
        public class FixedBufferPtr : Expression {
                Expression array;
 
-               public FixedBufferPtr (Expression array, Type array_type, Location l)
+               public FixedBufferPtr (Expression array, TypeSpec array_type, Location l)
                {
                        this.array = array;
                        this.loc = l;
 
-                       type = TypeManager.GetPointerType (array_type);
+                       type = PointerContainer.MakeType (array_type);
                        eclass = ExprClass.Value;
                }
 
@@ -9202,9 +8726,9 @@ namespace Mono.CSharp {
        // for fixed (char *pa = a)
        //
        public class ArrayPtr : FixedBufferPtr {
-               Type array_type;
+               TypeSpec array_type;
                
-               public ArrayPtr (Expression array, Type array_type, Location l):
+               public ArrayPtr (Expression array, TypeSpec array_type, Location l):
                        base (array, array_type, l)
                {
                        this.array_type = array_type;
@@ -9214,9 +8738,8 @@ namespace Mono.CSharp {
                {
                        base.Emit (ec);
                        
-                       ILGenerator ig = ec.ig;
-                       IntLiteral.EmitInt (ig, 0);
-                       ig.Emit (OpCodes.Ldelema, array_type);
+                       ec.EmitInt (0);
+                       ec.Emit (OpCodes.Ldelema, array_type);
                }
        }
 
@@ -9246,11 +8769,11 @@ namespace Mono.CSharp {
                        var expr_type = child.Type;
 
                        if (expr_type == TypeManager.uint32_type)
-                               ec.ig.Emit (OpCodes.Conv_U);
+                               ec.Emit (OpCodes.Conv_U);
                        else if (expr_type == TypeManager.int64_type)
-                               ec.ig.Emit (OpCodes.Conv_Ovf_I);
+                               ec.Emit (OpCodes.Conv_Ovf_I);
                        else if (expr_type == TypeManager.uint64_type)
-                               ec.ig.Emit (OpCodes.Conv_Ovf_I_Un);
+                               ec.Emit (OpCodes.Conv_Ovf_I_Un);
                        else
                                throw new InternalErrorException ("Cannot emit cast to unknown array element type", type);
                }
@@ -9260,7 +8783,7 @@ namespace Mono.CSharp {
        // Implements the `stackalloc' keyword
        //
        public class StackAlloc : Expression {
-               Type otype;
+               TypeSpec otype;
                Expression t;
                Expression count;
                
@@ -9306,7 +8829,7 @@ namespace Mono.CSharp {
                        if (!TypeManager.VerifyUnmanaged (ec.Compiler, otype, loc))
                                return null;
 
-                       type = TypeManager.GetPointerType (otype);
+                       type = PointerContainer.MakeType (otype);
                        eclass = ExprClass.Value;
 
                        return this;
@@ -9315,17 +8838,16 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        int size = GetTypeSize (otype);
-                       ILGenerator ig = ec.ig;
 
                        count.Emit (ec);
 
                        if (size == 0)
-                               ig.Emit (OpCodes.Sizeof, otype);
+                               ec.Emit (OpCodes.Sizeof, otype);
                        else
-                               IntConstant.EmitInt (ig, size);
+                               ec.EmitInt (size);
 
-                       ig.Emit (OpCodes.Mul_Ovf_Un);
-                       ig.Emit (OpCodes.Localloc);
+                       ec.Emit (OpCodes.Mul_Ovf_Un);
+                       ec.Emit (OpCodes.Localloc);
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -9376,7 +8898,7 @@ namespace Mono.CSharp {
                                return EmptyExpressionStatement.Instance;
                        
                        MemberExpr me = MemberLookupFinal (ec, ec.CurrentInitializerVariable.Type, ec.CurrentInitializerVariable.Type,
-                               Name, MemberTypes.Field | MemberTypes.Property, BindingFlags.Public | BindingFlags.Instance, loc) as MemberExpr;
+                               Name, 0, MemberKind.Field | MemberKind.Property, BindingRestriction.AccessibleOnly | BindingRestriction.InstanceOnly, loc) as MemberExpr;
 
                        if (me == null)
                                return null;
@@ -9411,10 +8933,10 @@ namespace Mono.CSharp {
                        return expr;
                }
 
-               protected override Expression Error_MemberLookupFailed (ResolveContext ec, Type type, MemberInfo[] members)
+               protected override MemberExpr Error_MemberLookupFailed (ResolveContext ec, TypeSpec type, IList<MemberSpec> members)
                {
-                       MemberInfo member = members [0];
-                       if (member.MemberType != MemberTypes.Property && member.MemberType != MemberTypes.Field)
+                       var member = members.First ();
+                       if (member.Kind != MemberKind.Property && member.Kind != MemberKind.Field)
                                ec.Report.Error (1913, loc, "Member `{0}' cannot be initialized. An object " +
                                        "initializer may only be used for fields, or properties", TypeManager.GetFullNameSignature (member));
                        else
@@ -9453,7 +8975,7 @@ namespace Mono.CSharp {
                        {
                        }
 
-                       protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, Type type, string name)
+                       protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, TypeSpec type, string name)
                        {
                                if (TypeManager.HasElementType (type))
                                        return;
@@ -9572,7 +9094,7 @@ namespace Mono.CSharp {
                                                initializer.Resolve (ec);
                                                throw new InternalErrorException ("This line should never be reached");
                                        } else {
-                                               if (!TypeManager.ImplementsInterface (ec.CurrentInitializerVariable.Type, TypeManager.ienumerable_type)) {
+                                               if (!ec.CurrentInitializerVariable.Type.ImplementsInterface (TypeManager.ienumerable_type)) {
                                                        ec.Report.Error (1922, loc, "A field or property `{0}' cannot be initialized with a collection " +
                                                                "object initializer because type `{1}' does not implement `{2}' interface",
                                                                ec.CurrentInitializerVariable.GetSignatureForError (),
@@ -9629,12 +9151,6 @@ namespace Mono.CSharp {
                        foreach (ExpressionStatement e in initializers)
                                e.EmitStatement (ec);
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       foreach (Expression e in initializers)
-                               e.MutateHoistedGenericType (storey);
-               }
        }
        
        //
@@ -9785,17 +9301,11 @@ namespace Mono.CSharp {
                                return !initializers.IsEmpty;
                        }
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       base.MutateHoistedGenericType (storey);
-                       initializers.MutateHoistedGenericType (storey);
-               }
        }
 
        public class NewAnonymousType : New
        {
-               static readonly IList<AnonymousTypeParameter> EmptyParameters = Array.AsReadOnly (new AnonymousTypeParameter[0]);
+               static readonly AnonymousTypeParameter[] EmptyParameters = new AnonymousTypeParameter[0];
 
                List<AnonymousTypeParameter> parameters;
                readonly TypeContainer parent;
@@ -9829,7 +9339,9 @@ namespace Mono.CSharp {
                        if (type == null)
                                return null;
 
+                       type.CreateType ();
                        type.DefineType ();
+                       type.ResolveTypeParameters ();
                        type.Define ();
                        type.EmitType ();
                        if (ec.Report.Errors == 0)
@@ -9846,7 +9358,7 @@ namespace Mono.CSharp {
 
                        var init = new ArrayInitializer (parameters.Count, loc);
                        foreach (Property p in anonymous_type.Properties)
-                               init.Add (new TypeOfMethod (Import.CreateMethod (TypeBuilder.GetMethod (type, p.GetBuilder)), loc));
+                               init.Add (new TypeOfMethod (MemberCache.GetMember (type, p.Get.Spec), loc));
 
                        var ctor_args = new ArrayInitializer (Arguments.Count, loc);
                        foreach (Argument a in Arguments)
@@ -9869,7 +9381,7 @@ namespace Mono.CSharp {
 
                        if (parameters == null) {
                                anonymous_type = CreateAnonymousType (ec, EmptyParameters);
-                               RequestedType = new TypeExpression (anonymous_type.TypeBuilder, loc);
+                               RequestedType = new TypeExpression (anonymous_type.Definition, loc);
                                return base.DoResolve (ec);
                        }
 
@@ -9894,7 +9406,7 @@ namespace Mono.CSharp {
                        if (anonymous_type == null)
                                return null;
 
-                       RequestedType = new GenericTypeExpr (anonymous_type.TypeBuilder, new TypeArguments (t_args), loc);
+                       RequestedType = new GenericTypeExpr (anonymous_type.Definition, new TypeArguments (t_args), loc);
                        return base.DoResolve (ec);
                }
        }
index 8f996ac08cb50bd8dca89ce7033786458c334032..e43bf5ba4c53d5db0981fd7f1a96fc28487379f2 100644 (file)
@@ -51,7 +51,7 @@ namespace Mono.CSharp
                        }
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.FieldOffset) {
                                status |= Status.HAS_OFFSET;
@@ -91,26 +91,36 @@ namespace Mono.CSharp
                                return;
                        }
 
-                       FieldBuilder.SetCustomAttribute (ctor, cdata);
+                       FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
                protected override bool CheckBase ()
                {
                        if (!base.CheckBase ())
                                return false;
-                       MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
+
+                       MemberSpec candidate;
+                       var conflict_symbol = MemberCache.FindBaseMember (this, out candidate);
+                       if (conflict_symbol == null)
+                               conflict_symbol = candidate;
+
                        if (conflict_symbol == null) {
                                if ((ModFlags & Modifiers.NEW) != 0) {
-                                       Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
+                                       Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+                                               GetSignatureForError ());
                                }
-                               return true;
-                       }
-                       if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) {
-                               Report.SymbolRelatedToPreviousError (conflict_symbol);
-                               Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
-                                       GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
+                       } else {
+                               if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) {
+                                       Report.SymbolRelatedToPreviousError (conflict_symbol);
+                                       Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
+                                               GetSignatureForError (), conflict_symbol.GetSignatureForError ());
+                               }
+
+                               if (conflict_symbol.IsAbstract) {
+                                       Report.SymbolRelatedToPreviousError (conflict_symbol);
+                                       Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
+                                               GetSignatureForError (), conflict_symbol.GetSignatureForError ());
+                               }
                        }
  
                        return true;
@@ -125,12 +135,11 @@ namespace Mono.CSharp
                {
                        base.DoMemberTypeDependentChecks ();
 
-                       if (TypeManager.IsGenericParameter (MemberType))
+                       if (MemberType.IsGenericParameter)
                                return;
 
-                       if (MemberType.IsSealed && MemberType.IsAbstract) {
+                       if (MemberType.IsStatic)
                                Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType, Report);
-                       }
 
                        CheckBase ();
                        IsTypePermitted ();
@@ -145,13 +154,13 @@ namespace Mono.CSharp
 
                public override void Emit ()
                {
-                       if (TypeManager.IsDynamicType (member_type)) {
+                       if (member_type == InternalType.Dynamic) {
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (FieldBuilder);
                        } else {
                                var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
                                if (trans_flags != null) {
                                        var pa = PredefinedAttributes.Get.DynamicTransform;
-                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type, 1))) {
                                                FieldBuilder.SetCustomAttribute (new CustomAttributeBuilder (pa.Constructor, new object[] { trans_flags }));
                                        }
                                }
@@ -171,7 +180,7 @@ namespace Mono.CSharp
                        base.Emit ();
                }
 
-               public static void Error_VariableOfStaticClass (Location loc, string variable_name, Type static_class, Report Report)
+               public static void Error_VariableOfStaticClass (Location loc, string variable_name, TypeSpec static_class, Report Report)
                {
                        Report.SymbolRelatedToPreviousError (static_class);
                        Report.Error (723, loc, "`{0}': cannot declare variables of static types",
@@ -189,15 +198,6 @@ namespace Mono.CSharp
                        }
                }
 
-               protected virtual bool IsFieldClsCompliant {
-                       get {
-                               if (FieldBuilder == null)
-                                       return true;
-
-                               return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
-                       }
-               }
-
                public FieldSpec Spec {
                        get { return spec; }
                }
@@ -214,56 +214,90 @@ namespace Mono.CSharp
                        if (!base.VerifyClsCompliance ())
                                return false;
 
-                       if (!IsFieldClsCompliant) {
+                       if (!MemberType.IsCLSCompliant () || this is FixedField) {
                                Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
                                        GetSignatureForError ());
                        }
                        return true;
                }
-
-               public void SetAssigned ()
-               {
-                       caching_flags |= Flags.IsAssigned;
-               }
        }
 
        //
        // Field specification
        //
-       public class FieldSpec : MemberSpec
+       public class FieldSpec : MemberSpec, IInterfaceMemberSpec
        {
-               FieldInfo info;
+               FieldInfo metaInfo;
+               TypeSpec memberType;
 
-               public FieldSpec (IMemberDefinition definition, FieldInfo info, Modifiers modifiers)
-                       : base (MemberKind.Field, definition, info.Name, modifiers)
+               public FieldSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo info, Modifiers modifiers)
+                       : base (MemberKind.Field, declaringType, definition, modifiers)
                {
-                       this.info = info;
+                       this.metaInfo = info;
+                       this.memberType = memberType;
                }
 
-               public bool IsReadOnly {
-                       get { return (Modifiers & Modifiers.READONLY) != 0; }
-               }
+#region Properties
 
-               public FieldInfo MetaInfo {
+               public bool IsReadOnly {
                        get {
-                               return info;
-                       }
-                       set {
-                               info = value;
+                               return (Modifiers & Modifiers.READONLY) != 0;
                        }
                }
 
-               public override Type DeclaringType {
+               public TypeSpec MemberType {
                        get {
-                               return MetaInfo.DeclaringType;
+                               return memberType;
                        }
                }
 
-               // Obsolete
-               public Type FieldType {
-                       get {
-                                return MetaInfo.FieldType;
+#endregion
+
+               public FieldInfo GetMetaInfo ()
+               {
+                       if ((state & StateFlags.PendingMetaInflate) != 0) {
+                               var decl_meta = DeclaringType.GetMetaInfo ();
+                               if (DeclaringType.IsTypeBuilder) {
+                                       metaInfo = TypeBuilder.GetField (decl_meta, metaInfo);
+                               } else {
+                                       var orig_token = metaInfo.MetadataToken;
+                                       metaInfo = decl_meta.GetField (Name);
+                                       if (metaInfo.MetadataToken != orig_token)
+                                               throw new NotImplementedException ("Resolved to wrong meta token");
+
+                                       // What a stupid API, does not work because field handle is imported
+                                       // metaInfo = FieldInfo.GetFieldFromHandle (metaInfo.FieldHandle, DeclaringType.MetaInfo.TypeHandle);
+                               }
+
+                               state &= ~StateFlags.PendingMetaInflate;
                        }
+
+                       return metaInfo;
+               }
+
+               public override MemberSpec InflateMember (TypeParameterInflator inflator)
+               {
+                       var fs = (FieldSpec) base.InflateMember (inflator);
+                       fs.memberType = inflator.Inflate (memberType);
+                       return fs;
+               }
+
+               public FieldSpec Mutate (TypeParameterMutator mutator)
+               {
+                       var decl = DeclaringType;
+                       if (DeclaringType.IsGenericOrParentIsGeneric)
+                               decl = mutator.Mutate (decl);
+
+                       if (decl == DeclaringType)
+                               return this;
+
+                       var fs = (FieldSpec) MemberwiseClone ();
+                       fs.declaringType = decl;
+                       fs.state |= StateFlags.PendingMetaInflate;
+
+                       // Gets back FieldInfo in case of metaInfo was inflated
+                       fs.metaInfo = MemberCache.GetMember (DeclaringType.GetDefinition (), this).metaInfo;
+                       return fs;
                }
        }
 
@@ -313,17 +347,16 @@ namespace Mono.CSharp
                        // Create nested fixed buffer container
                        string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
                        fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name, Parent.Module.DefaultCharSetType |
-                               TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
-                       
-                       var element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
+                               TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type.GetMetaInfo ());
+
+                       fixed_buffer_type.DefineField (FixedElementName, MemberType.GetMetaInfo (), FieldAttributes.Public);
                        RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
                        
                        FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, ModifiersExtensions.FieldAttr (ModFlags));
-                       spec = new FixedFieldSpec (this, FieldBuilder, element, ModFlags);
-
-                       Parent.MemberCache.AddMember (FieldBuilder, spec);
-                       TypeManager.RegisterFieldBase (FieldBuilder, this);
+                       var element_spec = new FieldSpec (null, this, MemberType, FieldBuilder, ModFlags);
+                       spec = new FixedFieldSpec (Parent.Definition, this, FieldBuilder, element_spec, ModFlags);
 
+                       Parent.MemberCache.AddMember (spec);
                        return true;
                }
 
@@ -381,8 +414,10 @@ namespace Mono.CSharp
                                        return;
 
                        // TODO: It's not cleared
-                       if (fi == null)
-                               fi = new FieldInfo[] { pa.Type.GetField ("Size") };
+                       if (fi == null) {
+                               var field = (FieldSpec) MemberCache.FindMember (pa.Type, MemberFilter.Field ("Size", null), BindingRestriction.DeclaredOnly);
+                               fi = new FieldInfo[] { field.GetMetaInfo () };
+                       }
 
                        object[] fi_val = new object[] { buffer_size };
                        cab = new CustomAttributeBuilder (pa.Constructor,
@@ -400,16 +435,10 @@ namespace Mono.CSharp
                                !pa.ResolveConstructor (Location, TypeManager.type_type, TypeManager.int32_type))
                                return;
 
-                       cab = new CustomAttributeBuilder (pa.Constructor, new object[] { MemberType, buffer_size });
+                       cab = new CustomAttributeBuilder (pa.Constructor, new object[] { MemberType.GetMetaInfo (), buffer_size });
                        FieldBuilder.SetCustomAttribute (cab);
                }
 
-               protected override bool IsFieldClsCompliant {
-                       get {
-                               return false;
-                       }
-               }
-
                public void SetCharSet (TypeAttributes ta)
                {
                        TypeAttributes cta = fixed_buffer_type.Attributes;
@@ -434,23 +463,26 @@ namespace Mono.CSharp
 
        class FixedFieldSpec : FieldSpec
        {
-               readonly FieldInfo element;
+               readonly FieldSpec element;
 
-               public FixedFieldSpec (IMemberDefinition definition, FieldInfo info, FieldInfo element, Modifiers modifiers)
-                        : base (definition, info, modifiers)
+               public FixedFieldSpec (TypeSpec declaringType, IMemberDefinition definition, FieldInfo info, FieldSpec element, Modifiers modifiers)
+                       : base (declaringType, definition, element.MemberType, info, modifiers)
                {
                        this.element = element;
+
+                       // It's never CLS-Compliant
+                       state &= ~StateFlags.CLSCompliant_Undetected;
                }
 
-               public FieldInfo Element {
+               public FieldSpec Element {
                        get {
                                return element;
                        }
                }
 
-               public Type ElementType {
+               public TypeSpec ElementType {
                        get {
-                               return element.FieldType;
+                               return MemberType;
                        }
                }
        }
@@ -492,36 +524,9 @@ namespace Mono.CSharp
                                MemberType == TypeManager.intptr_type || MemberType == TypeManager.uintptr_type)
                                return true;
 
-                       if (TypeManager.IsEnumType (MemberType))
-                               return true;
-
-                       return false;
-               }
-
-               bool CheckStructLayout (Type type, bool isStatic)
-               {
-                       if (TypeManager.IsBuiltinType (type))
+                       if (MemberType.IsEnum)
                                return true;
 
-                       if (isStatic) {
-                               if (!TypeManager.IsValueType (type) || TypeManager.IsEqual (type, Parent.TypeBuilder))
-                                       return true;
-                       }
-
-                       if (!TypeManager.IsEqual (TypeManager.DropGenericTypeArguments (type), Parent.TypeBuilder)) {
-                               if (!TypeManager.IsGenericType (type))
-                                       return true;
-
-                               foreach (Type t in TypeManager.GetTypeArguments (type)) {
-                                       if (!CheckStructLayout (t, false))
-                                               return false;
-                               }
-                               return true;
-                       }
-                       
-                       Report.Error (523, Location,
-                               "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
-                               GetSignatureForError (), TypeManager.CSharpName (MemberType));
                        return false;
                }
 
@@ -538,20 +543,18 @@ namespace Mono.CSharp
                                                        "System.Runtime.CompilerServices", "IsVolatile", MemberKind.Class, true);
 
                                        if (TypeManager.isvolatile_type != null)
-                                               required_modifier = new Type [] { TypeManager.isvolatile_type };
+                                               required_modifier = new Type[] { TypeManager.isvolatile_type.GetMetaInfo () };
                                }
 
                                FieldBuilder = Parent.TypeBuilder.DefineField (
-                                       Name, MemberType, required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags));
+                                       Name, member_type.GetMetaInfo (), required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags));
 
-                               spec = new FieldSpec (this, FieldBuilder, ModFlags);
+                               spec = new FieldSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags);
 
                                // Don't cache inaccessible fields
                                if ((ModFlags & Modifiers.BACKING_FIELD) == 0) {
-                                       Parent.MemberCache.AddMember (FieldBuilder, spec);
+                                       Parent.MemberCache.AddMember (spec);
                                }
-
-                               TypeManager.RegisterFieldBase (FieldBuilder, this);
                        }
                        catch (ArgumentException) {
                                Report.RuntimeMissingSupport (Location, "`void' or `void*' field type");
@@ -561,9 +564,6 @@ namespace Mono.CSharp
                        if (initializer != null) {
                                ((TypeContainer) Parent).RegisterFieldForInitialization (this,
                                        new FieldInitializer (this, initializer, this));
-                       } else {
-                               if (Parent.PartialContainer.Kind == MemberKind.Struct)
-                                       CheckStructLayout (member_type, (ModFlags & Modifiers.STATIC) != 0);
                        }
 
                        return true;
@@ -571,6 +571,9 @@ namespace Mono.CSharp
 
                protected override void DoMemberTypeDependentChecks ()
                {
+                       if ((ModFlags & Modifiers.BACKING_FIELD) != 0)
+                               return;
+
                        base.DoMemberTypeDependentChecks ();
 
                        if ((ModFlags & Modifiers.VOLATILE) != 0) {
index 035574ba5fe3184f8e5a43b7bee71de114235130..bc35e3591e9925c42d1eadcd95332a78336a3b06 100644 (file)
@@ -1014,7 +1014,7 @@ namespace Mono.CSharp
        // </summary>
        public class TypeInfo
        {
-               public readonly Type Type;
+               public readonly TypeSpec Type;
 
                // <summary>
                //   Total number of bits a variable of this type consumes in the flow vector.
@@ -1043,7 +1043,7 @@ namespace Mono.CSharp
                public TypeInfo[] SubStructInfo;
 
                readonly StructInfo struct_info;
-               private static Dictionary<Type, TypeInfo> type_hash;
+               private static Dictionary<TypeSpec, TypeInfo> type_hash;
                
                static TypeInfo ()
                {
@@ -1052,11 +1052,11 @@ namespace Mono.CSharp
                
                public static void Reset ()
                {
-                       type_hash = new Dictionary<Type, TypeInfo> ();
-                       StructInfo.field_type_hash = new Dictionary<Type, StructInfo> ();
+                       type_hash = new Dictionary<TypeSpec, TypeInfo> ();
+                       StructInfo.field_type_hash = new Dictionary<TypeSpec, StructInfo> ();
                }
 
-               public static TypeInfo GetTypeInfo (Type type)
+               public static TypeInfo GetTypeInfo (TypeSpec type)
                {
                        TypeInfo info;
                        if (type_hash.TryGetValue (type, out info))
@@ -1070,15 +1070,15 @@ namespace Mono.CSharp
                public static TypeInfo GetTypeInfo (TypeContainer tc)
                {
                        TypeInfo info;
-                       if (type_hash.TryGetValue (tc.TypeBuilder, out info))
+                       if (type_hash.TryGetValue (tc.Definition, out info))
                                return info;
 
                        info = new TypeInfo (tc);
-                       type_hash.Add (tc.TypeBuilder, info);
+                       type_hash.Add (tc.Definition, info);
                        return info;
                }
 
-               private TypeInfo (Type type)
+               private TypeInfo (TypeSpec type)
                {
                        this.Type = type;
 
@@ -1097,7 +1097,7 @@ namespace Mono.CSharp
 
                private TypeInfo (TypeContainer tc)
                {
-                       this.Type = tc.TypeBuilder;
+                       this.Type = tc.Definition;
 
                        struct_info = StructInfo.GetStructInfo (tc);
                        if (struct_info != null) {
@@ -1154,15 +1154,14 @@ namespace Mono.CSharp
                                var field = struct_info.Fields [i];
 
                                if (!branching.IsFieldAssigned (vi, field.Name)) {
-                                       FieldBase fb = TypeManager.GetField (field.MetaInfo);
-                                       if (fb is Property.BackingField) {
+                                       if (field.MemberDefinition is Property.BackingField) {
                                                ec.Report.Error (843, loc,
                                                        "An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling default contructor",
-                                                       fb.GetSignatureForError ());
+                                                       field.GetSignatureForError ());
                                        } else {
                                                ec.Report.Error (171, loc,
                                                        "Field `{0}' must be fully assigned before control leaves the constructor",
-                                                       TypeManager.GetFullNameSignature (field.MetaInfo));
+                                                       field.GetSignatureForError ());
                                        }
                                        ok = false;
                                }
@@ -1178,7 +1177,7 @@ namespace Mono.CSharp
                }
 
                class StructInfo {
-                       public readonly Type Type;
+                       public readonly TypeSpec Type;
                        public readonly FieldSpec[] Fields;
                        public readonly TypeInfo[] StructFields;
                        public readonly int Count;
@@ -1188,7 +1187,7 @@ namespace Mono.CSharp
                        public readonly int TotalLength;
                        public readonly bool HasStructFields;
 
-                       public static Dictionary<Type, StructInfo> field_type_hash;
+                       public static Dictionary<TypeSpec, StructInfo> field_type_hash;
                        private Dictionary<string, TypeInfo> struct_field_hash;
                        private Dictionary<string, int> field_hash;
 
@@ -1196,64 +1195,39 @@ namespace Mono.CSharp
 
                        // Private constructor.  To save memory usage, we only need to create one instance
                        // of this class per struct type.
-                       private StructInfo (Type type)
+                       private StructInfo (TypeSpec type)
                        {
                                this.Type = type;
 
                                field_type_hash.Add (type, this);
 
-                               if (TypeManager.IsBeingCompiled (type)) {
-                                       TypeContainer tc = TypeManager.LookupTypeContainer (TypeManager.DropGenericTypeArguments (type));
-
-                                       var public_fields = new List<FieldSpec> ();
-                                       var non_public_fields = new List<FieldSpec> ();
-
-                                       //
-                                       // TODO: tc != null is needed because FixedBuffers are not cached
-                                       //
-                                       if (tc != null) {
-                                               var fields = tc.Fields;
-
-                                               if (fields != null) {
-                                                       foreach (FieldBase field in fields) {
-                                                               if ((field.ModFlags & Modifiers.STATIC) != 0)
-                                                                       continue;
-                                                               if ((field.ModFlags & Modifiers.PUBLIC) != 0)
-                                                                       public_fields.Add (field.Spec);
-                                                               else
-                                                                       non_public_fields.Add (field.Spec);
-                                                       }
-                                               }
-                                       }
+                               TypeContainer tc = type.MemberDefinition as TypeContainer;
 
-                                       CountPublic = public_fields.Count;
-                                       CountNonPublic = non_public_fields.Count;
-                                       Count = CountPublic + CountNonPublic;
+                               var public_fields = new List<FieldSpec> ();
+                               var non_public_fields = new List<FieldSpec> ();
 
-                                       Fields = new FieldSpec [Count];
-                                       public_fields.CopyTo (Fields, 0);
-                                       non_public_fields.CopyTo (Fields, CountPublic);
-                               } else if (type is GenericTypeParameterBuilder) {
-                                       CountPublic = CountNonPublic = Count = 0;
-
-                                       Fields = new FieldSpec [0];
-                               } else {
-                                       FieldInfo[] public_fields = type.GetFields (
-                                               BindingFlags.Instance|BindingFlags.Public);
-                                       FieldInfo[] non_public_fields = type.GetFields (
-                                               BindingFlags.Instance|BindingFlags.NonPublic);
+                               if (tc != null) {
+                                       var fields = tc.Fields;
 
-                                       CountPublic = public_fields.Length;
-                                       CountNonPublic = non_public_fields.Length;
-                                       Count = CountPublic + CountNonPublic;
+                                       if (fields != null) {
+                                               foreach (FieldBase field in fields) {
+                                                       if ((field.ModFlags & Modifiers.STATIC) != 0)
+                                                               continue;
+                                                       if ((field.ModFlags & Modifiers.PUBLIC) != 0)
+                                                               public_fields.Add (field.Spec);
+                                                       else
+                                                               non_public_fields.Add (field.Spec);
+                                               }
+                                       }
+                               }
 
-                                       Fields = new FieldSpec [Count];
-                                       for (int i = 0; i < CountPublic; ++i)
-                                               Fields [i] = Import.CreateField (public_fields[i]);
+                               CountPublic = public_fields.Count;
+                               CountNonPublic = non_public_fields.Count;
+                               Count = CountPublic + CountNonPublic;
 
-                                       for (int i = 0; i < CountNonPublic; ++i)
-                                               Fields [i + CountPublic] = Import.CreateField (non_public_fields[i]);
-                               }
+                               Fields = new FieldSpec[Count];
+                               public_fields.CopyTo (Fields, 0);
+                               non_public_fields.CopyTo (Fields, CountPublic);
 
                                struct_field_hash = new Dictionary<string, TypeInfo> ();
                                field_hash = new Dictionary<string, int> ();
@@ -1267,14 +1241,10 @@ namespace Mono.CSharp
                                for (int i = 0; i < Count; i++) {
                                        var field = Fields [i];
 
-                                       sinfo [i] = GetStructInfo (field.FieldType);
+                                       sinfo [i] = GetStructInfo (field.MemberType);
                                        if (sinfo [i] == null)
                                                field_hash.Add (field.Name, ++Length);
                                        else if (sinfo [i].InTransit) {
-                                               RootContext.ToplevelTypes.Compiler.Report.Error (523, String.Format (
-                                                                     "Struct member `{0}.{1}' of type `{2}' causes " +
-                                                                     "a cycle in the structure layout",
-                                                                     type, field.Name, sinfo [i].Type));
                                                sinfo [i] = null;
                                                return;
                                        }
@@ -1317,7 +1287,7 @@ namespace Mono.CSharp
                                return null;
                        }
 
-                       public static StructInfo GetStructInfo (Type type)
+                       public static StructInfo GetStructInfo (TypeSpec type)
                        {
                                if (!TypeManager.IsValueType (type) || TypeManager.IsEnumType (type) ||
                                    TypeManager.IsBuiltinType (type))
@@ -1336,10 +1306,10 @@ namespace Mono.CSharp
                        public static StructInfo GetStructInfo (TypeContainer tc)
                        {
                                StructInfo info;
-                               if (field_type_hash.TryGetValue (tc.TypeBuilder, out info))
+                               if (field_type_hash.TryGetValue (tc.Definition, out info))
                                        return info;
 
-                               return new StructInfo (tc.TypeBuilder);
+                               return new StructInfo (tc.Definition);
                        }
                }
        }
@@ -1381,7 +1351,7 @@ namespace Mono.CSharp
                        get { return is_ever_assigned; }
                }
 
-               protected VariableInfo (string name, Type type, int offset)
+               protected VariableInfo (string name, TypeSpec type, int offset)
                {
                        this.Name = name;
                        this.Offset = offset;
index 284d6304bdcc5f1107ca19053c7f0cf4f18009eb..53b5d841426cf94482cdb50f48dcb70a239a5582 100644 (file)
@@ -16,177 +16,9 @@ using System.Reflection.Emit;
 using System.Globalization;
 using System.Collections.Generic;
 using System.Text;
+using System.Linq;
        
 namespace Mono.CSharp {
-
-       /// <summary>
-       ///   Abstract base class for type parameter constraints.
-       ///   The type parameter can come from a generic type definition or from reflection.
-       /// </summary>
-       public abstract class GenericConstraints {
-               public abstract GenericParameterAttributes Attributes {
-                       get;
-               }
-
-               public bool HasConstructorConstraint {
-                       get { return (Attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0; }
-               }
-
-               public bool HasReferenceTypeConstraint {
-                       get { return (Attributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0; }
-               }
-
-               public bool HasValueTypeConstraint {
-                       get { return (Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; }
-               }
-
-               public virtual bool HasClassConstraint {
-                       get { return ClassConstraint != null; }
-               }
-
-               public abstract Type ClassConstraint {
-                       get;
-               }
-
-               public abstract Type[] InterfaceConstraints {
-                       get;
-               }
-
-               public abstract Type EffectiveBaseClass {
-                       get;
-               }
-
-               // <summary>
-               //   Returns whether the type parameter is "known to be a reference type".
-               // </summary>
-               public virtual bool IsReferenceType {
-                       get {
-                               if (HasReferenceTypeConstraint)
-                                       return true;
-                               if (HasValueTypeConstraint)
-                                       return false;
-
-                               if (ClassConstraint != null) {
-                                       if (ClassConstraint.IsValueType)
-                                               return false;
-
-                                       if (ClassConstraint != TypeManager.object_type)
-                                               return true;
-                               }
-
-                               foreach (Type t in InterfaceConstraints) {
-                                       if (!t.IsGenericParameter)
-                                               continue;
-
-                                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
-                                       if ((gc != null) && gc.IsReferenceType)
-                                               return true;
-                               }
-
-                               return false;
-                       }
-               }
-
-               // <summary>
-               //   Returns whether the type parameter is "known to be a value type".
-               // </summary>
-               public virtual bool IsValueType {
-                       get {
-                               if (HasValueTypeConstraint)
-                                       return true;
-                               if (HasReferenceTypeConstraint)
-                                       return false;
-
-                               if (ClassConstraint != null) {
-                                       if (!TypeManager.IsValueType (ClassConstraint))
-                                               return false;
-
-                                       if (ClassConstraint != TypeManager.value_type)
-                                               return true;
-                               }
-
-                               foreach (Type t in InterfaceConstraints) {
-                                       if (!t.IsGenericParameter)
-                                               continue;
-
-                                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
-                                       if ((gc != null) && gc.IsValueType)
-                                               return true;
-                               }
-
-                               return false;
-                       }
-               }
-       }
-
-       public class ReflectionConstraints : GenericConstraints
-       {
-               GenericParameterAttributes attrs;
-               Type base_type;
-               Type class_constraint;
-               Type[] iface_constraints;
-
-               public static GenericConstraints GetConstraints (Type t)
-               {
-                       Type[] constraints = t.GetGenericParameterConstraints ();
-                       GenericParameterAttributes attrs = t.GenericParameterAttributes;
-                       if (constraints.Length == 0 && attrs == GenericParameterAttributes.None)
-                               return null;
-                       return new ReflectionConstraints (t.Name, constraints, attrs);
-               }
-
-               private ReflectionConstraints (string name, Type[] constraints, GenericParameterAttributes attrs)
-               {
-                       this.attrs = attrs;
-
-                       int interface_constraints_pos = 0;
-                       if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) {
-                               base_type = TypeManager.value_type;
-                               interface_constraints_pos = 1;
-                       } else if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0) {
-                               if (constraints.Length > 0 && constraints[0].IsClass) {
-                                       class_constraint = base_type = constraints[0];
-                                       interface_constraints_pos = 1;
-                               } else {
-                                       base_type = TypeManager.object_type;
-                               }
-                       } else {
-                               base_type = TypeManager.object_type;
-                       }
-
-                       if (constraints.Length > interface_constraints_pos) {
-                               if (interface_constraints_pos == 0) {
-                                       iface_constraints = constraints;
-                               } else {
-                                       iface_constraints = new Type[constraints.Length - interface_constraints_pos];
-                                       Array.Copy (constraints, interface_constraints_pos, iface_constraints, 0, iface_constraints.Length);
-                               }
-                       } else {
-                               iface_constraints = Type.EmptyTypes;
-                       }
-               }
-
-               public override GenericParameterAttributes Attributes
-               {
-                       get { return attrs; }
-               }
-
-               public override Type ClassConstraint
-               {
-                       get { return class_constraint; }
-               }
-
-               public override Type EffectiveBaseClass
-               {
-                       get { return base_type; }
-               }
-
-               public override Type[] InterfaceConstraints
-               {
-                       get { return iface_constraints; }
-               }
-       }
-
        public enum Variance
        {
                //
@@ -225,26 +57,14 @@ namespace Mono.CSharp {
        //
        // A set of parsed constraints for a type parameter
        //
-       public class Constraints : GenericConstraints
+       public class Constraints
        {
                SimpleMemberName tparam;
                List<FullNamedExpression> constraints;
                Location loc;
-               GenericParameterAttributes attrs;
-               TypeExpr class_constraint;
-               List<TypeExpr> iface_constraints;
-               List<TypeExpr> type_param_constraints;
-               int num_constraints;
-               Type class_constraint_type;
-               Type[] iface_constraint_types;
-               Type effective_base_type;
                bool resolved;
-               bool resolved_types;
+               bool resolving;
                
-               //
-               // name is the identifier, constraints is an arraylist of
-               // Expressions (with types) or `true' for the constructor constraint.
-               // 
                public Constraints (SimpleMemberName tparam, List<FullNamedExpression> constraints, Location loc)
                {
                        this.tparam = tparam;
@@ -254,6 +74,12 @@ namespace Mono.CSharp {
 
                #region Properties
 
+               public Location Location {
+                       get {
+                               return loc;
+                       }
+               }
+
                public SimpleMemberName TypeParameter {
                        get {
                                return tparam;
@@ -262,473 +88,407 @@ namespace Mono.CSharp {
 
                #endregion
 
-               public Constraints Clone ()
+               bool CheckConflictingInheritedConstraint (TypeSpec ba, TypeSpec bb, IMemberContext context, Location loc)
                {
-                       return new Constraints (tparam, constraints, loc);
+                       if (!TypeManager.IsSubclassOf (ba, bb) && !TypeManager.IsSubclassOf (bb, ba)) {
+                               context.Compiler.Report.Error (455, loc,
+                                       "Type parameter `{0}' inherits conflicting constraints `{1}' and `{2}'",
+                                       tparam.Value,
+                                       ba.GetSignatureForError (), bb.GetSignatureForError ());
+                               return false;
+                       }
+
+                       return true;
                }
 
-               /// <summary>
-               ///   Resolve the constraints - but only resolve things into Expression's, not
-               ///   into actual types.
-               /// </summary>
-               public bool Resolve (MemberCore ec, TypeParameter tp, Report Report)
+               public void CheckGenericConstraints (IMemberContext context)
+               {
+                       foreach (var c in constraints) {
+                               var ge = c as GenericTypeExpr;
+                               if (ge != null)
+                                       ge.CheckConstraints (context);
+                       }
+               }
+
+               //
+               // Resolve the constraints types with only possible early checks, return
+               // value `false' is reserved for recursive failure
+               //
+               public bool Resolve (IMemberContext context, TypeParameter tp)
                {
                        if (resolved)
                                return true;
 
-                       if (ec == null)
+                       if (resolving)
                                return false;
 
-                       iface_constraints = new List<TypeExpr> (2);     // TODO: Too expensive allocation
-                       type_param_constraints = new List<TypeExpr> ();
+                       resolving = true;
+                       var spec = tp.Type;
+                       List<TypeParameterSpec> tparam_types = null;
+                       bool iface_found = false;
 
-                       foreach (var obj in constraints) {
+                       spec.BaseType = TypeManager.object_type;
 
-                               if (obj is SpecialContraintExpr) {
-                                       SpecialConstraint sc = ((SpecialContraintExpr) obj).Constraint;
+                       for (int i = 0; i < constraints.Count; ++i) {
+                               var constraint = constraints[i];
 
-                                       if (sc == SpecialConstraint.Constructor) {
-                                               if (!HasValueTypeConstraint) {
-                                                       attrs |= GenericParameterAttributes.DefaultConstructorConstraint;
-                                                       continue;
-                                               }
-                                       }
+                               if (constraint is SpecialContraintExpr) {
+                                       spec.SpecialConstraint |= ((SpecialContraintExpr) constraint).Constraint;
+                                       if (spec.HasSpecialStruct)
+                                               spec.BaseType = TypeManager.value_type;
 
-                                       if (sc == SpecialConstraint.Class)
-                                               attrs |= GenericParameterAttributes.ReferenceTypeConstraint;
-                                       else
-                                               attrs |= GenericParameterAttributes.NotNullableValueTypeConstraint;
+                                       // Set to null as it does not have a type
+                                       constraints[i] = null;
                                        continue;
                                }
 
-                               int errors = Report.Errors;
-                               FullNamedExpression fn = obj.ResolveAsTypeStep (ec, false);
-
-                               if (fn == null) {
-                                       if (errors != Report.Errors)
-                                               return false;
+                               var type_expr = constraints[i] = constraint.ResolveAsTypeTerminal (context, false);
+                               if (type_expr == null)
+                                       continue;
 
-                                       NamespaceEntry.Error_NamespaceNotFound (loc, obj.GetSignatureForError (), Report);
-                                       return false;
+                               var gexpr = type_expr as GenericTypeExpr;
+                               if (gexpr != null && gexpr.HasDynamicArguments ()) {
+                                       context.Compiler.Report.Error (1968, constraint.Location,
+                                               "A constraint cannot be the dynamic type `{0}'", gexpr.GetSignatureForError ());
+                                       continue;
                                }
 
-                               TypeExpr expr;
-                               GenericTypeExpr cexpr = fn as GenericTypeExpr;
-                               if (cexpr != null) {
-                                       expr = cexpr.ResolveAsBaseTerminal (ec, false);
-                                       if (expr != null && cexpr.HasDynamicArguments ()) {
-                                               Report.Error (1968, cexpr.Location,
-                                                       "A constraint cannot be the dynamic type `{0}'",
-                                                       cexpr.GetSignatureForError ());
-                                               expr = null;
-                                       }
-                               } else
-                                       expr = ((Expression) obj).ResolveAsTypeTerminal (ec, false);
-
-                               if ((expr == null) || (expr.Type == null))
-                                       return false;
+                               var type = type_expr.Type;
 
-                               if (TypeManager.IsGenericParameter (expr.Type))
-                                       type_param_constraints.Add (expr);
-                               else if (expr.IsInterface)
-                                       iface_constraints.Add (expr);
-                               else if (class_constraint != null || iface_constraints.Count != 0) {
-                                       Report.Error (406, loc,
-                                               "The class type constraint `{0}' must be listed before any other constraints. Consider moving type constraint to the beginning of the constraint list",
-                                               expr.GetSignatureForError ());
-                                       return false;
-                               } else if (HasReferenceTypeConstraint || HasValueTypeConstraint) {
-                                       Report.Error (450, loc, "`{0}': cannot specify both " +
-                                                     "a constraint class and the `class' " +
-                                                     "or `struct' constraint", expr.GetSignatureForError ());
-                                       return false;
-                               } else
-                                       class_constraint = expr;
+                               if (!context.CurrentMemberDefinition.IsAccessibleAs (type)) {
+                                       context.Compiler.Report.SymbolRelatedToPreviousError (type);
+                                       context.Compiler.Report.Error (703, loc,
+                                               "Inconsistent accessibility: constraint type `{0}' is less accessible than `{1}'",
+                                               type.GetSignatureForError (), context.GetSignatureForError ());
+                               }
 
+                               if (type.IsInterface) {
+                                       if (!spec.AddInterface (type)) {
+                                               context.Compiler.Report.Error (405, constraint.Location,
+                                                       "Duplicate constraint `{0}' for type parameter `{1}'", type.GetSignatureForError (), tparam.Value);
+                                       }
 
-                               //
-                               // Checks whether each generic method parameter constraint type
-                               // is valid with respect to T
-                               //
-                               if (tp != null && tp.Type.DeclaringMethod != null) {
-                                       TypeManager.CheckTypeVariance (expr.Type, Variance.Contravariant, ec as MemberCore);
+                                       iface_found = true;
+                                       continue;
                                }
 
-                               if (!ec.IsAccessibleAs (fn.Type)) {
-                                       Report.SymbolRelatedToPreviousError (fn.Type);
-                                       Report.Error (703, loc,
-                                               "Inconsistent accessibility: constraint type `{0}' is less accessible than `{1}'",
-                                               fn.GetSignatureForError (), ec.GetSignatureForError ());
-                               }
 
-                               num_constraints++;
-                       }
+                               var constraint_tp = type as TypeParameterSpec;
+                               if (constraint_tp != null) {
+                                       if (tparam_types == null) {
+                                               tparam_types = new List<TypeParameterSpec> (2);
+                                       } else if (tparam_types.Contains (constraint_tp)) {
+                                               context.Compiler.Report.Error (405, constraint.Location,
+                                                       "Duplicate constraint `{0}' for type parameter `{1}'", type.GetSignatureForError (), tparam.Value);
+                                               continue;
+                                       }
+
+                                       //
+                                       // Checks whether each generic method parameter constraint type
+                                       // is valid with respect to T
+                                       //
+                                       if (tp.IsMethodTypeParameter) {
+                                               TypeManager.CheckTypeVariance (type, Variance.Contravariant, context);
+                                       }
 
-                       var list = new List<Type> ();
-                       foreach (TypeExpr iface_constraint in iface_constraints) {
-                               foreach (Type type in list) {
-                                       if (!type.Equals (iface_constraint.Type))
+                                       var tp_def = constraint_tp.MemberDefinition as TypeParameter;
+                                       if (tp_def != null && !tp_def.ResolveConstraints (context)) {
+                                               context.Compiler.Report.Error (454, constraint.Location,
+                                                       "Circular constraint dependency involving `{0}' and `{1}'",
+                                                       constraint_tp.GetSignatureForError (), tp.GetSignatureForError ());
                                                continue;
+                                       }
 
-                                       Report.Error (405, loc,
-                                                     "Duplicate constraint `{0}' for type " +
-                                                     "parameter `{1}'.", iface_constraint.GetSignatureForError (),
-                                                     tparam.Value);
-                                       return false;
-                               }
+                                       //
+                                       // Checks whether there are no conflicts between type parameter constraints
+                                       //
+                                       // class Foo<T, U>
+                                       //      where T : A
+                                       //      where U : B, T
+                                       //
+                                       // A and B are not convertible and only 1 class constraint is allowed
+                                       //
+                                       if (constraint_tp.HasTypeConstraint) {
+                                               if (spec.HasTypeConstraint || spec.HasSpecialStruct) {
+                                                       if (!CheckConflictingInheritedConstraint (spec.BaseType, constraint_tp.BaseType, context, constraint.Location))
+                                                               continue;
+                                               } else {
+                                                       for (int ii = 0; ii < tparam_types.Count; ++ii) {
+                                                               if (!tparam_types[ii].HasTypeConstraint)
+                                                                       continue;
 
-                               list.Add (iface_constraint.Type);
-                       }
+                                                               if (!CheckConflictingInheritedConstraint (tparam_types[ii].BaseType, constraint_tp.BaseType, context, constraint.Location))
+                                                                       break;
+                                                       }
+                                               }
+                                       }
 
-                       foreach (TypeExpr expr in type_param_constraints) {
-                               foreach (Type type in list) {
-                                       if (!type.Equals (expr.Type))
+                                       if (constraint_tp.HasSpecialStruct) {
+                                               context.Compiler.Report.Error (456, constraint.Location,
+                                                       "Type parameter `{0}' has the `struct' constraint, so it cannot be used as a constraint for `{1}'",
+                                                       constraint_tp.GetSignatureForError (), tp.GetSignatureForError ());
                                                continue;
+                                       }
 
-                                       Report.Error (405, loc,
-                                                     "Duplicate constraint `{0}' for type " +
-                                                     "parameter `{1}'.", expr.GetSignatureForError (), tparam.Value);
-                                       return false;
+                                       tparam_types.Add (constraint_tp);
+                                       continue;
                                }
 
-                               list.Add (expr.Type);
-                       }
-
-                       iface_constraint_types = new Type [list.Count];
-                       list.CopyTo (iface_constraint_types, 0);
+                               if (iface_found || spec.HasTypeConstraint) {
+                                       context.Compiler.Report.Error (406, constraint.Location,
+                                               "The class type constraint `{0}' must be listed before any other constraints. Consider moving type constraint to the beginning of the constraint list",
+                                               type.GetSignatureForError ());
+                               }
 
-                       if (class_constraint != null) {
-                               class_constraint_type = class_constraint.Type;
-                               if (class_constraint_type == null)
-                                       return false;
+                               if (spec.HasSpecialStruct || spec.HasSpecialClass) {
+                                       context.Compiler.Report.Error (450, type_expr.Location,
+                                               "`{0}': cannot specify both a constraint class and the `class' or `struct' constraint",
+                                               type.GetSignatureForError ());
+                               }
 
-                               if (class_constraint_type.IsSealed) {
-                                       if (class_constraint_type.IsAbstract)
-                                       {
-                                               Report.Error (717, loc, "`{0}' is not a valid constraint. Static classes cannot be used as constraints",
-                                                       TypeManager.CSharpName (class_constraint_type));
-                                       }
-                                       else
-                                       {
-                                               Report.Error (701, loc, "`{0}' is not a valid constraint. A constraint must be an interface, " +
-                                                       "a non-sealed class or a type parameter", TypeManager.CSharpName(class_constraint_type));
-                                       }
-                                       return false;
+                               if (type == InternalType.Dynamic) {
+                                       context.Compiler.Report.Error (1967, constraint.Location, "A constraint cannot be the dynamic type");
+                                       continue;
                                }
 
-                               if ((class_constraint_type == TypeManager.array_type) ||
-                                   (class_constraint_type == TypeManager.delegate_type) ||
-                                   (class_constraint_type == TypeManager.enum_type) ||
-                                   (class_constraint_type == TypeManager.value_type) ||
-                                   (class_constraint_type == TypeManager.object_type) ||
-                                       class_constraint_type == TypeManager.multicast_delegate_type) {
-                                       Report.Error (702, loc,
-                                                         "A constraint cannot be special class `{0}'",
-                                                     TypeManager.CSharpName (class_constraint_type));
-                                       return false;
+                               if (type.IsSealed || !type.IsClass) {
+                                       context.Compiler.Report.Error (701, loc,
+                                               "`{0}' is not a valid constraint. A constraint must be an interface, a non-sealed class or a type parameter",
+                                               TypeManager.CSharpName (type));
+                                       continue;
                                }
 
-                               if (TypeManager.IsDynamicType (class_constraint_type)) {
-                                       Report.Error (1967, loc, "A constraint cannot be the dynamic type");
-                                       return false;
+                               if (type.IsStatic) {
+                                       context.Compiler.Report.Error (717, constraint.Location,
+                                               "`{0}' is not a valid constraint. Static classes cannot be used as constraints",
+                                               type.GetSignatureForError ());
+                               } else if (type == TypeManager.array_type || type == TypeManager.delegate_type ||
+                                                       type == TypeManager.enum_type || type == TypeManager.value_type ||
+                                                       type == TypeManager.object_type || type == TypeManager.multicast_delegate_type) {
+                                       context.Compiler.Report.Error (702, constraint.Location,
+                                               "A constraint cannot be special class `{0}'", type.GetSignatureForError ());
+                                       continue;
                                }
-                       }
 
-                       if (class_constraint_type != null)
-                               effective_base_type = class_constraint_type;
-                       else if (HasValueTypeConstraint)
-                               effective_base_type = TypeManager.value_type;
-                       else
-                               effective_base_type = TypeManager.object_type;
+                               spec.BaseType = type;
+                       }
 
-                       if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
-                               attrs |= GenericParameterAttributes.DefaultConstructorConstraint;
+                       if (tparam_types != null)
+                               spec.TypeArguments = tparam_types.ToArray ();
 
+                       resolving = false;
                        resolved = true;
                        return true;
                }
 
-               bool CheckTypeParameterConstraints (Type tparam, ref TypeExpr prevConstraint, List<Type> seen, Report Report)
+               public void VerifyClsCompliance (Report report)
                {
-                       seen.Add (tparam);
-
-                       Constraints constraints = TypeManager.LookupTypeParameter (tparam).Constraints;
-                       if (constraints == null)
-                               return true;
-
-                       if (constraints.HasValueTypeConstraint) {
-                               Report.Error (456, loc,
-                                       "Type parameter `{0}' has the `struct' constraint, so it cannot be used as a constraint for `{1}'",
-                                       tparam.Name, this.tparam.Value);
-                               return false;
-                       }
-
-                       //
-                       //  Checks whether there are no conflicts between type parameter constraints
-                       //
-                       //   class Foo<T, U>
-                       //      where T : A
-                       //      where U : A, B  // A and B are not convertible
-                       //
-                       if (constraints.HasClassConstraint) {
-                               if (prevConstraint != null) {
-                                       Type t2 = constraints.ClassConstraint;
-                                       TypeExpr e2 = constraints.class_constraint;
-
-                                       if (!Convert.ImplicitReferenceConversionExists (prevConstraint, t2) &&
-                                               !Convert.ImplicitReferenceConversionExists (e2, prevConstraint.Type)) {
-                                               Report.Error (455, loc,
-                                                       "Type parameter `{0}' inherits conflicting constraints `{1}' and `{2}'",
-                                                       this.tparam.Value, TypeManager.CSharpName (prevConstraint.Type), TypeManager.CSharpName (t2));
-                                               return false;
-                                       }
-                               }
-
-                               prevConstraint = constraints.class_constraint;
-                       }
-
-                       if (constraints.type_param_constraints == null)
-                               return true;
+                       foreach (var c in constraints)
+                       {
+                               if (c == null)
+                                       continue;
 
-                       foreach (TypeExpr expr in constraints.type_param_constraints) {
-                               if (seen.Contains (expr.Type)) {
-                                       Report.Error (454, loc, "Circular constraint " +
-                                                     "dependency involving `{0}' and `{1}'",
-                                                     tparam.Name, expr.GetSignatureForError ());
-                                       return false;
+                               if (!c.Type.IsCLSCompliant ()) {
+                                       report.SymbolRelatedToPreviousError (c.Type);
+                                       report.Warning (3024, 1, loc, "Constraint type `{0}' is not CLS-compliant",
+                                               c.Type.GetSignatureForError ());
                                }
-
-                               if (!CheckTypeParameterConstraints (expr.Type, ref prevConstraint, seen, Report))
-                                       return false;
                        }
-
-                       return true;
                }
+       }
 
-               /// <summary>
-               ///   Resolve the constraints into actual types.
-               /// </summary>
-               public bool ResolveTypes (IMemberContext ec, Report r)
-               {
-                       if (resolved_types)
-                               return true;
+       //
+       // A type parameter for a generic type or generic method definition
+       //
+       public class TypeParameter : MemberCore, ITypeDefinition
+       {
+               static readonly string[] attribute_target = new string [] { "type parameter" };
+               
+               Constraints constraints;
+               GenericTypeParameterBuilder builder;
+//             Variance variance;
+               TypeParameterSpec spec;
 
-                       resolved_types = true;
+               public TypeParameter (DeclSpace parent, int index, MemberName name, Constraints constraints, Attributes attrs, Variance variance)
+                       : base (parent, name, attrs)
+               {
+                       this.constraints = constraints;
+//                     this.variance = variance;
+                       this.spec = new TypeParameterSpec (null, index, this, SpecialConstraint.None, variance, null);
+               }
 
-                       foreach (object obj in constraints) {
-                               GenericTypeExpr cexpr = obj as GenericTypeExpr;
-                               if (cexpr == null)
-                                       continue;
+               #region Properties
 
-                               if (!cexpr.CheckConstraints (ec))
-                                       return false;
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.GenericParameter;
                        }
+               }
 
-                       if (type_param_constraints.Count != 0) {
-                               var seen = new List<Type> ();
-                               TypeExpr prev_constraint = class_constraint;
-                               foreach (TypeExpr expr in type_param_constraints) {
-                                       if (!CheckTypeParameterConstraints (expr.Type, ref prev_constraint, seen, r))
-                                               return false;
-                                       seen.Clear ();
-                               }
+               public override string DocCommentHeader {
+                       get {
+                               throw new InvalidOperationException (
+                                       "Unexpected attempt to get doc comment from " + this.GetType ());
                        }
+               }
 
-                       for (int i = 0; i < iface_constraints.Count; ++i) {
-                               TypeExpr iface_constraint = (TypeExpr) iface_constraints [i];
-                               iface_constraint = iface_constraint.ResolveAsTypeTerminal (ec, false);
-                               if (iface_constraint == null)
-                                       return false;
-                               iface_constraints [i] = iface_constraint;
+               public bool IsMethodTypeParameter {
+                       get {
+                               return spec.IsMethodOwned;
                        }
+               }
 
-                       if (class_constraint != null) {
-                               class_constraint = class_constraint.ResolveAsTypeTerminal (ec, false);
-                               if (class_constraint == null)
-                                       return false;
+               public string Namespace {
+                       get {
+                               return null;
                        }
-
-                       return true;
                }
 
-               public override GenericParameterAttributes Attributes {
-                       get { return attrs; }
+               public TypeParameterSpec Type {
+                       get {
+                               return spec;
+                       }
                }
 
-               public override bool HasClassConstraint {
-                       get { return class_constraint != null; }
+               public int TypeParametersCount {
+                       get {
+                               return 0;
+                       }
                }
 
-               public override Type ClassConstraint {
-                       get { return class_constraint_type; }
+               public TypeParameterSpec[] TypeParameters {
+                       get {
+                               return null;
+                       }
                }
 
-               public override Type[] InterfaceConstraints {
-                       get { return iface_constraint_types; }
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_target;
+                       }
                }
 
-               public override Type EffectiveBaseClass {
-                       get { return effective_base_type; }
+               public Variance Variance {
+                       get {
+                               return spec.Variance;
+                       }
                }
 
-               public bool IsSubclassOf (Type t)
+               #endregion
+
+               //
+               // This is called for each part of a partial generic type definition.
+               //
+               // If partial type parameters constraints are not null and we don't
+               // already have constraints they become our constraints. If we already
+               // have constraints, we must check that they're the same.
+               //
+               public bool AddPartialConstraints (TypeContainer part, TypeParameter tp)
                {
-                       if ((class_constraint_type != null) &&
-                           class_constraint_type.IsSubclassOf (t))
+                       if (builder == null)
+                               throw new InvalidOperationException ();
+
+                       var new_constraints = tp.constraints;
+                       if (new_constraints == null)
                                return true;
 
-                       if (iface_constraint_types == null)
+                       // TODO: could create spec only
+                       //tp.Define (null, -1, part.Definition);
+                       tp.spec.DeclaringType = part.Definition;
+                       if (!tp.ResolveConstraints (part))
                                return false;
 
-                       foreach (Type iface in iface_constraint_types) {
-                               if (TypeManager.IsSubclassOf (iface, t))
-                                       return true;
-                       }
+                       if (constraints != null)
+                               return spec.HasSameConstraintsDefinition (tp.Type);
 
-                       return false;
+                       constraints = new_constraints;
+                       return true;
                }
 
-               public Location Location {
-                       get {
-                               return loc;
-                       }
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
+               {
+                       builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
-               /// <summary>
-               ///   This is used when we're implementing a generic interface method.
-               ///   Each method type parameter in implementing method must have the same
-               ///   constraints than the corresponding type parameter in the interface
-               ///   method.  To do that, we're called on each of the implementing method's
-               ///   type parameters.
-               /// </summary>
-               public bool AreEqual (GenericConstraints gc)
+               public void CheckGenericConstraints ()
                {
-                       if (gc.Attributes != attrs)
-                               return false;
-
-                       if (HasClassConstraint != gc.HasClassConstraint)
-                               return false;
-                       if (HasClassConstraint && !TypeManager.IsEqual (gc.ClassConstraint, ClassConstraint))
-                               return false;
-
-                       int gc_icount = gc.InterfaceConstraints != null ?
-                               gc.InterfaceConstraints.Length : 0;
-                       int icount = InterfaceConstraints != null ?
-                               InterfaceConstraints.Length : 0;
-
-                       if (gc_icount != icount)
-                               return false;
+                       if (constraints != null)
+                               constraints.CheckGenericConstraints (this);
+               }
 
-                       for (int i = 0; i < gc.InterfaceConstraints.Length; ++i) {
-                               Type iface = gc.InterfaceConstraints [i];
-                               if (iface.IsGenericType)
-                                       iface = iface.GetGenericTypeDefinition ();
-                               
-                               bool ok = false;
-                               for (int ii = 0; ii < InterfaceConstraints.Length; ii++) {
-                                       Type check = InterfaceConstraints [ii];
-                                       if (check.IsGenericType)
-                                               check = check.GetGenericTypeDefinition ();
-                                       
-                                       if (TypeManager.IsEqual (iface, check)) {
-                                               ok = true;
-                                               break;
-                                       }
+               public TypeParameter CreateHoistedCopy (TypeSpec declaringType)
+               {
+                       return new TypeParameter (Parent, spec.DeclaredPosition, MemberName, constraints, null, spec.Variance) {
+                               spec = new TypeParameterSpec (declaringType, spec.DeclaredPosition, spec.MemberDefinition, spec.SpecialConstraint, spec.Variance, null) {
+                                       BaseType = spec.BaseType,
+                                       InterfacesDefined = spec.InterfacesDefined,
+                                       TypeArguments = spec.TypeArguments
                                }
+                       };
+               }
 
-                               if (!ok)
-                                       return false;
-                       }
-
+               public override bool Define ()
+               {
                        return true;
                }
 
-               public void VerifyClsCompliance (Report r)
+               //
+               // This is the first method which is called during the resolving
+               // process; we're called immediately after creating the type parameters
+               // with SRE (by calling `DefineGenericParameters()' on the TypeBuilder /
+               // MethodBuilder).
+               //
+               public void Define (GenericTypeParameterBuilder type, TypeSpec declaringType)
                {
-                       if (class_constraint_type != null && !AttributeTester.IsClsCompliant (class_constraint_type))
-                               Warning_ConstrainIsNotClsCompliant (class_constraint_type, class_constraint.Location, r);
+                       if (builder != null)
+                               throw new InternalErrorException ();
 
-                       if (iface_constraint_types != null) {
-                               for (int i = 0; i < iface_constraint_types.Length; ++i) {
-                                       if (!AttributeTester.IsClsCompliant (iface_constraint_types [i]))
-                                               Warning_ConstrainIsNotClsCompliant (iface_constraint_types [i],
-                                                       ((TypeExpr)iface_constraints [i]).Location, r);
-                               }
-                       }
+                       this.builder = type;
+                       spec.DeclaringType = declaringType;
+                       spec.SetMetaInfo (type);
                }
 
-               void Warning_ConstrainIsNotClsCompliant (Type t, Location loc, Report Report)
+               public void EmitConstraints (GenericTypeParameterBuilder builder)
                {
-                       Report.SymbolRelatedToPreviousError (t);
-                       Report.Warning (3024, 1, loc, "Constraint type `{0}' is not CLS-compliant",
-                               TypeManager.CSharpName (t));
-               }
-       }
-
-       /// <summary>
-       ///   A type parameter from a generic type definition.
-       /// </summary>
-       public class TypeParameter : MemberCore, IMemberContainer
-       {
-               static readonly string[] attribute_target = new string [] { "type parameter" };
-               
-               DeclSpace decl;
-               GenericConstraints gc;
-               Constraints constraints;
-               GenericTypeParameterBuilder type;
-               MemberCache member_cache;
-               Variance variance;
+                       var attr = GenericParameterAttributes.None;
+                       if (spec.Variance == Variance.Contravariant)
+                               attr |= GenericParameterAttributes.Contravariant;
+                       else if (spec.Variance == Variance.Covariant)
+                               attr |= GenericParameterAttributes.Covariant;
 
-               public TypeParameter (DeclSpace parent, DeclSpace decl, string name,
-                                     Constraints constraints, Attributes attrs, Variance variance, Location loc)
-                       : base (parent, new MemberName (name, loc), attrs)
-               {
-                       this.decl = decl;
-                       this.constraints = constraints;
-                       this.variance = variance;
-               }
+                       if (spec.HasSpecialClass)
+                               attr |= GenericParameterAttributes.ReferenceTypeConstraint;
+                       else if (spec.HasSpecialStruct)
+                               attr |= GenericParameterAttributes.NotNullableValueTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint;
 
-               public GenericConstraints GenericConstraints {
-                       get { return gc != null ? gc : constraints; }
-               }
+                       if (spec.HasSpecialConstructor)
+                               attr |= GenericParameterAttributes.DefaultConstructorConstraint;
 
-               public Constraints Constraints {
-                       get { return constraints; }
-               }
+                       if (spec.BaseType != TypeManager.object_type)
+                               builder.SetBaseTypeConstraint (spec.BaseType.GetMetaInfo ());
 
-               public DeclSpace DeclSpace {
-                       get { return decl; }
-               }
+                       if (spec.InterfacesDefined != null)
+                               builder.SetInterfaceConstraints (spec.InterfacesDefined.Select (l => l.GetMetaInfo ()).ToArray ());
 
-               public Variance Variance {
-                       get { return variance; }
-               }
+                       if (spec.TypeArguments != null)
+                               builder.SetInterfaceConstraints (spec.TypeArguments.Select (l => l.GetMetaInfo ()).ToArray ());
 
-               public Type Type {
-                       get { return type; }
+                       builder.SetGenericParameterAttributes (attr);
                }
 
-               /// <summary>
-               ///   This is the first method which is called during the resolving
-               ///   process; we're called immediately after creating the type parameters
-               ///   with SRE (by calling `DefineGenericParameters()' on the TypeBuilder /
-               ///   MethodBuilder).
-               ///
-               ///   We're either called from TypeContainer.DefineType() or from
-               ///   GenericMethod.Define() (called from Method.Define()).
-               /// </summary>
-               public void Define (GenericTypeParameterBuilder type)
+               public override void Emit ()
                {
-                       if (this.type != null)
-                               throw new InvalidOperationException ();
+                       EmitConstraints (builder);
 
-                       this.type = type;
-                       TypeManager.AddTypeParameter (type, this);
+                       if (OptAttributes != null)
+                               OptAttributes.Emit ();
+
+                       base.Emit ();
                }
 
                public void ErrorInvalidVariance (IMemberContext mc, Variance expected)
                {
-// TODO:       Report.SymbolRelatedToPreviousError (mc);
+                       Report.SymbolRelatedToPreviousError (mc.CurrentMemberDefinition);
                        string input_variance = Variance == Variance.Contravariant ? "contravariant" : "covariant";
                        string gtype_variance;
                        switch (expected) {
@@ -745,448 +505,1018 @@ namespace Mono.CSharp {
                                        GetSignatureForError (), mc.GetSignatureForError (), input_variance, gtype_variance, parameters);
                }
 
-               /// <summary>
-               ///   This is the second method which is called during the resolving
-               ///   process - in case of class type parameters, we're called from
-               ///   TypeContainer.ResolveType() - after it resolved the class'es
-               ///   base class and interfaces. For method type parameters, we're
-               ///   called immediately after Define().
-               ///
-               ///   We're just resolving the constraints into expressions here, we
-               ///   don't resolve them into actual types.
-               ///
-               ///   Note that in the special case of partial generic classes, we may be
-               ///   called _before_ Define() and we may also be called multiple types.
-               /// </summary>
-               public bool Resolve (DeclSpace ds)
+               public TypeSpec GetAttributeCoClass ()
                {
-                       if (constraints != null) {
-                               if (!constraints.Resolve (ds, this, Report)) {
-                                       constraints = null;
-                                       return false;
-                               }
-                       }
+                       return null;
+               }
+
+               public string GetAttributeDefaultMember ()
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       return MemberName.Name;
+               }
+
+               public MemberCache LoadMembers (TypeSpec declaringType)
+               {
+                       throw new NotSupportedException ("Not supported for compiled definition");
+               }
 
+               //
+               // Resolves all type parameter constraints
+               //
+               public bool ResolveConstraints (IMemberContext context)
+               {
+                       if (constraints != null)
+                               return constraints.Resolve (context, this);
+
+                       spec.BaseType = TypeManager.object_type;
                        return true;
                }
 
-               /// <summary>
-               ///   This is the third method which is called during the resolving
-               ///   process.  We're called immediately after calling DefineConstraints()
-               ///   on all of the current class'es type parameters.
-               ///
-               ///   Our job is to resolve the constraints to actual types.
-               ///
-               ///   Note that we may have circular dependencies on type parameters - this
-               ///   is why Resolve() and ResolveType() are separate.
-               /// </summary>
-               public bool ResolveType (IMemberContext ec)
+               public static TypeParameter FindTypeParameter (TypeParameter[] tparams, string name)
                {
-                       if (constraints != null) {
-                               if (!constraints.ResolveTypes (ec, Report)) {
-                                       constraints = null;
-                                       return false;
+                       foreach (var tp in tparams) {
+                               if (tp.Name == name)
+                                       return tp;
+                       }
+
+                       return null;
+               }
+
+               public override bool IsClsComplianceRequired ()
+               {
+                       return false;
+               }
+
+               public new void VerifyClsCompliance ()
+               {
+                       if (constraints != null)
+                               constraints.VerifyClsCompliance (Report);
+               }
+       }
+
+       [System.Diagnostics.DebuggerDisplay ("{DisplayDebugInfo()}")]
+       public class TypeParameterSpec : TypeSpec
+       {
+               public static readonly new TypeParameterSpec[] EmptyTypes = new TypeParameterSpec[0];
+
+               Variance variance;
+               SpecialConstraint spec;
+               readonly int tp_pos;
+               TypeSpec[] targs;
+               TypeSpec[] ifaces_defined;
+
+               //
+               // Creates type owned type parameter
+               //
+               public TypeParameterSpec (TypeSpec declaringType, int index, ITypeDefinition definition, SpecialConstraint spec, Variance variance, Type info)
+                       : base (MemberKind.TypeParameter, declaringType, definition, info, Modifiers.PUBLIC)
+               {
+                       this.variance = variance;
+                       this.spec = spec;
+                       state &= ~StateFlags.Obsolete_Undetected;
+                       tp_pos = index;
+               }
+
+               //
+               // Creates method owned type parameter
+               //
+               public TypeParameterSpec (int index, ITypeDefinition definition, SpecialConstraint spec, Variance variance, Type info)
+                       : this (null, index, definition, spec, variance, info)
+               {
+               }
+
+               #region Properties
+
+               public int DeclaredPosition {
+                       get {
+                               return tp_pos;
+                       }
+               }
+
+               public bool HasSpecialConstructor {
+                       get {
+                               return (spec & SpecialConstraint.Constructor) != 0;
+                       }
+               }
+
+               public bool HasSpecialClass {
+                       get {
+                               return (spec & SpecialConstraint.Class) != 0;
+                       }
+               }
+
+               public bool HasSpecialStruct {
+                       get {
+                               return (spec & SpecialConstraint.Struct) != 0;
+                       }
+               }
+
+               public bool HasTypeConstraint {
+                       get {
+                               return BaseType != TypeManager.object_type && BaseType != TypeManager.value_type;
+                       }
+               }
+
+               public override IList<TypeSpec> Interfaces {
+                       get {
+                               if ((state & StateFlags.InterfacesExpanded) == 0) {
+                                       if (ifaces != null) {
+                                               for (int i = 0; i < ifaces.Count; ++i ) {
+                                                       var iface_type = ifaces[i];
+                                                       if (iface_type.Interfaces != null) {
+                                                               if (ifaces_defined == null)
+                                                                       ifaces_defined = ifaces.ToArray ();
+
+                                                               for (int ii = 0; ii < iface_type.Interfaces.Count; ++ii) {
+                                                                       var ii_iface_type = iface_type.Interfaces [ii];
+
+                                                                       AddInterface (ii_iface_type);
+                                                               }
+                                                       }
+                                               }
+                                       }
+
+                                       if (ifaces_defined == null && ifaces != null)
+                                               ifaces_defined = ifaces.ToArray ();
+
+                                       state |= StateFlags.InterfacesExpanded;
                                }
+
+                               return ifaces;
                        }
+               }
 
-                       return true;
+               //
+               // Unexpanded interfaces list
+               //
+               public TypeSpec[] InterfacesDefined {
+                       get {
+                               if (ifaces_defined == null && ifaces != null)
+                                       ifaces_defined = ifaces.ToArray ();
+
+                               return ifaces_defined;
+                       }
+                       set {
+                               ifaces_defined = value;
+                       }
                }
 
-               /// <summary>
-               ///   This is the fourth and last method which is called during the resolving
-               ///   process.  We're called after everything is fully resolved and actually
-               ///   register the constraints with SRE and the TypeManager.
-               /// </summary>
-               public bool DefineType (IMemberContext ec)
+               public bool IsConstrained {
+                       get {
+                               return spec != SpecialConstraint.None || ifaces != null || targs != null || HasTypeConstraint;
+                       }
+               }
+
+               //
+               // Returns whether the type parameter is "known to be a reference type"
+               //
+               public bool IsReferenceType {
+                       get {
+                               return (spec & SpecialConstraint.Class) != 0 || HasTypeConstraint;
+                       }
+               }
+
+               public bool IsValueType {       // TODO: Do I need this ?
+                       get {
+                               // TODO MemberCache: probably wrong
+                               return HasSpecialStruct;
+                       }
+               }
+
+               public override string Name {
+                       get {
+                               return definition.Name;
+                       }
+               }
+
+               public bool IsMethodOwned {
+                       get {
+                               return DeclaringType == null;
+                       }
+               }
+
+               public SpecialConstraint SpecialConstraint {
+                       get {
+                               return spec;
+                       }
+                       set {
+                               spec = value;
+                       }
+               }
+
+               //
+               // Types used to inflate the generic type
+               //
+               public new TypeSpec[] TypeArguments {
+                       get {
+                               return targs;
+                       }
+                       set {
+                               targs = value;
+                       }
+               }
+
+               public Variance Variance {
+                       get {
+                               return variance;
+                       }
+               }
+
+               #endregion
+
+               public string DisplayDebugInfo ()
                {
-                       return DefineType (ec, null, null, false);
+                       var s = GetSignatureForError ();
+                       return IsMethodOwned ? s + "!!" : s + "!";
                }
 
-               /// <summary>
-               ///   This is the fith and last method which is called during the resolving
-               ///   process.  We're called after everything is fully resolved and actually
-               ///   register the constraints with SRE and the TypeManager.
-               ///
-               ///   The `builder', `implementing' and `is_override' arguments are only
-               ///   applicable to method type parameters.
-               /// </summary>
-               public bool DefineType (IMemberContext ec, MethodBuilder builder,
-                                       MethodInfo implementing, bool is_override)
+               //
+               // Finds effective base class
+               //
+               public TypeSpec GetEffectiveBase ()
+               {
+                       if (HasSpecialStruct) {
+                               return TypeManager.value_type;
+                       }
+
+                       if (BaseType != null && targs == null)
+                               return BaseType;
+
+                       var types = targs;
+                       if (HasTypeConstraint) {
+                               Array.Resize (ref types, types.Length + 1);
+                               types[types.Length - 1] = BaseType;
+                       }
+
+                       if (types != null)
+                               return Convert.FindMostEncompassedType (types.Select (l => l.BaseType));
+
+                       return TypeManager.object_type;
+               }
+
+               public override string GetSignatureForError ()
                {
-                       if (!ResolveType (ec))
+                       return Name;
+               }
+
+               //
+               // Constraints have to match by definition but not position, used by
+               // partial classes or methods
+               //
+               public bool HasSameConstraintsDefinition (TypeParameterSpec other)
+               {
+                       if (spec != other.spec)
                                return false;
 
-                       if (implementing != null) {
-                               MethodBase mb = TypeManager.DropGenericMethodArguments (implementing);
+                       if (BaseType != other.BaseType)
+                               return false;
 
-                               int pos = type.GenericParameterPosition;
-                               Type mparam = mb.GetGenericArguments () [pos];
-                               GenericConstraints temp_gc = ReflectionConstraints.GetConstraints (mparam);
+                       if (!TypeSpecComparer.Override.IsSame (InterfacesDefined, other.InterfacesDefined))
+                               return false;
 
-                               if (temp_gc != null)
-                                       gc = new InflatedConstraints (temp_gc, implementing.DeclaringType);
-                               else if (constraints != null)
-                                       gc = new InflatedConstraints (constraints, implementing.DeclaringType);
+                       if (!TypeSpecComparer.Override.IsSame (targs, other.targs))
+                               return false;
 
-                               bool ok = true;
-                               if (constraints != null) {
-                                       if (temp_gc == null)
-                                               ok = false;
-                                       else if (!constraints.AreEqual (gc))
-                                               ok = false;
-                               } else {
-                                       if (!is_override && (temp_gc != null))
-                                               ok = false;
+                       return true;
+               }
+
+               //
+               // Constraints have to match by using same set of types, used by
+               // implicit interface implementation
+               //
+               public bool HasSameConstraintsImplementation (TypeParameterSpec other)
+               {
+                       if (spec != other.spec)
+                               return false;
+
+                       //
+                       // It can be same base type or inflated type parameter
+                       //
+                       // interface I<T> { void Foo<U> where U : T; }
+                       // class A : I<int> { void Foo<X> where X : int {} }
+                       //
+                       bool found;
+                       if (BaseType != other.BaseType) {
+                               if (other.targs == null)
+                                       return false;
+
+                               found = false;
+                               foreach (var otarg in other.targs) {
+                                       if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
+                                               found = true;
+                                               break;
+                                       }
                                }
 
-                               if (!ok) {
-                                       Report.SymbolRelatedToPreviousError (implementing);
-
-                                       Report.Error (
-                                               425, Location, "The constraints for type " +
-                                               "parameter `{0}' of method `{1}' must match " +
-                                               "the constraints for type parameter `{2}' " +
-                                               "of interface method `{3}'. Consider using " +
-                                               "an explicit interface implementation instead",
-                                               Name, TypeManager.CSharpSignature (builder),
-                                               TypeManager.CSharpName (mparam), TypeManager.CSharpSignature (mb));
+                               if (!found)
                                        return false;
+                       }
+
+                       // Check interfaces implementation -> definition
+                       if (InterfacesDefined != null) {
+                               foreach (var iface in InterfacesDefined) {
+                                       found = false;
+                                       if (other.InterfacesDefined != null) {
+                                               foreach (var oiface in other.InterfacesDefined) {
+                                                       if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
+                                                               found = true;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+
+                                       if (found)
+                                               continue;
+
+                                       if (other.targs != null) {
+                                               foreach (var otarg in other.targs) {
+                                                       if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
+                                                               found = true;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+
+                                       if (!found)
+                                               return false;
+                               }
+                       }
+
+                       // Check interfaces implementation <- definition
+                       if (other.InterfacesDefined != null) {
+                               if (InterfacesDefined == null)
+                                       return false;
+
+                               foreach (var oiface in other.InterfacesDefined) {
+                                       found = false;
+                                       foreach (var iface in InterfacesDefined) {
+                                               if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
+                                                       found = true;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (!found)
+                                               return false;
                                }
-                       } else if (DeclSpace is CompilerGeneratedClass) {
-                               TypeParameter[] tparams = DeclSpace.TypeParameters;
-                               Type[] types = new Type [tparams.Length];
-                               for (int i = 0; i < tparams.Length; i++)
-                                       types [i] = tparams [i].Type;
-
-                               if (constraints != null)
-                                       gc = new InflatedConstraints (constraints, types);
-                       } else {
-                               gc = (GenericConstraints) constraints;
                        }
 
-                       SetConstraints (type);
+                       // Check type parameters implementation -> definition
+                       if (targs != null) {
+                               if (other.targs == null)
+                                       return false;
+
+                               foreach (var targ in targs) {
+                                       found = false;
+                                       foreach (var otarg in other.targs) {
+                                               if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
+                                                       found = true;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (!found)
+                                               return false;
+                               }
+                       }
+
+                       // Check type parameters implementation <- definition
+                       if (other.targs != null) {
+                               foreach (var otarg in other.targs) {
+                                       // Ignore inflated type arguments, were checked above
+                                       if (!otarg.IsGenericParameter)
+                                               continue;
+
+                                       if (targs == null)
+                                               return false;
+
+                                       found = false;
+                                       foreach (var targ in targs) {
+                                               if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
+                                                       found = true;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (!found)
+                                               return false;
+                               }                               
+                       }
+
                        return true;
                }
 
-               public static TypeParameter FindTypeParameter (TypeParameter[] tparams, string name)
+               public static TypeParameterSpec[] InflateConstraints (TypeParameterInflator inflator, TypeParameterSpec[] tparams)
                {
-                       foreach (var tp in tparams) {
-                               if (tp.Name == name)
-                                       return tp;
+                       TypeParameterSpec[] constraints = null;
+
+                       for (int i = 0; i < tparams.Length; ++i) {
+                               var tp = tparams[i];
+                               if (tp.HasTypeConstraint || tp.Interfaces != null || tp.TypeArguments != null) {
+                                       if (constraints == null) {
+                                               constraints = new TypeParameterSpec[tparams.Length];
+                                               Array.Copy (tparams, constraints, constraints.Length);
+                                       }
+
+                                       constraints[i] = (TypeParameterSpec) constraints[i].InflateMember (inflator);
+                               }
                        }
 
-                       return null;
+                       if (constraints == null)
+                               constraints = tparams;
+
+                       return constraints;
                }
 
-               public void SetConstraints (GenericTypeParameterBuilder type)
+               public override MemberSpec InflateMember (TypeParameterInflator inflator)
                {
-                       GenericParameterAttributes attr = GenericParameterAttributes.None;
-                       if (variance == Variance.Contravariant)
-                               attr |= GenericParameterAttributes.Contravariant;
-                       else if (variance == Variance.Covariant)
-                               attr |= GenericParameterAttributes.Covariant;
+                       var tps = (TypeParameterSpec) MemberwiseClone ();
+                       tps.BaseType = inflator.Inflate (BaseType);
+                       if (ifaces != null) {
+                               tps.ifaces = new TypeSpec[ifaces.Count];
+                               for (int i = 0; i < ifaces.Count; ++i)
+                                       tps.ifaces[i] = inflator.Inflate (ifaces[i]);
+                       }
+                       if (targs != null) {
+                               tps.targs = new TypeSpec[targs.Length];
+                               for (int i = 0; i < targs.Length; ++i)
+                                       tps.targs[i] = inflator.Inflate (targs[i]);
+                       }
 
-                       if (gc != null) {
-                               if (gc.HasClassConstraint || gc.HasValueTypeConstraint)
-                                       type.SetBaseTypeConstraint (gc.EffectiveBaseClass);
+                       return tps;
+               }
 
-                               attr |= gc.Attributes;
-                               type.SetInterfaceConstraints (gc.InterfaceConstraints);
-                               TypeManager.RegisterBuilder (type, gc.InterfaceConstraints);
+               //
+               // Populates type parameter members using type parameter constraints
+               // The trick here is to be called late enough but not too late to
+               // populate member cache with all members from other types
+               //
+               protected override void InitializeMemberCache (bool onlyTypes)
+               {
+                       cache = new MemberCache ();
+                       if (ifaces != null) {
+                               foreach (var iface_type in Interfaces) {
+                                       cache.AddInterface (iface_type);
+                               }
                        }
-                       
-                       type.SetGenericParameterAttributes (attr);
                }
 
-               /// <summary>
-               ///   This is called for each part of a partial generic type definition.
-               ///
-               ///   If `new_constraints' is not null and we don't already have constraints,
-               ///   they become our constraints.  If we already have constraints, we must
-               ///   check that they're the same.
-               ///   con
-               /// </summary>
-               public bool UpdateConstraints (MemberCore ec, Constraints new_constraints)
+               public override TypeSpec Mutate (TypeParameterMutator mutator)
                {
-                       if (type == null)
-                               throw new InvalidOperationException ();
-
-                       if (new_constraints == null)
-                               return true;
-
-                       if (!new_constraints.Resolve (ec, this, Report))
-                               return false;
-                       if (!new_constraints.ResolveTypes (ec, Report))
-                               return false;
+                       return mutator.Mutate (this);
+               }
+       }
 
-                       if (constraints != null) 
-                               return constraints.AreEqual (new_constraints);
+       public struct TypeParameterInflator
+       {
+               readonly TypeSpec type;
+               readonly TypeParameterSpec[] tparams;
+               readonly TypeSpec[] targs;
 
-                       constraints = new_constraints;
-                       return true;
+               public TypeParameterInflator (TypeParameterInflator nested, TypeSpec type)
+                       : this (type, nested.tparams, nested.targs)
+               {
                }
 
-               public override void Emit ()
+               public TypeParameterInflator (TypeSpec type, TypeParameterSpec[] tparams, TypeSpec[] targs)
                {
-                       if (OptAttributes != null)
-                               OptAttributes.Emit ();
+                       if (tparams.Length != targs.Length)
+                               throw new ArgumentException ("Invalid arguments");
 
-                       base.Emit ();
+                       this.tparams = tparams;
+                       this.targs = targs;
+                       this.type = type;
                }
 
-               public override string DocCommentHeader {
+               //
+               // Type parameters to inflate
+               //
+               public TypeParameterSpec[] TypeParameters {
                        get {
-                               throw new InvalidOperationException (
-                                       "Unexpected attempt to get doc comment from " + this.GetType () + ".");
+                               return tparams;
+                       }
+               }
+
+               public TypeSpec Inflate (TypeSpec ts)
+               {
+                       var tp = ts as TypeParameterSpec;
+                       if (tp != null)
+                               return Inflate (tp);
+
+                       var ac = ts as ArrayContainer;
+                       if (ac != null) {
+                               var et = Inflate (ac.Element);
+                               if (et != ac.Element)
+                                       return ArrayContainer.MakeType (et, ac.Rank);
+
+                               return ac;
+                       }
+
+                       //
+                       // When inflating a nested type, inflate its parent first
+                       // in case it's using same type parameters (was inflated within the type)
+                       //
+                       if (ts.IsNested) {
+                               var parent = Inflate (ts.DeclaringType);
+                               if (ts.DeclaringType != parent) {
+                                       //
+                                       // Keep the inflated type arguments
+                                       // 
+                                       var targs = ts.TypeArguments;
+
+                                       //
+                                       // Parent was inflated, find the same type on inflated type
+                                       // to use same cache for nested types on same generic parent
+                                       //
+                                       // TODO: Should use BindingRestriction.DeclaredOnly or GetMember
+                                       ts = MemberCache.FindNestedType (parent, ts.Name, targs.Length);
+
+                                       //
+                                       // Handle the tricky case where parent shares local type arguments
+                                       // which means inflating inflated type
+                                       //
+                                       // class Test<T> {
+                                       //              public static Nested<T> Foo () { return null; }
+                                       //
+                                       //              public class Nested<U> {}
+                                       //      }
+                                       //
+                                       //  return type of Test<string>.Foo() has to be Test<string>.Nested<string> 
+                                       //
+                                       if (targs.Length > 0) {
+                                               var inflated_targs = new TypeSpec [targs.Length];
+                                               for (var i = 0; i < targs.Length; ++i)
+                                                       inflated_targs[i] = Inflate (targs[i]);
+
+                                               ts = ts.MakeGenericType (inflated_targs);
+                                       }
+
+                                       return ts;
+                               }
                        }
+
+                       // Inflate generic type
+                       if (ts.IsGeneric)
+                               return InflateTypeParameters (ts);
+
+                       return ts;
+               }
+
+               public TypeSpec Inflate (TypeParameterSpec tp)
+               {
+                       for (int i = 0; i < tparams.Length; ++i)
+                               if (tparams [i] == tp)
+                                       return targs[i];
+
+                       // CECIL: This can happen when inflating nested types
+                       // without type arguments specified
+                       return tp;
                }
 
                //
-               // MemberContainer
+               // Inflates generic types
                //
+               TypeSpec InflateTypeParameters (TypeSpec type)
+               {
+                       var targs = new TypeSpec[type.Arity];
+                       var i = 0;
 
-               public override bool Define ()
+                       var gti = type as InflatedTypeSpec;
+
+                       //
+                       // Inflating using outside type arguments, var v = new Foo<int> (), class Foo<T> {}
+                       //
+                       if (gti != null) {
+                               for (; i < targs.Length; ++i)
+                                       targs[i] = Inflate (gti.TypeArguments[i]);
+
+                               return gti.GetDefinition ().MakeGenericType (targs);
+                       }
+
+                       //
+                       // Inflating parent using inside type arguments, class Foo<T> { ITest<T> foo; }
+                       //
+                       var args = type.MemberDefinition.TypeParameters;
+                       foreach (var ds_tp in args)
+                               targs[i++] = Inflate (ds_tp);
+
+                       return type.MakeGenericType (targs);
+               }
+
+               public TypeSpec TypeInstance {
+                       get { return type; }
+               }
+       }
+
+       //
+       // Before emitting any code we have to change all MVAR references to VAR
+       // when the method is of generic type and has hoisted variables
+       //
+       public class TypeParameterMutator
+       {
+               TypeParameter[] mvar;
+               TypeParameter[] var;
+               Dictionary<TypeSpec, TypeSpec> mutated_typespec = new Dictionary<TypeSpec, TypeSpec> ();
+
+               public TypeParameterMutator (TypeParameter[] mvar, TypeParameter[] var)
                {
-                       return true;
+                       if (mvar.Length != var.Length)
+                               throw new ArgumentException ();
+
+                       this.mvar = mvar;
+                       this.var = var;
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public TypeSpec Mutate (TypeSpec ts)
                {
-                       type.SetCustomAttribute (ctor, cdata);
+                       TypeSpec value;
+                       if (mutated_typespec.TryGetValue (ts, out value))
+                               return value;
+
+                       value = ts.Mutate (this);
+                       mutated_typespec.Add (ts, value);
+                       return value;
                }
 
-               public override AttributeTargets AttributeTargets {
-                       get {
-                               return AttributeTargets.GenericParameter;
+               public FieldInfo Mutate (FieldSpec fs)
+               {
+                       // TODO:
+                       return fs.GetMetaInfo ();
+               }
+
+               public TypeParameterSpec Mutate (TypeParameterSpec tp)
+               {
+                       for (int i = 0; i < mvar.Length; ++i) {
+                               if (mvar[i].Type == tp)
+                                       return var[i].Type;
+                       }
+
+                       return tp;
+               }
+
+               public TypeSpec[] Mutate (TypeSpec[] targs)
+               {
+                       TypeSpec[] mutated = new TypeSpec[targs.Length];
+                       bool changed = false;
+                       for (int i = 0; i < targs.Length; ++i) {
+                               mutated[i] = Mutate (targs[i]);
+                               changed |= targs[i] != mutated[i];
                        }
+
+                       return changed ? mutated : targs;
                }
+       }
 
-               public override string[] ValidAttributeTargets {
+       /// <summary>
+       ///   A TypeExpr which already resolved to a type parameter.
+       /// </summary>
+       public class TypeParameterExpr : TypeExpr {
+               
+               public TypeParameterExpr (TypeParameter type_parameter, Location loc)
+               {
+                       this.type = type_parameter.Type;
+                       this.eclass = ExprClass.TypeParameter;
+                       this.loc = loc;
+               }
+
+               protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
+               {
+                       return this;
+               }
+
+               public override bool CheckAccessLevel (IMemberContext ds)
+               {
+                       return true;
+               }
+       }
+
+       public class InflatedTypeSpec : TypeSpec
+       {
+               TypeSpec[] targs;
+               TypeParameterSpec[] constraints;
+               readonly TypeSpec open_type;
+
+               public InflatedTypeSpec (TypeSpec openType, TypeSpec declaringType, TypeSpec[] targs)
+                       : base (openType.Kind, declaringType, openType.MemberDefinition, null, openType.Modifiers)
+               {
+                       if (targs == null)
+                               throw new ArgumentNullException ("targs");
+
+#if DEBUG
+                       if (ID == 4937)
+                               Console.WriteLine ("HIT");
+#endif
+
+//                     this.state = openType.state;
+                       this.open_type = openType;
+                       this.targs = targs;
+               }
+
+               #region Properties
+
+               public override TypeSpec BaseType {
                        get {
-                               return attribute_target;
+                               if (cache == null || (state & StateFlags.PendingBaseTypeInflate) != 0)
+                                       InitializeMemberCache (true);
+
+                               return base.BaseType;
                        }
                }
 
                //
-               // IMemberContainer
+               // Inflated type parameters with constraints array, mapping with type arguments is based on index
                //
+               public TypeParameterSpec[] Constraints {
+                       get {
+                               if (constraints == null) {
+                                       var inflator = new TypeParameterInflator (this, MemberDefinition.TypeParameters, targs);
+                                       constraints = TypeParameterSpec.InflateConstraints (inflator, MemberDefinition.TypeParameters);
+                               }
 
-               string IMemberContainer.Name {
-                       get { return Name; }
+                               return constraints;
+                       }
                }
 
-               MemberCache IMemberContainer.BaseCache {
+               public override IList<TypeSpec> Interfaces {
                        get {
-                               if (gc == null)
-                                       return null;
-
-                               if (gc.EffectiveBaseClass.BaseType == null)
-                                       return null;
+                               if (cache == null)
+                                       InitializeMemberCache (true);
 
-                               return TypeManager.LookupMemberCache (gc.EffectiveBaseClass.BaseType);
+                               return base.Interfaces;
                        }
                }
 
-               bool IMemberContainer.IsInterface {
-                       get { return false; }
-               }
+               public override MemberCache MemberCacheTypes {
+                       get {
+                               if (cache == null)
+                                       InitializeMemberCache (true);
 
-               MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
-               {
-                       throw new NotSupportedException ();
+                               return cache;
+                       }
                }
 
-               public MemberCache MemberCache {
+               //
+               // Types used to inflate the generic  type
+               //
+               public override TypeSpec[] TypeArguments {
                        get {
-                               if (member_cache != null)
-                                       return member_cache;
-
-                               if (gc == null)
-                                       return null;
-
-                               Type[] ifaces = TypeManager.ExpandInterfaces (gc.InterfaceConstraints);
-                               member_cache = new MemberCache (this, gc.EffectiveBaseClass, ifaces);
-
-                               return member_cache;
+                               return targs;
                        }
                }
 
-               public MemberList FindMembers (MemberTypes mt, BindingFlags bf,
-                                              MemberFilter filter, object criteria)
-               {
-                       if (gc == null)
-                               return MemberList.Empty;
-
-                       var members = new List<MemberInfo> ();
-
-                       if (gc.HasClassConstraint) {
-                               MemberList list = TypeManager.FindMembers (
-                                       gc.ClassConstraint, mt, bf, filter, criteria);
+               #endregion
 
-                               members.AddRange (list);
-                       }
+               Type CreateMetaInfo (TypeParameterMutator mutator)
+               {
+                       //
+                       // Converts nested type arguments into right order
+                       // Foo<string, bool>.Bar<int> => string, bool, int
+                       //
+                       var all = new List<Type> ();
+                       TypeSpec type = this;
+                       TypeSpec definition = type;
+                       do {
+                               if (type.GetDefinition().IsGeneric) {
+                                       all.InsertRange (0,
+                                               type.TypeArguments != TypeSpec.EmptyTypes ?
+                                               type.TypeArguments.Select (l => l.GetMetaInfo ()) :
+                                               type.MemberDefinition.TypeParameters.Select (l => l.GetMetaInfo ()));
+                               }
 
-                       Type[] ifaces = TypeManager.ExpandInterfaces (gc.InterfaceConstraints);
-                       foreach (Type t in ifaces) {
-                               MemberList list = TypeManager.FindMembers (
-                                       t, mt, bf, filter, criteria);
+                               definition = definition.GetDefinition ();
+                               type = type.DeclaringType;
+                       } while (type != null);
 
-                               members.AddRange (list);
-                       }
+                       return definition.GetMetaInfo ().MakeGenericType (all.ToArray ());
+               }
 
-                       return new MemberList (members);
+               public override ObsoleteAttribute GetAttributeObsolete ()
+               {
+                       return open_type.GetAttributeObsolete ();
                }
 
-               public bool IsSubclassOf (Type t)
+               protected override bool IsNotCLSCompliant ()
                {
-                       if (type.Equals (t))
+                       if (base.IsNotCLSCompliant ())
                                return true;
 
-                       if (constraints != null)
-                               return constraints.IsSubclassOf (t);
+                       foreach (var ta in TypeArguments) {
+                               if (ta.MemberDefinition.IsNotCLSCompliant ())
+                                       return true;
+                       }
 
                        return false;
                }
 
-               public void InflateConstraints (Type declaring)
+               public override TypeSpec GetDefinition ()
                {
-                       if (constraints != null)
-                               gc = new InflatedConstraints (constraints, declaring);
+                       return open_type;
                }
-               
-               public override bool IsClsComplianceRequired ()
+
+               public override Type GetMetaInfo ()
                {
-                       return false;
+                       if (info == null)
+                               info = CreateMetaInfo (null);
+
+                       return info;
                }
 
-               protected class InflatedConstraints : GenericConstraints
+               public override string GetSignatureForError ()
                {
-                       GenericConstraints gc;
-                       Type base_type;
-                       Type class_constraint;
-                       Type[] iface_constraints;
-                       Type[] dargs;
+                       if (TypeManager.IsNullableType (open_type))
+                               return targs[0].GetSignatureForError () + "?";
 
-                       public InflatedConstraints (GenericConstraints gc, Type declaring)
-                               : this (gc, TypeManager.GetTypeArguments (declaring))
-                       { }
+                       if (MemberDefinition is AnonymousTypeClass)
+                               return ((AnonymousTypeClass) MemberDefinition).GetSignatureForError ();
 
-                       public InflatedConstraints (GenericConstraints gc, Type[] dargs)
-                       {
-                               this.gc = gc;
-                               this.dargs = dargs;
-
-                               var list = new List<Type> ();
-                               if (gc.HasClassConstraint)
-                                       list.Add (inflate (gc.ClassConstraint));
-                               foreach (Type iface in gc.InterfaceConstraints)
-                                       list.Add (inflate (iface));
-
-                               bool has_class_constr = false;
-                               if (list.Count > 0) {
-                                       Type first = (Type) list [0];
-                                       has_class_constr = !first.IsGenericParameter && !first.IsInterface;
-                               }
+                       return base.GetSignatureForError ();
+               }
+
+               protected override string GetTypeNameSignature ()
+               {
+                       if (targs.Length == 0 || MemberDefinition is AnonymousTypeClass)
+                               return null;
 
-                               if ((list.Count > 0) && has_class_constr) {
-                                       class_constraint = (Type) list [0];
-                                       iface_constraints = new Type [list.Count - 1];
-                                       list.CopyTo (1, iface_constraints, 0, list.Count - 1);
+                       return "<" + TypeManager.CSharpName (targs) + ">";
+               }
+
+               protected override void InitializeMemberCache (bool onlyTypes)
+               {
+                       if (cache == null)
+                               cache = new MemberCache (open_type.MemberCache);
+
+                       TypeParameterSpec[] tparams_full;
+                       TypeSpec[] targs_full = targs;
+                       if (IsNested) {
+                               //
+                               // Special case is needed when we are inflating an open type (nested type definition)
+                               // on inflated parent. Consider following case
+                               //
+                               // Foo<T>.Bar<U> => Foo<string>.Bar<U>
+                               //
+                               // Any later inflation of Foo<string>.Bar<U> has to also inflate T if used inside Bar<U>
+                               //
+                               List<TypeSpec> merged_targs = null;
+                               List<TypeParameterSpec> merged_tparams = null;
+
+                               var type = DeclaringType;
+
+                               do {
+                                       if (type.TypeArguments.Length > 0) {
+                                               if (merged_targs == null) {
+                                                       merged_targs = new List<TypeSpec> ();
+                                                       merged_tparams = new List<TypeParameterSpec> ();
+                                                       if (targs.Length > 0) {
+                                                               merged_targs.AddRange (targs);
+                                                               merged_tparams.AddRange (open_type.MemberDefinition.TypeParameters);
+                                                       }
+                                               }
+                                               merged_tparams.AddRange (type.MemberDefinition.TypeParameters);
+                                               merged_targs.AddRange (type.TypeArguments);
+                                       }
+                                       type = type.DeclaringType;
+                               } while (type != null);
+
+                               if (merged_targs != null) {
+                                       // Type arguments are not in the right order but it should not matter in this case
+                                       targs_full = merged_targs.ToArray ();
+                                       tparams_full = merged_tparams.ToArray ();
+                               } else if (targs.Length == 0) {
+                                       tparams_full = TypeParameterSpec.EmptyTypes;
                                } else {
-                                       iface_constraints = new Type [list.Count];
-                                       list.CopyTo (iface_constraints, 0);
+                                       tparams_full = open_type.MemberDefinition.TypeParameters;
                                }
-
-                               if (HasValueTypeConstraint)
-                                       base_type = TypeManager.value_type;
-                               else if (class_constraint != null)
-                                       base_type = class_constraint;
-                               else
-                                       base_type = TypeManager.object_type;
+                       } else if (targs.Length == 0) {
+                               tparams_full = TypeParameterSpec.EmptyTypes;
+                       } else {
+                               tparams_full = open_type.MemberDefinition.TypeParameters;
                        }
 
-                       Type inflate (Type t)
-                       {
-                               if (t == null)
-                                       return null;
-                               if (t.IsGenericParameter)
-                                       return t.GenericParameterPosition < dargs.Length ? dargs [t.GenericParameterPosition] : t;
-                               if (t.IsGenericType) {
-                                       Type[] args = t.GetGenericArguments ();
-                                       Type[] inflated = new Type [args.Length];
+                       var inflator = new TypeParameterInflator (this, tparams_full, targs_full);
 
-                                       for (int i = 0; i < args.Length; i++)
-                                               inflated [i] = inflate (args [i]);
+                       //
+                       // Two stage inflate due to possible nested types recursive
+                       // references
+                       //
+                       // class A<T> {
+                       //    B b;
+                       //    class B {
+                       //      T Value;
+                       //    }
+                       // }
+                       //
+                       // When resolving type of `b' members of `B' cannot be 
+                       // inflated because are not yet available in membercache
+                       //
+                       if ((state & StateFlags.PendingMemberCacheMembers) == 0) {
+                               open_type.MemberCache.InflateTypes (cache, inflator);
 
-                                       t = t.GetGenericTypeDefinition ();
-                                       t = t.MakeGenericType (inflated);
+                               //
+                               // Inflate any implemented interfaces
+                               //
+                               if (open_type.Interfaces != null) {
+                                       ifaces = new List<TypeSpec> (open_type.Interfaces.Count);
+                                       foreach (var iface in open_type.Interfaces) {
+                                               var iface_inflated = inflator.Inflate (iface);
+                                               AddInterface (iface_inflated);
+                                       }
                                }
 
-                               return t;
+                               //
+                               // Handles the tricky case of recursive nested base generic type
+                               //
+                               // class A<T> : Base<A<T>.Nested> {
+                               //    class Nested {}
+                               // }
+                               //
+                               // When inflating A<T>. base type is not yet known, secondary
+                               // inflation is required (not common case) once base scope
+                               // is known
+                               //
+                               if (open_type.BaseType == null) {
+                                       if (IsClass)
+                                               state |= StateFlags.PendingBaseTypeInflate;
+                               } else {
+                                       BaseType = inflator.Inflate (open_type.BaseType);
+                               }
+                       } else if ((state & StateFlags.PendingBaseTypeInflate) != 0) {
+                               BaseType = inflator.Inflate (open_type.BaseType);
+                               state &= ~StateFlags.PendingBaseTypeInflate;
                        }
 
-                       public override GenericParameterAttributes Attributes {
-                               get { return gc.Attributes; }
+                       if (onlyTypes) {
+                               state |= StateFlags.PendingMemberCacheMembers;
+                               return;
                        }
 
-                       public override Type ClassConstraint {
-                               get { return class_constraint; }
-                       }
+                       var tc = open_type.MemberDefinition as TypeContainer;
+                       if (tc != null && !tc.HasMembersDefined)
+                               throw new InternalErrorException ("Inflating MemberCache with undefined members");
 
-                       public override Type EffectiveBaseClass {
-                               get { return base_type; }
+                       if ((state & StateFlags.PendingBaseTypeInflate) != 0) {
+                               BaseType = inflator.Inflate (open_type.BaseType);
+                               state &= ~StateFlags.PendingBaseTypeInflate;
                        }
 
-                       public override Type[] InterfaceConstraints {
-                               get { return iface_constraints; }
-                       }
+                       state &= ~StateFlags.PendingMemberCacheMembers;
+                       open_type.MemberCache.InflateMembers (cache, open_type, inflator);
                }
-       }
 
-       /// <summary>
-       ///   A TypeExpr which already resolved to a type parameter.
-       /// </summary>
-       public class TypeParameterExpr : TypeExpr {
-               
-               public TypeParameterExpr (TypeParameter type_parameter, Location loc)
+               public override TypeSpec Mutate (TypeParameterMutator mutator)
                {
-                       this.type = type_parameter.Type;
-                       this.eclass = ExprClass.TypeParameter;
-                       this.loc = loc;
-               }
+                       var targs = TypeArguments;
+                       if (targs != null)
+                               targs = mutator.Mutate (targs);
 
-               protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
-               {
-                       throw new NotSupportedException ();
-               }
+                       var decl = DeclaringType;
+                       if (IsNested && DeclaringType.IsGenericOrParentIsGeneric)
+                               decl = mutator.Mutate (decl);
 
-               public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
-               {
-                       return this;
-               }
+                       if (targs == TypeArguments && decl == DeclaringType)
+                               return this;
 
-               public override bool IsInterface {
-                       get { return false; }
-               }
+                       var mutated = (InflatedTypeSpec) MemberwiseClone ();
+                       if (decl != DeclaringType) {
+                               // Gets back MethodInfo in case of metaInfo was inflated
+                               //mutated.info = MemberCache.GetMember<TypeSpec> (DeclaringType.GetDefinition (), this).info;
 
-               public override bool CheckAccessLevel (IMemberContext ds)
-               {
-                       return true;
+                               mutated.declaringType = decl;
+                               mutated.state |= StateFlags.PendingMetaInflate;
+                       }
+
+                       if (targs != null) {
+                               mutated.targs = targs;
+                               mutated.info = null;
+                       }
+
+                       return mutated;
                }
        }
 
+
        //
        // Tracks the type arguments when instantiating a generic type. It's used
        // by both type arguments and type parameters
        //
-       public class TypeArguments {
+       public class TypeArguments
+       {
                List<FullNamedExpression> args;
-               Type[] atypes;
-               
-               public TypeArguments ()
-               {
-                       args = new List<FullNamedExpression> ();
-               }
+               TypeSpec[] atypes;
 
                public TypeArguments (params FullNamedExpression[] types)
                {
@@ -1198,11 +1528,6 @@ namespace Mono.CSharp {
                        args.Add (type);
                }
 
-               public void Add (TypeArguments new_args)
-               {
-                       args.AddRange (new_args.args);
-               }
-
                // TODO: Kill this monster
                public TypeParameterName[] GetDeclarations ()
                {
@@ -1213,7 +1538,8 @@ namespace Mono.CSharp {
                ///   We may only be used after Resolve() is called and return the fully
                ///   resolved types.
                /// </summary>
-               public Type[] Arguments {
+               // TODO: Not needed, just return type from resolve
+               public TypeSpec[] Arguments {
                        get {
                                return atypes;
                        }
@@ -1225,34 +1551,42 @@ namespace Mono.CSharp {
                        }
                }
 
+               public virtual bool IsEmpty {
+                       get {
+                               return false;
+                       }
+               }
+
                public string GetSignatureForError()
                {
-                       StringBuilder sb = new StringBuilder();
-                       for (int i = 0; i < Count; ++i)
-                       {
-                               Expression expr = (Expression)args [i];
-                               sb.Append(expr.GetSignatureForError());
+                       StringBuilder sb = new StringBuilder ();
+                       for (int i = 0; i < Count; ++i) {
+                               var expr = args[i];
+                               if (expr != null)
+                                       sb.Append (expr.GetSignatureForError ());
+
                                if (i + 1 < Count)
-                                       sb.Append(',');
+                                       sb.Append (',');
                        }
-                       return sb.ToString();
+
+                       return sb.ToString ();
                }
 
                /// <summary>
                ///   Resolve the type arguments.
                /// </summary>
-               public bool Resolve (IMemberContext ec)
+               public virtual bool Resolve (IMemberContext ec)
                {
                        if (atypes != null)
-                               return atypes.Length != 0;
+                           return atypes.Length != 0;
 
                        int count = args.Count;
                        bool ok = true;
 
-                       atypes = new Type [count];
+                       atypes = new TypeSpec [count];
 
                        for (int i = 0; i < count; i++){
-                               TypeExpr te = ((FullNamedExpression) args[i]).ResolveAsTypeTerminal (ec, false);
+                               TypeExpr te = args[i].ResolveAsTypeTerminal (ec, false);
                                if (te == null) {
                                        ok = false;
                                        continue;
@@ -1260,7 +1594,7 @@ namespace Mono.CSharp {
 
                                atypes[i] = te.Type;
 
-                               if (te.Type.IsSealed && te.Type.IsAbstract) {
+                               if (te.Type.IsStatic) {
                                        ec.Compiler.Report.Error (718, te.Location, "`{0}': static classes cannot be used as generic arguments",
                                                te.GetSignatureForError ());
                                        ok = false;
@@ -1275,7 +1609,7 @@ namespace Mono.CSharp {
                        }
 
                        if (!ok)
-                               atypes = Type.EmptyTypes;
+                               atypes = TypeSpec.EmptyTypes;
 
                        return ok;
                }
@@ -1290,6 +1624,26 @@ namespace Mono.CSharp {
                }
        }
 
+       public class UnboundTypeArguments : TypeArguments
+       {
+               public UnboundTypeArguments (int arity)
+                       : base (new FullNamedExpression[arity])
+               {
+               }
+
+               public override bool IsEmpty {
+                       get {
+                               return true;
+                       }
+               }
+
+               public override bool Resolve (IMemberContext ec)
+               {
+                       // should not be called
+                       throw new NotSupportedException ();
+               }
+       }
+
        public class TypeParameterName : SimpleName
        {
                Attributes attributes;
@@ -1320,41 +1674,23 @@ namespace Mono.CSharp {
                }
        }
 
-       /// <summary>
-       ///   A reference expression to generic type
-       /// </summary>  
+       //
+       // A type expression of generic type with type arguments
+       //
        class GenericTypeExpr : TypeExpr
        {
                TypeArguments args;
-               Type[] gen_params;      // TODO: Waiting for constrains check cleanup
-               Type open_type;
-
-               //
-               // Should be carefully used only with defined generic containers. Type parameters
-               // can be used as type arguments in this case.
-               //
-               // TODO: This could be GenericTypeExpr specialization
-               //
-               public GenericTypeExpr (DeclSpace gType, Location l)
-               {
-                       open_type = gType.TypeBuilder.GetGenericTypeDefinition ();
-
-                       args = new TypeArguments ();
-                       foreach (TypeParameter type_param in gType.TypeParameters)
-                               args.Add (new TypeParameterExpr (type_param, l));
-
-                       this.loc = l;
-               }
+               TypeSpec open_type;
+               bool constraints_checked;
 
                /// <summary>
                ///   Instantiate the generic type `t' with the type arguments `args'.
                ///   Use this constructor if you already know the fully resolved
                ///   generic type.
                /// </summary>          
-               public GenericTypeExpr (Type t, TypeArguments args, Location l)
+               public GenericTypeExpr (TypeSpec open_type, TypeArguments args, Location l)
                {
-                       open_type = t.GetGenericTypeDefinition ();
-
+                       this.open_type = open_type;
                        loc = l;
                        this.args = args;
                }
@@ -1370,38 +1706,51 @@ namespace Mono.CSharp {
 
                protected override TypeExpr DoResolveAsTypeStep (IMemberContext ec)
                {
-                       eclass = ExprClass.Type;
-
                        if (!args.Resolve (ec))
                                return null;
 
-                       gen_params = open_type.GetGenericArguments ();
-                       Type[] atypes = args.Arguments;
-                       
-                       if (atypes.Length != gen_params.Length) {
-                               Namespace.Error_InvalidNumberOfTypeArguments (ec.Compiler.Report, open_type, loc);
-                               return null;
-                       }
+                       TypeSpec[] atypes = args.Arguments;
 
                        //
                        // Now bind the parameters
                        //
                        type = open_type.MakeGenericType (atypes);
+
+                       //
+                       // Check constraints when context is not method/base type
+                       //
+                       if (!ec.HasUnresolvedConstraints)
+                               CheckConstraints (ec);
+
                        return this;
                }
 
-               /// <summary>
-               ///   Check the constraints; we're called from ResolveAsTypeTerminal()
-               ///   after fully resolving the constructed type.
-               /// </summary>
+               //
+               // Checks the constraints of open generic type against type
+               // arguments. Has to be called onafter all members are defined
+               //
                public bool CheckConstraints (IMemberContext ec)
                {
-                       return ConstraintChecker.CheckConstraints (ec, open_type, gen_params, args.Arguments, loc);
+                       if (constraints_checked)
+                               return true;
+
+                       constraints_checked = true;
+
+                       var gtype = (InflatedTypeSpec) type;
+                       var constraints = gtype.Constraints;
+                       if (constraints == null)
+                               return true;
+
+                       return ConstraintChecker.CheckAll (open_type, args.Arguments, constraints, loc, ec.Compiler.Report);
                }
        
                public override bool CheckAccessLevel (IMemberContext mc)
                {
-                       return mc.CurrentTypeDefinition.CheckAccessLevel (open_type);
+                       DeclSpace c = mc.CurrentMemberDefinition as DeclSpace;
+                       if (c == null)
+                               c = mc.CurrentMemberDefinition.Parent;
+
+                       return c.CheckAccessLevel (open_type);
                }
 
                public bool HasDynamicArguments ()
@@ -1409,36 +1758,19 @@ namespace Mono.CSharp {
                        return HasDynamicArguments (args.Arguments);
                }
 
-               static bool HasDynamicArguments (Type[] args)
+               static bool HasDynamicArguments (TypeSpec[] args)
                {
-                       foreach (var item in args)
-                       {
+                       foreach (var item in args) {
+                               if (item == InternalType.Dynamic)
+                                       return true;
+
                                if (TypeManager.IsGenericType (item))
                                        return HasDynamicArguments (TypeManager.GetTypeArguments (item));
-
-                               if (TypeManager.IsDynamicType (item))
-                                       return true;
                        }
 
                        return false;
                }
 
-               public override bool IsClass {
-                       get { return open_type.IsClass; }
-               }
-
-               public override bool IsValueType {
-                       get { return TypeManager.IsStruct (open_type); }
-               }
-
-               public override bool IsInterface {
-                       get { return open_type.IsInterface; }
-               }
-
-               public override bool IsSealed {
-                       get { return open_type.IsSealed; }
-               }
-
                public override bool Equals (object obj)
                {
                        GenericTypeExpr cobj = obj as GenericTypeExpr;
@@ -1455,335 +1787,144 @@ namespace Mono.CSharp {
                {
                        return base.GetHashCode ();
                }
-       }
-
-       public abstract class ConstraintChecker
-       {
-               protected readonly Type[] gen_params;
-               protected readonly Type[] atypes;
-               protected readonly Location loc;
-               protected Report Report;
-
-               protected ConstraintChecker (Type[] gen_params, Type[] atypes, Location loc, Report r)
-               {
-                       this.gen_params = gen_params;
-                       this.atypes = atypes;
-                       this.loc = loc;
-                       this.Report = r;
-               }
-
-               /// <summary>
-               ///   Check the constraints; we're called from ResolveAsTypeTerminal()
-               ///   after fully resolving the constructed type.
-               /// </summary>
-               public bool CheckConstraints (IMemberContext ec)
-               {
-                       for (int i = 0; i < gen_params.Length; i++) {
-                               if (!CheckConstraints (ec, i))
-                                       return false;
-                       }
-
-                       return true;
-               }
-
-               protected bool CheckConstraints (IMemberContext ec, int index)
-               {
-                       Type atype = TypeManager.TypeToCoreType (atypes [index]);
-                       Type ptype = gen_params [index];
-
-                       if (atype == ptype)
-                               return true;
-
-                       Expression aexpr = new EmptyExpression (atype);
-
-                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (ptype);
-                       if (gc == null)
-                               return true;
-
-                       bool is_class, is_struct;
-                       if (atype.IsGenericParameter) {
-                               GenericConstraints agc = TypeManager.GetTypeParameterConstraints (atype);
-                               if (agc != null) {
-                                       if (agc is Constraints) {
-                                               // FIXME: No constraints can be resolved here, we are in
-                                               // completely wrong/different context. This path is hit
-                                               // when resolving base type of unresolved generic type
-                                               // with constraints. We are waiting with CheckConsttraints
-                                               // after type-definition but not in this case
-                                               if (!((Constraints) agc).Resolve (null, null, Report))
-                                                       return true;
-                                       }
-                                       is_class = agc.IsReferenceType;
-                                       is_struct = agc.IsValueType;
-                               } else {
-                                       is_class = is_struct = false;
-                               }
-                       } else {
-                               is_class = TypeManager.IsReferenceType (atype);
-                               is_struct = TypeManager.IsValueType (atype) && !TypeManager.IsNullableType (atype);
-                       }
-
-                       //
-                       // First, check the `class' and `struct' constraints.
-                       //
-                       if (gc.HasReferenceTypeConstraint && !is_class) {
-                               Report.Error (452, loc, "The type `{0}' must be " +
-                                             "a reference type in order to use it " +
-                                             "as type parameter `{1}' in the " +
-                                             "generic type or method `{2}'.",
-                                             TypeManager.CSharpName (atype),
-                                             TypeManager.CSharpName (ptype),
-                                             GetSignatureForError ());
-                               return false;
-                       } else if (gc.HasValueTypeConstraint && !is_struct) {
-                               Report.Error (453, loc, "The type `{0}' must be a " +
-                                             "non-nullable value type in order to use it " +
-                                             "as type parameter `{1}' in the " +
-                                             "generic type or method `{2}'.",
-                                             TypeManager.CSharpName (atype),
-                                             TypeManager.CSharpName (ptype),
-                                             GetSignatureForError ());
-                               return false;
-                       }
-
-                       //
-                       // The class constraint comes next.
-                       //
-                       if (gc.HasClassConstraint) {
-                               if (!CheckConstraint (ec, ptype, aexpr, gc.ClassConstraint))
-                                       return false;
-                       }
-
-                       //
-                       // Now, check the interface constraints.
-                       //
-                       if (gc.InterfaceConstraints != null) {
-                               foreach (Type it in gc.InterfaceConstraints) {
-                                       if (!CheckConstraint (ec, ptype, aexpr, it))
-                                               return false;
-                               }
-                       }
-
-                       //
-                       // Finally, check the constructor constraint.
-                       //
-
-                       if (!gc.HasConstructorConstraint)
-                               return true;
-
-                       if (TypeManager.IsValueType (atype))
-                               return true;
-
-                       if (HasDefaultConstructor (atype))
-                               return true;
-
-                       Report_SymbolRelatedToPreviousError ();
-                       Report.SymbolRelatedToPreviousError (atype);
-                       Report.Error (310, loc, "The type `{0}' must have a public " +
-                                     "parameterless constructor in order to use it " +
-                                     "as parameter `{1}' in the generic type or " +
-                                     "method `{2}'",
-                                     TypeManager.CSharpName (atype),
-                                     TypeManager.CSharpName (ptype),
-                                     GetSignatureForError ());
-                       return false;
-               }
-               
-               Type InflateType(IMemberContext ec, Type ctype)
-               {
-                       Type[] types = TypeManager.GetTypeArguments (ctype);
-
-                       TypeArguments new_args = new TypeArguments ();
-
-                       for (int i = 0; i < types.Length; i++) {
-                               Type t = TypeManager.TypeToCoreType (types [i]);
-
-                               if (t.IsGenericParameter) {
-                                       int pos = t.GenericParameterPosition;
-                                       if (t.DeclaringMethod == null && this is MethodConstraintChecker) {
-                                               Type parent = ((MethodConstraintChecker) this).declaring_type;
-                                               t = parent.GetGenericArguments ()[pos];
-                                       } else {
-                                               t = atypes [pos];
-                                       }
-                               } else if(TypeManager.HasGenericArguments(t)) {
-                                       t = InflateType (ec, t);
-                                       if (t == null) {
-                                               return null;
-                                       }
-                               }
-                               new_args.Add (new TypeExpression (t, loc));
-                       }
-
-                       TypeExpr ct = new GenericTypeExpr (ctype, new_args, loc);
-                       if (ct.ResolveAsTypeStep (ec, false) == null)
-                               return null;
-                       
-                       return ct.Type;
-               }
+       }
 
-               protected bool CheckConstraint (IMemberContext ec, Type ptype, Expression expr,
-                                               Type ctype)
+       static class ConstraintChecker
+       {
+               /// <summary>
+               ///   Check the constraints; we're called from ResolveAsTypeTerminal()
+               ///   after fully resolving the constructed type.
+               /// </summary>
+               public static bool CheckAll (MemberSpec context, TypeSpec[] targs, TypeParameterSpec[] tparams, Location loc, Report report)
                {
-                       //
-                       // All this is needed because we don't have
-                       // real inflated type hierarchy
-                       //
-                       if (TypeManager.HasGenericArguments (ctype)) {
-                               ctype = InflateType (ec, ctype);
-                               if(ctype == null) {
+                       for (int i = 0; i < tparams.Length; i++) {
+                               if (!CheckConstraint (context, targs [i], tparams [i], loc, report))
                                        return false;
-                               }
-                       } else if (ctype.IsGenericParameter) {
-                               int pos = ctype.GenericParameterPosition;
-                               if (ctype.DeclaringMethod == null) {
-                                       // FIXME: Implement
-                                       return true;
-                               } else {                                
-                                       ctype = atypes [pos];
-                               }
                        }
 
-                       if (Convert.ImplicitStandardConversionExists (expr, ctype))
-                               return true;
-
-                       Report_SymbolRelatedToPreviousError ();
-                       Report.SymbolRelatedToPreviousError (expr.Type);
-
-                       if (TypeManager.IsNullableType (expr.Type) && ctype.IsInterface) {
-                               Report.Error (313, loc,
-                                       "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. " +
-                                       "The nullable type `{0}' never satisfies interface constraint of type `{3}'",
-                                       TypeManager.CSharpName (expr.Type), TypeManager.CSharpName (ptype),
-                                       GetSignatureForError (), TypeManager.CSharpName (ctype));
-                       } else {
-                               Report.Error (309, loc,
-                                       "The type `{0}' must be convertible to `{1}' in order to " +
-                                       "use it as parameter `{2}' in the generic type or method `{3}'",
-                                       TypeManager.CSharpName (expr.Type), TypeManager.CSharpName (ctype),
-                                       TypeManager.CSharpName (ptype), GetSignatureForError ());
-                       }
-                       return false;
+                       return true;
                }
 
-               static bool HasDefaultConstructor (Type atype)
+               static bool CheckConstraint (MemberSpec context, TypeSpec atype, TypeParameterSpec tparam, Location loc, Report report)
                {
-                       TypeParameter tparam = TypeManager.LookupTypeParameter (atype);
-                       if (tparam != null) {
-                               if (tparam.GenericConstraints == null)
-                                       return false;
-                                               
-                               return tparam.GenericConstraints.HasConstructorConstraint || 
-                                       tparam.GenericConstraints.HasValueTypeConstraint;
-                       }
-               
-                       if (atype.IsAbstract)
+                       //
+                       // First, check the `class' and `struct' constraints.
+                       //
+                       if (tparam.HasSpecialClass && !TypeManager.IsReferenceType (atype)) {
+                               report.Error (452, loc,
+                                       "The type `{0}' must be a reference type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
+                                       TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
                                return false;
+                       }
 
-               again:
-                       atype = TypeManager.DropGenericTypeArguments (atype);
-                       if (atype is TypeBuilder) {
-                               TypeContainer tc = TypeManager.LookupTypeContainer (atype);
-                               if (tc.InstanceConstructors == null) {
-                                       atype = atype.BaseType;
-                                       goto again;
-                               }
+                       if (tparam.HasSpecialStruct && (!TypeManager.IsValueType (atype) || TypeManager.IsNullableType (atype))) {
+                               report.Error (453, loc,
+                                       "The type `{0}' must be a non-nullable value type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
+                                       TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
+                               return false;
+                       }
 
-                               foreach (Constructor c in tc.InstanceConstructors) {
-                                       if ((c.ModFlags & Modifiers.PUBLIC) == 0)
-                                               continue;
-                                       if ((c.Parameters.FixedParameters != null) &&
-                                           (c.Parameters.FixedParameters.Length != 0))
-                                               continue;
-                                       if (c.Parameters.HasArglist || c.Parameters.HasParams)
-                                               continue;
+                       //
+                       // The class constraint comes next.
+                       //
+                       if (tparam.HasTypeConstraint) {
+                               CheckConversion (context, atype, tparam, tparam.BaseType, loc, report);
+                       }
 
-                                       return true;
+                       //
+                       // Now, check the interfaces and type parameters constraints
+                       //
+                       if (tparam.Interfaces != null) {
+                               if (TypeManager.IsNullableType (atype)) {
+                                       report.Error (313, loc,
+                                               "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. The nullable type `{0}' never satisfies interface constraint",
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ());
+                               } else {
+                                       foreach (TypeSpec iface in tparam.Interfaces) {
+                                               CheckConversion (context, atype, tparam, iface, loc, report);
+                                       }
                                }
                        }
 
-                       MemberInfo [] list = TypeManager.MemberLookup (null, null, atype, MemberTypes.Constructor,
-                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                               ConstructorInfo.ConstructorName, null);
+                       //
+                       // Finally, check the constructor constraint.
+                       //
+                       if (!tparam.HasSpecialConstructor)
+                               return true;
 
-                       if (list == null)
+                       if (!HasDefaultConstructor (atype)) {
+                               report.SymbolRelatedToPreviousError (atype);
+                               report.Error (310, loc,
+                                       "The type `{0}' must have a public parameterless constructor in order to use it as parameter `{1}' in the generic type or method `{2}'",
+                                       TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
                                return false;
-
-                       foreach (MethodBase mb in list) {
-                               AParametersCollection pd = TypeManager.GetParameterData (mb);
-                               if (pd.Count == 0)
-                                       return true;
                        }
 
-                       return false;
+                       return true;
                }
 
-               protected abstract string GetSignatureForError ();
-               protected abstract void Report_SymbolRelatedToPreviousError ();
-
-               public static bool CheckConstraints (IMemberContext ec, MethodBase definition,
-                                                    MethodBase instantiated, Location loc)
+               static void CheckConversion (MemberSpec context, TypeSpec atype, TypeParameterSpec tparam, TypeSpec ttype, Location loc, Report report)
                {
-                       MethodConstraintChecker checker = new MethodConstraintChecker (
-                               definition, instantiated.DeclaringType, definition.GetGenericArguments (),
-                               instantiated.GetGenericArguments (), loc, ec.Compiler.Report);
-
-                       return checker.CheckConstraints (ec);
+                       var expr = new EmptyExpression (atype);
+                       if (!Convert.ImplicitStandardConversionExists (expr, ttype)) {
+                               report.SymbolRelatedToPreviousError (tparam);
+                               if (TypeManager.IsValueType (atype)) {
+                                       report.Error (315, loc, "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. There is no boxing conversion from `{0}' to `{3}'",
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError (), ttype.GetSignatureForError ());
+                               } else if (atype.IsGenericParameter) {
+                                       report.Error (314, loc, "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. There is no boxing or type parameter conversion from `{0}' to `{3}'",
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError (), ttype.GetSignatureForError ());
+                               } else {
+                                       report.Error (311, loc, "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. There is no implicit reference conversion from `{0}' to `{3}'",
+                                               atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError (), ttype.GetSignatureForError ());
+                               }
+                       }
                }
 
-               public static bool CheckConstraints (IMemberContext ec, Type gt, Type[] gen_params,
-                                                    Type[] atypes, Location loc)
+               static bool HasDefaultConstructor (TypeSpec atype)
                {
-                       TypeConstraintChecker checker = new TypeConstraintChecker (
-                               gt, gen_params, atypes, loc, ec.Compiler.Report);
-
-                       return checker.CheckConstraints (ec);
-               }
+                       var tp = atype as TypeParameterSpec;
+                       if (tp != null) {
+                               return tp.HasSpecialConstructor || tp.HasSpecialStruct;
+                       }
 
-               protected class MethodConstraintChecker : ConstraintChecker
-               {
-                       MethodBase definition;
-                       public Type declaring_type;
+                       if (atype.IsStruct || atype.IsEnum)
+                               return true;
 
-                       public MethodConstraintChecker (MethodBase definition, Type declaringType, Type[] gen_params,
-                                                       Type[] atypes, Location loc, Report r)
-                               : base (gen_params, atypes, loc, r)
-                       {
-                               this.declaring_type = declaringType;
-                               this.definition = definition;
-                       }
+                       if (atype.IsAbstract)
+                               return false;
 
-                       protected override string GetSignatureForError ()
-                       {
-                               return TypeManager.CSharpSignature (definition);
-                       }
+                       var tdef = atype.GetDefinition ();
 
-                       protected override void Report_SymbolRelatedToPreviousError ()
-                       {
-                               Report.SymbolRelatedToPreviousError (definition);
-                       }
-               }
+                       //
+                       // In some circumstances MemberCache is not yet populated and members
+                       // cannot be defined yet (recursive type new constraints)
+                       //
+                       // class A<T> where T : B<T>, new () {}
+                       // class B<T> where T : A<T>, new () {}
+                       //
+                       var tc = tdef.MemberDefinition as Class;
+                       if (tc != null) {
+                               if (tc.InstanceConstructors == null) {
+                                       // Default ctor will be generated later
+                                       return true;
+                               }
 
-               protected class TypeConstraintChecker : ConstraintChecker
-               {
-                       Type gt;
+                               foreach (var c in tc.InstanceConstructors) {
+                                       if (c.ParameterInfo.IsEmpty) {
+                                               if ((c.ModFlags & Modifiers.PUBLIC) != 0)
+                                                       return true;
+                                       }
+                               }
 
-                       public TypeConstraintChecker (Type gt, Type[] gen_params, Type[] atypes,
-                                                     Location loc, Report r)
-                               : base (gen_params, atypes, loc, r)
-                       {
-                               this.gt = gt;
+                               return false;
                        }
 
-                       protected override string GetSignatureForError ()
-                       {
-                               return TypeManager.CSharpName (gt);
-                       }
+                       var found = MemberCache.FindMember (tdef,
+                               MemberFilter.Constructor (ParametersCompiled.EmptyReadOnlyParameters),
+                               BindingRestriction.DeclaredOnly | BindingRestriction.InstanceOnly);
 
-                       protected override void Report_SymbolRelatedToPreviousError ()
-                       {
-                               Report.SymbolRelatedToPreviousError (gt);
-                       }
+                       return found != null && (found.Modifiers & Modifiers.PUBLIC) != 0;
                }
        }
 
@@ -1792,21 +1933,20 @@ namespace Mono.CSharp {
        /// </summary>
        public class GenericMethod : DeclSpace
        {
-               FullNamedExpression return_type;
                ParametersCompiled parameters;
 
                public GenericMethod (NamespaceEntry ns, DeclSpace parent, MemberName name,
                                      FullNamedExpression return_type, ParametersCompiled parameters)
                        : base (ns, parent, name, null)
                {
-                       this.return_type = return_type;
                        this.parameters = parameters;
                }
 
-               public override TypeContainer CurrentTypeDefinition {
-                       get {
-                               return Parent.CurrentTypeDefinition;
-                       }
+               public GenericMethod (NamespaceEntry ns, DeclSpace parent, MemberName name, TypeParameter[] tparams,
+                                         FullNamedExpression return_type, ParametersCompiled parameters)
+                       : this (ns, parent, name, return_type, parameters)
+               {
+                       this.type_params = tparams;
                }
 
                public override TypeParameter[] CurrentTypeParameters {
@@ -1820,13 +1960,14 @@ namespace Mono.CSharp {
                        throw new Exception ();
                }
 
-               public override bool Define ()
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
-                       for (int i = 0; i < TypeParameters.Length; i++)
-                               if (!TypeParameters [i].Resolve (this))
-                                       return false;
+                       throw new NotSupportedException ();
+               }
 
-                       return true;
+               public override bool Define ()
+               {
+                       throw new NotSupportedException ();
                }
 
                /// <summary>
@@ -1854,64 +1995,22 @@ namespace Mono.CSharp {
 
                        GenericTypeParameterBuilder[] gen_params = m.MethodBuilder.DefineGenericParameters (snames);
                        for (int i = 0; i < TypeParameters.Length; i++)
-                               TypeParameters [i].Define (gen_params [i]);
-
-                       if (!Define ())
-                               return false;
-
-                       for (int i = 0; i < TypeParameters.Length; i++) {
-                               if (!TypeParameters [i].ResolveType (this))
-                                       return false;
-                       }
+                               TypeParameters [i].Define (gen_params [i], null);
 
                        return true;
                }
 
-               /// <summary>
-               ///   We're called from MethodData.Define() after creating the MethodBuilder.
-               /// </summary>
-               public bool DefineType (IMemberContext ec, MethodBuilder mb,
-                                       MethodInfo implementing, bool is_override)
-               {
-                       for (int i = 0; i < TypeParameters.Length; i++)
-                               if (!TypeParameters [i].DefineType (
-                                           ec, mb, implementing, is_override))
-                                       return false;
-
-                       bool ok = parameters.Resolve (ec);
-
-                       if ((return_type != null) && (return_type.ResolveAsTypeTerminal (ec, false) == null))
-                               ok = false;
-
-                       return ok;
-               }
-
                public void EmitAttributes ()
                {
-                       for (int i = 0; i < TypeParameters.Length; i++)
-                               TypeParameters [i].Emit ();
-
                        if (OptAttributes != null)
                                OptAttributes.Emit ();
                }
 
-               public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
-                                                       MemberFilter filter, object criteria)
-               {
-                       throw new Exception ();
-               }
-
                public override string GetSignatureForError ()
                {
                        return base.GetSignatureForError () + parameters.GetSignatureForError ();
                }
 
-               public override MemberCache MemberCache {
-                       get {
-                               return null;
-                       }
-               }
-
                public override AttributeTargets AttributeTargets {
                        get {
                                return AttributeTargets.Method | AttributeTargets.ReturnValue;
@@ -1925,56 +2024,32 @@ namespace Mono.CSharp {
                public new void VerifyClsCompliance ()
                {
                        foreach (TypeParameter tp in TypeParameters) {
-                               if (tp.Constraints == null)
-                                       continue;
-
-                               tp.Constraints.VerifyClsCompliance (Report);
+                               tp.VerifyClsCompliance ();
                        }
                }
        }
 
-       partial class TypeManager
+       public partial class TypeManager
        {
-               public static TypeContainer LookupGenericTypeContainer (Type t)
+               public static Variance CheckTypeVariance (TypeSpec t, Variance expected, IMemberContext member)
                {
-                       t = DropGenericTypeArguments (t);
-                       return LookupTypeContainer (t);
-               }
-
-               public static Variance GetTypeParameterVariance (Type type)
-               {
-                       TypeParameter tparam = LookupTypeParameter (type);
-                       if (tparam != null)
-                               return tparam.Variance;
-
-                       switch (type.GenericParameterAttributes & GenericParameterAttributes.VarianceMask) {
-                       case GenericParameterAttributes.Covariant:
-                               return Variance.Covariant;
-                       case GenericParameterAttributes.Contravariant:
-                               return Variance.Contravariant;
-                       default:
-                               return Variance.None;
-                       }
-               }
-
-               public static Variance CheckTypeVariance (Type t, Variance expected, IMemberContext member)
-               {
-                       TypeParameter tp = LookupTypeParameter (t);
+                       var tp = t as TypeParameterSpec;
                        if (tp != null) {
                                Variance v = tp.Variance;
                                if (expected == Variance.None && v != expected ||
                                        expected == Variance.Covariant && v == Variance.Contravariant ||
-                                       expected == Variance.Contravariant && v == Variance.Covariant)
-                                       tp.ErrorInvalidVariance (member, expected);
+                                       expected == Variance.Contravariant && v == Variance.Covariant) {
+                                       ((TypeParameter)tp.MemberDefinition).ErrorInvalidVariance (member, expected);
+                               }
 
                                return expected;
                        }
 
-                       if (t.IsGenericType) {
-                               Type[] targs_definition = GetTypeArguments (DropGenericTypeArguments (t));
-                               Type[] targs = GetTypeArguments (t);
-                               for (int i = 0; i < targs_definition.Length; ++i) {
-                                       Variance v = GetTypeParameterVariance (targs_definition[i]);
+                       if (t.TypeArguments.Length > 0) {
+                               var targs_definition = t.MemberDefinition.TypeParameters;
+                               TypeSpec[] targs = GetTypeArguments (t);
+                               for (int i = 0; i < targs.Length; ++i) {
+                                       Variance v = targs_definition[i].Variance;
                                        CheckTypeVariance (targs[i], (Variance) ((int)v * (int)expected), member);
                                }
 
@@ -1987,163 +2062,6 @@ namespace Mono.CSharp {
                        return Variance.None;
                }
 
-               public static bool IsVariantOf (Type type1, Type type2)
-               {
-                       if (!type1.IsGenericType || !type2.IsGenericType)
-                               return false;
-
-                       Type generic_target_type = DropGenericTypeArguments (type2);
-                       if (DropGenericTypeArguments (type1) != generic_target_type)
-                               return false;
-
-                       Type[] t1 = GetTypeArguments (type1);
-                       Type[] t2 = GetTypeArguments (type2);
-                       Type[] targs_definition = GetTypeArguments (generic_target_type);
-                       for (int i = 0; i < targs_definition.Length; ++i) {
-                               Variance v = GetTypeParameterVariance (targs_definition [i]);
-                               if (v == Variance.None) {
-                                       if (t1[i] == t2[i])
-                                               continue;
-                                       return false;
-                               }
-
-                               if (v == Variance.Covariant) {
-                                       if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t1 [i]), t2 [i]))
-                                               return false;
-                               } else if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t2[i]), t1[i])) {
-                                       return false;
-                               }
-                       }
-
-                       return true;
-               }
-
-               /// <summary>
-               ///   Check whether `a' and `b' may become equal generic types.
-               ///   The algorithm to do that is a little bit complicated.
-               /// </summary>
-               public static bool MayBecomeEqualGenericTypes (Type a, Type b, Type[] class_inferred,
-                                                              Type[] method_inferred)
-               {
-                       if (a.IsGenericParameter) {
-                               //
-                               // If a is an array of a's type, they may never
-                               // become equal.
-                               //
-                               while (b.IsArray) {
-                                       b = GetElementType (b);
-                                       if (a.Equals (b))
-                                               return false;
-                               }
-
-                               //
-                               // If b is a generic parameter or an actual type,
-                               // they may become equal:
-                               //
-                               //    class X<T,U> : I<T>, I<U>
-                               //    class X<T> : I<T>, I<float>
-                               // 
-                               if (b.IsGenericParameter || !b.IsGenericType) {
-                                       int pos = a.GenericParameterPosition;
-                                       Type[] args = a.DeclaringMethod != null ? method_inferred : class_inferred;
-                                       if (args [pos] == null) {
-                                               args [pos] = b;
-                                               return true;
-                                       }
-
-                                       return args [pos] == a;
-                               }
-
-                               //
-                               // We're now comparing a type parameter with a
-                               // generic instance.  They may become equal unless
-                               // the type parameter appears anywhere in the
-                               // generic instance:
-                               //
-                               //    class X<T,U> : I<T>, I<X<U>>
-                               //        -> error because you could instanciate it as
-                               //           X<X<int>,int>
-                               //
-                               //    class X<T> : I<T>, I<X<T>> -> ok
-                               //
-
-                               Type[] bargs = GetTypeArguments (b);
-                               for (int i = 0; i < bargs.Length; i++) {
-                                       if (a.Equals (bargs [i]))
-                                               return false;
-                               }
-
-                               return true;
-                       }
-
-                       if (b.IsGenericParameter)
-                               return MayBecomeEqualGenericTypes (b, a, class_inferred, method_inferred);
-
-                       //
-                       // At this point, neither a nor b are a type parameter.
-                       //
-                       // If one of them is a generic instance, let
-                       // MayBecomeEqualGenericInstances() compare them (if the
-                       // other one is not a generic instance, they can never
-                       // become equal).
-                       //
-
-                       if (a.IsGenericType || b.IsGenericType)
-                               return MayBecomeEqualGenericInstances (a, b, class_inferred, method_inferred);
-
-                       //
-                       // If both of them are arrays.
-                       //
-
-                       if (a.IsArray && b.IsArray) {
-                               if (a.GetArrayRank () != b.GetArrayRank ())
-                                       return false;
-                       
-                               a = GetElementType (a);
-                               b = GetElementType (b);
-
-                               return MayBecomeEqualGenericTypes (a, b, class_inferred, method_inferred);
-                       }
-
-                       //
-                       // Ok, two ordinary types.
-                       //
-
-                       return a.Equals (b);
-               }
-
-               //
-               // Checks whether two generic instances may become equal for some
-               // particular instantiation (26.3.1).
-               //
-               public static bool MayBecomeEqualGenericInstances (Type a, Type b,
-                                                                  Type[] class_inferred,
-                                                                  Type[] method_inferred)
-               {
-                       if (!a.IsGenericType || !b.IsGenericType)
-                               return false;
-                       if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
-                               return false;
-
-                       return MayBecomeEqualGenericInstances (
-                               GetTypeArguments (a), GetTypeArguments (b), class_inferred, method_inferred);
-               }
-
-               public static bool MayBecomeEqualGenericInstances (Type[] aargs, Type[] bargs,
-                                                                  Type[] class_inferred,
-                                                                  Type[] method_inferred)
-               {
-                       if (aargs.Length != bargs.Length)
-                               return false;
-
-                       for (int i = 0; i < aargs.Length; i++) {
-                               if (!MayBecomeEqualGenericTypes (aargs [i], bargs [i], class_inferred, method_inferred))
-                                       return false;
-                       }
-
-                       return true;
-               }
-
                /// <summary>
                ///   Type inference.  Try to infer the type arguments from `method',
                ///   which is invoked with the arguments `arguments'.  This is used
@@ -2153,32 +2071,16 @@ namespace Mono.CSharp {
                public static int InferTypeArguments (ResolveContext ec, Arguments arguments, ref MethodSpec method)
                {
                        ATypeInference ti = ATypeInference.CreateInstance (arguments);
-                       Type[] i_args = ti.InferMethodArguments (ec, method);
+                       TypeSpec[] i_args = ti.InferMethodArguments (ec, method);
                        if (i_args == null)
                                return ti.InferenceScore;
 
                        if (i_args.Length == 0)
                                return 0;
 
-                       method = method.Inflate (i_args);
+                       method = method.MakeGenericMethod (i_args);
                        return 0;
                }
-
-/*
-               public static bool InferTypeArguments (ResolveContext ec, AParametersCollection param, ref MethodBase method)
-               {
-                       if (!TypeManager.IsGenericMethod (method))
-                               return true;
-
-                       ATypeInference ti = ATypeInference.CreateInstance (DelegateCreation.CreateDelegateMethodArguments (param, Location.Null));
-                       Type[] i_args = ti.InferDelegateArguments (ec, method);
-                       if (i_args == null)
-                               return false;
-
-                       method = ((MethodInfo) method).MakeGenericMethod (i_args);
-                       return true;
-               }
-*/
        }
 
        abstract class ATypeInference
@@ -2204,8 +2106,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public abstract Type[] InferMethodArguments (ResolveContext ec, MethodSpec method);
-//             public abstract Type[] InferDelegateArguments (ResolveContext ec, MethodBase method);
+               public abstract TypeSpec[] InferMethodArguments (ResolveContext ec, MethodSpec method);
        }
 
        //
@@ -2229,38 +2130,12 @@ namespace Mono.CSharp {
                        }
                }
 
-/*
-               public override Type[] InferDelegateArguments (ResolveContext ec, MethodBase method)
-               {
-                       AParametersCollection pd = TypeManager.GetParameterData (method);
-                       if (arg_count != pd.Count)
-                               return null;
-
-                       Type[] d_gargs = method.GetGenericArguments ();
-                       TypeInferenceContext context = new TypeInferenceContext (d_gargs);
-
-                       // A lower-bound inference is made from each argument type Uj of D
-                       // to the corresponding parameter type Tj of M
-                       for (int i = 0; i < arg_count; ++i) {
-                               Type t = pd.Types [i];
-                               if (!t.IsGenericParameter)
-                                       continue;
-
-                               context.LowerBoundInference (arguments [i].Expr.Type, t);
-                       }
-
-                       if (!context.FixAllTypes (ec))
-                               return null;
-
-                       return context.InferredTypeArguments;
-               }
-*/
-               public override Type[] InferMethodArguments (ResolveContext ec, MethodSpec method)
+               public override TypeSpec[] InferMethodArguments (ResolveContext ec, MethodSpec method)
                {
-                       var method_generic_args = method.GetGenericArguments ();
+                       var method_generic_args = method.GenericDefinition.TypeParameters;
                        TypeInferenceContext context = new TypeInferenceContext (method_generic_args);
                        if (!context.UnfixedVariableExists)
-                               return Type.EmptyTypes;
+                               return TypeSpec.EmptyTypes;
 
                        AParametersCollection pd = method.Parameters;
                        if (!InferInPhases (ec, context, pd))
@@ -2281,12 +2156,12 @@ namespace Mono.CSharp {
                                params_arguments_start = arg_count;
                        }
 
-                       Type [] ptypes = methodParameters.Types;
+                       TypeSpec [] ptypes = methodParameters.Types;
                        
                        //
                        // The first inference phase
                        //
-                       Type method_parameter = null;
+                       TypeSpec method_parameter = null;
                        for (int i = 0; i < arg_count; i++) {
                                Argument a = arguments [i];
                                if (a == null)
@@ -2300,7 +2175,7 @@ namespace Mono.CSharp {
                                        else
                                                method_parameter = TypeManager.GetElementType (methodParameters.Types [params_arguments_start]);
 
-                                       ptypes = (Type[]) ptypes.Clone ();
+                                       ptypes = (TypeSpec[]) ptypes.Clone ();
                                        ptypes [i] = method_parameter;
                                }
 
@@ -2320,7 +2195,7 @@ namespace Mono.CSharp {
                                        continue;
                                }
 
-                               if (a.Expr.Type == TypeManager.null_type)
+                               if (a.Expr.Type == InternalType.Null)
                                        continue;
 
                                if (TypeManager.IsValueType (method_parameter)) {
@@ -2345,7 +2220,7 @@ namespace Mono.CSharp {
                        return DoSecondPhase (ec, tic, ptypes, !fixed_any);
                }
 
-               bool DoSecondPhase (ResolveContext ec, TypeInferenceContext tic, Type[] methodParameters, bool fixDependent)
+               bool DoSecondPhase (ResolveContext ec, TypeInferenceContext tic, TypeSpec[] methodParameters, bool fixDependent)
                {
                        bool fixed_any = false;
                        if (fixDependent && !tic.FixDependentTypes (ec, ref fixed_any))
@@ -2364,23 +2239,17 @@ namespace Mono.CSharp {
                        for (int i = 0; i < arg_count; i++) {
                                
                                // Align params arguments
-                               Type t_i = methodParameters [i >= methodParameters.Length ? methodParameters.Length - 1: i];
+                               TypeSpec t_i = methodParameters [i >= methodParameters.Length ? methodParameters.Length - 1: i];
                                
                                if (!TypeManager.IsDelegateType (t_i)) {
-                                       if (TypeManager.DropGenericTypeArguments (t_i) != TypeManager.expression_type)
+                                       if (t_i.GetDefinition () != TypeManager.expression_type)
                                                continue;
 
-                                       t_i = t_i.GetGenericArguments () [0];
+                                       t_i = TypeManager.GetTypeArguments (t_i) [0];
                                }
 
-                               var mi = Delegate.GetInvokeMethod (ec.Compiler, t_i, t_i);
-                               Type rtype = mi.ReturnType;
-
-#if MS_COMPATIBLE
-                               // Blablabla, because reflection does not work with dynamic types
-//                             Type[] g_args = t_i.GetGenericArguments ();
-//                             rtype = g_args[rtype.GenericParameterPosition];
-#endif
+                               var mi = Delegate.GetInvokeMethod (ec.Compiler, t_i);
+                               TypeSpec rtype = mi.ReturnType;
 
                                if (tic.IsReturnTypeNonDependent (ec, mi, rtype))
                                        score -= tic.OutputTypeInference (ec, arguments [i].Expr, t_i);
@@ -2402,10 +2271,10 @@ namespace Mono.CSharp {
 
                class BoundInfo
                {
-                       public readonly Type Type;
+                       public readonly TypeSpec Type;
                        public readonly BoundKind Kind;
 
-                       public BoundInfo (Type type, BoundKind kind)
+                       public BoundInfo (TypeSpec type, BoundKind kind)
                        {
                                this.Type = type;
                                this.Kind = kind;
@@ -2423,22 +2292,23 @@ namespace Mono.CSharp {
                        }
                }
 
-               readonly Type[] unfixed_types;
-               readonly Type[] fixed_types;
+               readonly TypeSpec[] unfixed_types;
+               readonly TypeSpec[] fixed_types;
                readonly List<BoundInfo>[] bounds;
                bool failed;
-               
-               public TypeInferenceContext (Type[] typeArguments)
+
+               // TODO MemberCache: Could it be TypeParameterSpec[] ??
+               public TypeInferenceContext (TypeSpec[] typeArguments)
                {
                        if (typeArguments.Length == 0)
                                throw new ArgumentException ("Empty generic arguments");
 
-                       fixed_types = new Type [typeArguments.Length];
+                       fixed_types = new TypeSpec [typeArguments.Length];
                        for (int i = 0; i < typeArguments.Length; ++i) {
                                if (typeArguments [i].IsGenericParameter) {
                                        if (bounds == null) {
                                                bounds = new List<BoundInfo> [typeArguments.Length];
-                                               unfixed_types = new Type [typeArguments.Length];
+                                               unfixed_types = new TypeSpec [typeArguments.Length];
                                        }
                                        unfixed_types [i] = typeArguments [i];
                                } else {
@@ -2453,19 +2323,19 @@ namespace Mono.CSharp {
                //
                public TypeInferenceContext ()
                {
-                       fixed_types = new Type [1];
-                       unfixed_types = new Type [1];
+                       fixed_types = new TypeSpec [1];
+                       unfixed_types = new TypeSpec [1];
                        unfixed_types[0] = InternalType.Arglist; // it can be any internal type
                        bounds = new List<BoundInfo> [1];
                }
 
-               public Type[] InferredTypeArguments {
+               public TypeSpec[] InferredTypeArguments {
                        get {
                                return fixed_types;
                        }
                }
 
-               public void AddCommonTypeBound (Type type)
+               public void AddCommonTypeBound (TypeSpec type)
                {
                        AddToBounds (new BoundInfo (type, BoundKind.Lower), 0);
                }
@@ -2500,17 +2370,17 @@ namespace Mono.CSharp {
                        a.Add (bound);
                }
                
-               bool AllTypesAreFixed (Type[] types)
+               bool AllTypesAreFixed (TypeSpec[] types)
                {
-                       foreach (Type t in types) {
+                       foreach (TypeSpec t in types) {
                                if (t.IsGenericParameter) {
                                        if (!IsFixed (t))
                                                return false;
                                        continue;
                                }
 
-                               if (t.IsGenericType)
-                                       return AllTypesAreFixed (t.GetGenericArguments ());
+                               if (TypeManager.IsGenericType (t))
+                                       return AllTypesAreFixed (TypeManager.GetTypeArguments (t));
                        }
                        
                        return true;
@@ -2519,26 +2389,27 @@ namespace Mono.CSharp {
                //
                // 26.3.3.8 Exact Inference
                //
-               public int ExactInference (Type u, Type v)
+               public int ExactInference (TypeSpec u, TypeSpec v)
                {
                        // If V is an array type
                        if (v.IsArray) {
                                if (!u.IsArray)
                                        return 0;
 
-                               if (u.GetArrayRank () != v.GetArrayRank ())
+                               // TODO MemberCache: GetMetaInfo ()
+                               if (u.GetMetaInfo ().GetArrayRank () != v.GetMetaInfo ().GetArrayRank ())
                                        return 0;
 
                                return ExactInference (TypeManager.GetElementType (u), TypeManager.GetElementType (v));
                        }
 
                        // If V is constructed type and U is constructed type
-                       if (v.IsGenericType && !v.IsGenericTypeDefinition) {
-                               if (!u.IsGenericType)
+                       if (TypeManager.IsGenericType (v)) {
+                               if (!TypeManager.IsGenericType (u))
                                        return 0;
 
-                               Type [] ga_u = u.GetGenericArguments ();
-                               Type [] ga_v = v.GetGenericArguments ();
+                               TypeSpec [] ga_u = TypeManager.GetTypeArguments (u);
+                               TypeSpec [] ga_v = TypeManager.GetTypeArguments (v);
                                if (ga_u.Length != ga_v.Length)
                                        return 0;
 
@@ -2593,39 +2464,32 @@ namespace Mono.CSharp {
                //
                // All unfixed type variables Xi which depend on no Xj are fixed
                //
-               public bool FixIndependentTypeArguments (ResolveContext ec, Type[] methodParameters, ref bool fixed_any)
+               public bool FixIndependentTypeArguments (ResolveContext ec, TypeSpec[] methodParameters, ref bool fixed_any)
                {
-                       var types_to_fix = new List<Type> (unfixed_types);
+                       var types_to_fix = new List<TypeSpec> (unfixed_types);
                        for (int i = 0; i < methodParameters.Length; ++i) {
-                               Type t = methodParameters[i];
+                               TypeSpec t = methodParameters[i];
 
                                if (!TypeManager.IsDelegateType (t)) {
-                                       if (TypeManager.DropGenericTypeArguments (t) != TypeManager.expression_type)
+                                       if (TypeManager.expression_type == null || t.MemberDefinition != TypeManager.expression_type.MemberDefinition)
                                                continue;
 
-                                       t = t.GetGenericArguments () [0];
+                                       t =  TypeManager.GetTypeArguments (t) [0];
                                }
 
                                if (t.IsGenericParameter)
                                        continue;
 
-                               var invoke = Delegate.GetInvokeMethod (ec.Compiler, t, t);
-                               Type rtype = invoke.ReturnType;
-                               if (!rtype.IsGenericParameter && !rtype.IsGenericType)
+                               var invoke = Delegate.GetInvokeMethod (ec.Compiler, t);
+                               TypeSpec rtype = invoke.ReturnType;
+                               if (!rtype.IsGenericParameter && !TypeManager.IsGenericType (rtype))
                                        continue;
 
-#if MS_COMPATIBLE
-                               // Blablabla, because reflection does not work with dynamic types
-//                             if (rtype.IsGenericParameter) {
-//                                     Type [] g_args = t.GetGenericArguments ();
-//                                     rtype = g_args [rtype.GenericParameterPosition];
-//                             }
-#endif
                                // Remove dependent types, they cannot be fixed yet
                                RemoveDependentTypes (types_to_fix, rtype);
                        }
 
-                       foreach (Type t in types_to_fix) {
+                       foreach (TypeSpec t in types_to_fix) {
                                if (t == null)
                                        continue;
 
@@ -2657,8 +2521,8 @@ namespace Mono.CSharp {
 
                        if (candidates.Count == 1) {
                                unfixed_types[i] = null;
-                               Type t = candidates[0].Type;
-                               if (t == TypeManager.null_type)
+                               TypeSpec t = candidates[0].Type;
+                               if (t == InternalType.Null)
                                        return false;
 
                                fixed_types [i] = t;
@@ -2670,16 +2534,16 @@ namespace Mono.CSharp {
                        // a standard implicit conversion to all the other
                        // candidate types.
                        //
-                       Type best_candidate = null;
+                       TypeSpec best_candidate = null;
                        int cii;
                        int candidates_count = candidates.Count;
                        for (int ci = 0; ci < candidates_count; ++ci) {
-                               BoundInfo bound = (BoundInfo)candidates [ci];
+                               BoundInfo bound = candidates [ci];
                                for (cii = 0; cii < candidates_count; ++cii) {
                                        if (cii == ci)
                                                continue;
 
-                                       BoundInfo cbound = (BoundInfo) candidates[cii];
+                                       BoundInfo cbound = candidates[cii];
                                        
                                        // Same type parameters with different bounds
                                        if (cbound.Type == bound.Type) {
@@ -2741,24 +2605,27 @@ namespace Mono.CSharp {
                //
                // Uses inferred types to inflate delegate type argument
                //
-               public Type InflateGenericArgument (Type parameter)
+               public TypeSpec InflateGenericArgument (TypeSpec parameter)
                {
-                       if (parameter.IsGenericParameter) {
+                       var tp = parameter as TypeParameterSpec;
+                       if (tp != null) {
                                //
                                // Inflate method generic argument (MVAR) only
                                //
-                               if (parameter.DeclaringMethod == null)
+                               if (!tp.IsMethodOwned)
                                        return parameter;
 
-                               return fixed_types [parameter.GenericParameterPosition];
+                               return fixed_types [tp.DeclaredPosition];
                        }
 
-                       if (parameter.IsGenericType) {
-                               Type [] parameter_targs = parameter.GetGenericArguments ();
-                               for (int ii = 0; ii < parameter_targs.Length; ++ii) {
-                                       parameter_targs [ii] = InflateGenericArgument (parameter_targs [ii]);
+                       var gt = parameter as InflatedTypeSpec;
+                       if (gt != null) {
+                               var inflated_targs = new TypeSpec [gt.TypeArguments.Length];
+                               for (int ii = 0; ii < inflated_targs.Length; ++ii) {
+                                       inflated_targs[ii] = InflateGenericArgument (gt.TypeArguments [ii]);
                                }
-                               return parameter.GetGenericTypeDefinition ().MakeGenericType (parameter_targs);
+
+                               return gt.GetDefinition ().MakeGenericType (inflated_targs);
                        }
 
                        return parameter;
@@ -2768,18 +2635,18 @@ namespace Mono.CSharp {
                // Tests whether all delegate input arguments are fixed and generic output type
                // requires output type inference 
                //
-               public bool IsReturnTypeNonDependent (ResolveContext ec, MethodSpec invoke, Type returnType)
+               public bool IsReturnTypeNonDependent (ResolveContext ec, MethodSpec invoke, TypeSpec returnType)
                {
                        if (returnType.IsGenericParameter) {
                                if (IsFixed (returnType))
                                    return false;
-                       } else if (returnType.IsGenericType) {
+                       } else if (TypeManager.IsGenericType (returnType)) {
                                if (TypeManager.IsDelegateType (returnType)) {
-                                       invoke = Delegate.GetInvokeMethod (ec.Compiler, returnType, returnType);
+                                       invoke = Delegate.GetInvokeMethod (ec.Compiler, returnType);
                                        return IsReturnTypeNonDependent (ec, invoke, invoke.ReturnType);
                                }
                                        
-                               Type[] g_args = returnType.GetGenericArguments ();
+                               TypeSpec[] g_args = TypeManager.GetTypeArguments (returnType);
                                
                                // At least one unfixed return type has to exist 
                                if (AllTypesAreFixed (g_args))
@@ -2793,12 +2660,12 @@ namespace Mono.CSharp {
                        return AllTypesAreFixed (d_parameters.Types);
                }
                
-               bool IsFixed (Type type)
+               bool IsFixed (TypeSpec type)
                {
                        return IsUnfixed (type) == -1;
                }               
 
-               int IsUnfixed (Type type)
+               int IsUnfixed (TypeSpec type)
                {
                        if (!type.IsGenericParameter)
                                return -1;
@@ -2815,7 +2682,7 @@ namespace Mono.CSharp {
                //
                // 26.3.3.9 Lower-bound Inference
                //
-               public int LowerBoundInference (Type u, Type v)
+               public int LowerBoundInference (TypeSpec u, TypeSpec v)
                {
                        return LowerBoundInference (u, v, false);
                }
@@ -2823,7 +2690,7 @@ namespace Mono.CSharp {
                //
                // Lower-bound (false) or Upper-bound (true) inference based on inversed argument
                //
-               int LowerBoundInference (Type u, Type v, bool inversed)
+               int LowerBoundInference (TypeSpec u, TypeSpec v, bool inversed)
                {
                        // If V is one of the unfixed type arguments
                        int pos = IsUnfixed (v);
@@ -2833,75 +2700,67 @@ namespace Mono.CSharp {
                        }                       
 
                        // If U is an array type
-                       if (u.IsArray) {
-                               int u_dim = u.GetArrayRank ();
-                               Type v_i;
-                               Type u_i = TypeManager.GetElementType (u);
-
-                               if (v.IsArray) {
-                                       if (u_dim != v.GetArrayRank ())
+                       var u_ac = u as ArrayContainer;
+                       if (u_ac != null) {
+                               var v_ac = v as ArrayContainer;
+                               if (v_ac != null) {
+                                       if (u_ac.Rank != v_ac.Rank)
                                                return 0;
 
-                                       v_i = TypeManager.GetElementType (v);
-
-                                       if (TypeManager.IsValueType (u_i))
-                                               return ExactInference (u_i, v_i);
+                                       if (TypeManager.IsValueType (u_ac.Element))
+                                               return ExactInference (u_ac.Element, v_ac.Element);
 
-                                       return LowerBoundInference (u_i, v_i, inversed);
+                                       return LowerBoundInference (u_ac.Element, v_ac.Element, inversed);
                                }
 
-                               if (u_dim != 1)
+                               if (u_ac.Rank != 1)
                                        return 0;
 
-                               if (v.IsGenericType) {
-                                       Type g_v = v.GetGenericTypeDefinition ();
-                                       if ((g_v != TypeManager.generic_ilist_type) && (g_v != TypeManager.generic_icollection_type) &&
-                                               (g_v != TypeManager.generic_ienumerable_type))
+                               if (TypeManager.IsGenericType (v)) {
+                                       TypeSpec g_v = v.GetDefinition ();
+                                       if (g_v != TypeManager.generic_ilist_type &&
+                                               g_v != TypeManager.generic_icollection_type &&
+                                               g_v != TypeManager.generic_ienumerable_type)
                                                return 0;
 
-                                       v_i = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (v) [0]);
-                                       if (TypeManager.IsValueType (u_i))
-                                               return ExactInference (u_i, v_i);
+                                       var v_i = TypeManager.GetTypeArguments (v) [0];
+                                       if (TypeManager.IsValueType (u_ac.Element))
+                                               return ExactInference (u_ac.Element, v_i);
 
-                                       return LowerBoundInference (u_i, v_i);
+                                       return LowerBoundInference (u_ac.Element, v_i);
                                }
-                       } else if (v.IsGenericType && !v.IsGenericTypeDefinition) {
+                       } else if (TypeManager.IsGenericType (v)) {
                                //
                                // if V is a constructed type C<V1..Vk> and there is a unique type C<U1..Uk>
                                // such that U is identical to, inherits from (directly or indirectly),
                                // or implements (directly or indirectly) C<U1..Uk>
                                //
-                               var u_candidates = new List<Type> ();
-                               if (u.IsGenericType)
-                                       u_candidates.Add (u);
+                               var u_candidates = new List<TypeSpec> ();
+                               var open_v = v.MemberDefinition;
 
-                               for (Type t = u.BaseType; t != null; t = t.BaseType) {
-                                       if (t.IsGenericType && !t.IsGenericTypeDefinition)
+                               for (TypeSpec t = u; t != null; t = t.BaseType) {
+                                       if (open_v == t.MemberDefinition)
                                                u_candidates.Add (t);
-                               }
-
-                               // TODO: Implement GetGenericInterfaces only and remove
-                               // the if from foreach
-                               u_candidates.AddRange (TypeManager.GetInterfaces (u));
 
-                               Type open_v = v.GetGenericTypeDefinition ();
-                               Type [] unique_candidate_targs = null;
-                               Type [] ga_v = v.GetGenericArguments ();                        
-                               foreach (Type u_candidate in u_candidates) {
-                                       if (!u_candidate.IsGenericType || u_candidate.IsGenericTypeDefinition)
-                                               continue;
-
-                                       if (TypeManager.DropGenericTypeArguments (u_candidate) != open_v)
-                                               continue;
+                                       if (t.Interfaces != null) {
+                                               foreach (var iface in t.Interfaces) {
+                                                       if (open_v == iface.MemberDefinition)
+                                                               u_candidates.Add (iface);
+                                               }
+                                       }
+                               }
 
+                               TypeSpec [] unique_candidate_targs = null;
+                               TypeSpec[] ga_v = TypeManager.GetTypeArguments (v);
+                               foreach (TypeSpec u_candidate in u_candidates) {
                                        //
                                        // The unique set of types U1..Uk means that if we have an interface I<T>,
                                        // class U : I<int>, I<long> then no type inference is made when inferring
                                        // type I<T> by applying type U because T could be int or long
                                        //
                                        if (unique_candidate_targs != null) {
-                                               Type[] second_unique_candidate_targs = u_candidate.GetGenericArguments ();
-                                               if (TypeManager.IsEqual (unique_candidate_targs, second_unique_candidate_targs)) {
+                                               TypeSpec[] second_unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate);
+                                               if (TypeSpecComparer.Default.Equals (unique_candidate_targs, second_unique_candidate_targs)) {
                                                        unique_candidate_targs = second_unique_candidate_targs;
                                                        continue;
                                                }
@@ -2913,16 +2772,16 @@ namespace Mono.CSharp {
                                                return 1;
                                        }
 
-                                       unique_candidate_targs = u_candidate.GetGenericArguments ();
+                                       unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate);
                                }
 
                                if (unique_candidate_targs != null) {
-                                       Type[] ga_open_v = open_v.GetGenericArguments ();
+                                       var ga_open_v = open_v.TypeParameters;
                                        int score = 0;
                                        for (int i = 0; i < unique_candidate_targs.Length; ++i) {
-                                               Variance variance = TypeManager.GetTypeParameterVariance (ga_open_v [i]);
+                                               Variance variance = ga_open_v [i].Variance;
 
-                                               Type u_i = unique_candidate_targs [i];
+                                               TypeSpec u_i = unique_candidate_targs [i];
                                                if (variance == Variance.None || TypeManager.IsValueType (u_i)) {
                                                        if (ExactInference (u_i, ga_v [i]) == 0)
                                                                ++score;
@@ -2944,25 +2803,20 @@ namespace Mono.CSharp {
                //
                // 26.3.3.6 Output Type Inference
                //
-               public int OutputTypeInference (ResolveContext ec, Expression e, Type t)
+               public int OutputTypeInference (ResolveContext ec, Expression e, TypeSpec t)
                {
                        // If e is a lambda or anonymous method with inferred return type
                        AnonymousMethodExpression ame = e as AnonymousMethodExpression;
                        if (ame != null) {
-                               Type rt = ame.InferReturnType (ec, this, t);
-                               var invoke = Delegate.GetInvokeMethod (ec.Compiler, t, t);
+                               TypeSpec rt = ame.InferReturnType (ec, this, t);
+                               var invoke = Delegate.GetInvokeMethod (ec.Compiler, t);
 
                                if (rt == null) {
                                        AParametersCollection pd = invoke.Parameters;
                                        return ame.Parameters.Count == pd.Count ? 1 : 0;
                                }
 
-                               Type rtype = invoke.ReturnType;
-#if MS_COMPATIBLE
-                               // Blablabla, because reflection does not work with dynamic types
-//                             Type [] g_args = t.GetGenericArguments ();
-//                             rtype = g_args [rtype.GenericParameterPosition];
-#endif
+                               TypeSpec rtype = invoke.ReturnType;
                                return LowerBoundInference (rt, rtype) + 1;
                        }
 
@@ -2977,13 +2831,8 @@ namespace Mono.CSharp {
                                if (!TypeManager.IsDelegateType (t))
                                        return 0;
 
-                               var invoke = Delegate.GetInvokeMethod (ec.Compiler, t, t);
-                               Type rtype = invoke.ReturnType;
-#if MS_COMPATIBLE
-                               // Blablabla, because reflection does not work with dynamic types
-//                             Type [] g_args = t.GetGenericArguments ();
-//                             rtype = g_args [rtype.GenericParameterPosition];
-#endif
+                               var invoke = Delegate.GetInvokeMethod (ec.Compiler, t);
+                               TypeSpec rtype = invoke.ReturnType;
 
                                if (!TypeManager.IsGenericType (rtype))
                                        return 0;
@@ -3006,7 +2855,7 @@ namespace Mono.CSharp {
                        return LowerBoundInference (e.Type, t) * 2;
                }
 
-               void RemoveDependentTypes (List<Type> types, Type returnType)
+               void RemoveDependentTypes (List<TypeSpec> types, TypeSpec returnType)
                {
                        int idx = IsUnfixed (returnType);
                        if (idx >= 0) {
@@ -3014,8 +2863,8 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (returnType.IsGenericType) {
-                               foreach (Type t in returnType.GetGenericArguments ()) {
+                       if (TypeManager.IsGenericType (returnType)) {
+                               foreach (TypeSpec t in TypeManager.GetTypeArguments (returnType)) {
                                        RemoveDependentTypes (types, t);
                                }
                        }
@@ -3026,7 +2875,7 @@ namespace Mono.CSharp {
                                if (unfixed_types == null)
                                        return false;
 
-                               foreach (Type ut in unfixed_types)
+                               foreach (TypeSpec ut in unfixed_types)
                                        if (ut != null)
                                                return true;
                                return false;
index 8c74402d8d59496a2ddb8104bab8216bc25aaf14..2a02515b3ac3a89abeadcfd3adcc22cee4e1b612 100644 (file)
@@ -12,22 +12,63 @@ using System;
 using System.Reflection;
 using System.Runtime.CompilerServices;
 using System.Linq;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
 
 namespace Mono.CSharp
 {
-       static class Import
+       public static class Import
        {
-               public static FieldSpec CreateField (FieldInfo fi)
+               static Dictionary<Type, TypeSpec> import_cache;
+               static Dictionary<Type, PredefinedTypeSpec> type_2_predefined;
+
+               public static void Initialize ()
                {
-                       // TODO MemberCache: remove
-                       var cs = TypeManager.GetConstant (fi);
-                       if (cs != null)
-                               return cs;
-                       var fb = TypeManager.GetFieldCore (fi);
-                       if (fb != null)
-                               return fb.Spec;
-                       // End
+                       import_cache = new Dictionary<Type, TypeSpec> (1024, ReferenceEquality<Type>.Default);
+
+                       // Setup mapping for predefined types
+                       type_2_predefined = new Dictionary<Type, PredefinedTypeSpec> () {
+                               { typeof (object), TypeManager.object_type },
+                               { typeof (System.ValueType), TypeManager.value_type },
+                               { typeof (System.Attribute), TypeManager.attribute_type },
+
+                               { typeof (int), TypeManager.int32_type },
+                               { typeof (long), TypeManager.int64_type },
+                               { typeof (uint), TypeManager.uint32_type },
+                               { typeof (ulong), TypeManager.uint64_type },
+                               { typeof (byte), TypeManager.byte_type },
+                               { typeof (sbyte), TypeManager.sbyte_type },
+                               { typeof (short), TypeManager.short_type },
+                               { typeof (ushort), TypeManager.ushort_type },
+
+                               { typeof (System.Collections.IEnumerator), TypeManager.ienumerator_type },
+                               { typeof (System.Collections.IEnumerable), TypeManager.ienumerable_type },
+                               { typeof (System.IDisposable), TypeManager.idisposable_type },
+
+                               { typeof (char), TypeManager.char_type },
+                               { typeof (string), TypeManager.string_type },
+                               { typeof (float), TypeManager.float_type },
+                               { typeof (double), TypeManager.double_type },
+                               { typeof (decimal), TypeManager.decimal_type },
+                               { typeof (bool), TypeManager.bool_type },
+                               { typeof (System.IntPtr), TypeManager.intptr_type },
+                               { typeof (System.UIntPtr), TypeManager.uintptr_type },
+
+                               { typeof (System.MulticastDelegate), TypeManager.multicast_delegate_type },
+                               { typeof (System.Delegate), TypeManager.delegate_type },
+                               { typeof (System.Enum), TypeManager.enum_type },
+                               { typeof (System.Array), TypeManager.array_type },
+                               { typeof (void), TypeManager.void_type },
+                               { typeof (System.Type), TypeManager.type_type },
+                               { typeof (System.Exception), TypeManager.exception_type },
+                               { typeof (System.RuntimeFieldHandle), TypeManager.runtime_field_handle_type },
+                               { typeof (System.RuntimeTypeHandle), TypeManager.runtime_handle_type }
+                       };
+               }
 
+               public static FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType)
+               {
                        Modifiers mod = 0;
                        var fa = fi.Attributes;
                        switch (fa & FieldAttributes.FieldAccessMask) {
@@ -48,37 +89,18 @@ namespace Mono.CSharp
                                        break;
                        }
 
-                       // TODO MemberCache: Remove completely and use only Imported
-                       IMemberDefinition definition;
-                       var gfd = TypeManager.GetGenericFieldDefinition (fi);
-                       fb = TypeManager.GetFieldCore (gfd);
-                       if (fb != null) {
-                               definition = fb;
-                       } else {
-                               cs = TypeManager.GetConstant (gfd);
-                               if (cs != null)
-                                       definition = cs.MemberDefinition;
-                               else
-                                       definition = new ImportedMemberDefinition (fi);
-                       }
+                       var definition = new ImportedMemberDefinition (fi);
 
                        if ((fa & FieldAttributes.Literal) != 0) {
-                               Expression c;
-                               if (gfd is System.Reflection.Emit.FieldBuilder) {
-                                       // TODO: Remove after MemberCache
-                                       c = TypeManager.GetConstant (gfd).Value;
-                               } else {
-                                       c = Constant.CreateConstantFromValue (fi.FieldType, gfd.GetValue (gfd), Location.Null);
-                               }
-
-                               return new ConstSpec (definition, fi, mod, c);
+                               var     c = Constant.CreateConstantFromValue (ImportType (fi.FieldType), fi.GetValue (fi), Location.Null);
+                               return new ConstSpec (declaringType, definition, ImportType (fi.FieldType), fi, mod, c);
                        }
 
                        if ((fa & FieldAttributes.InitOnly) != 0) {
-                               if (fi.FieldType == TypeManager.decimal_type) {
-                                       var dc = ReadDecimalConstant (gfd);
+                               if (fi.FieldType == typeof (decimal)) {
+                                       var dc = ReadDecimalConstant (fi);
                                        if (dc != null)
-                                               return new ConstSpec (definition, fi, mod, dc);
+                                               return new ConstSpec (declaringType, definition, ImportType (fi.FieldType), fi, mod, dc);
                                }
 
                                mod |= Modifiers.READONLY;
@@ -87,94 +109,109 @@ namespace Mono.CSharp
                        if ((fa & FieldAttributes.Static) != 0)
                                mod |= Modifiers.STATIC;
 
-                       if (!TypeManager.IsReferenceType (fi.FieldType)) {
-                               PredefinedAttribute pa = PredefinedAttributes.Get.FixedBuffer;
-                               if (pa.IsDefined) {
-                                       if (gfd is System.Reflection.Emit.FieldBuilder) {
-                                                // TODO: Remove this after MemberCache fix
-                                       } else if (gfd.IsDefined (pa.Type, false)) {
-                                               var element_field = fi.FieldType.GetField (FixedField.FixedElementName);
-                                               return new FixedFieldSpec (definition, fi, element_field, mod);
-                                       }
+                       if (fi.FieldType.IsValueType) {
+                                if (fi.IsDefined (typeof (FixedBufferAttribute), false)) {
+                                       var element_field = CreateField (fi.FieldType.GetField (FixedField.FixedElementName), declaringType);
+                                       return new FixedFieldSpec (declaringType, definition, fi, element_field, mod);
                                }
                        }
 
-                       // TODO: volatile
+                       // TODO: import volatile
 
-                       return new FieldSpec (definition, fi, mod);
+                       return new FieldSpec (declaringType, definition, ImportType (fi.FieldType), fi, mod);
                }
 
-               public static EventSpec CreateEvent (EventInfo ei)
+               public static EventSpec CreateEvent (EventInfo ei, TypeSpec declaringType, MethodSpec add, MethodSpec remove)
                {
-                       // TODO MemberCache: Remove
-                       var ef = TypeManager.GetEventField (ei);
-                       if (ef != null)
-                               return ef;
+                       add.IsAccessor = true;
+                       remove.IsAccessor = true;
 
-                       var add_accessor = CreateMethod (TypeManager.GetAddMethod (ei));
-                       var remove_accessor = CreateMethod (TypeManager.GetRemoveMethod (ei));
-
-                       if (add_accessor.Modifiers != remove_accessor.Modifiers)
+                       if (add.Modifiers != remove.Modifiers)
                                throw new NotImplementedException ("Different accessor modifiers " + ei.Name);
 
                        var definition = new ImportedMemberDefinition (ei);
-                       return new EventSpec (definition, ei, add_accessor.Modifiers, add_accessor, remove_accessor) {
-                               EventType = ei.EventHandlerType
-                       };
+                       return new EventSpec (declaringType, definition, ImportType (ei.EventHandlerType), add.Modifiers, add, remove);
                }
 
-               public static MethodSpec CreateMethod (MethodBase mb)
+               static T[] CreateGenericParameters<T> (Type type, TypeSpec declaringType) where T : TypeSpec
                {
-                       // TODO MemberCache: Remove
-                       MethodCore mc = TypeManager.GetMethod (mb) as MethodCore;
-                       if (mc != null)
-                               return mc.Spec;
+                       Type[] tparams = type.GetGenericArguments ();
 
-                       Modifiers mod = 0;
-                       var ma = mb.Attributes;
-                       switch (ma & MethodAttributes.MemberAccessMask) {
-                               case MethodAttributes.Public:
-                                       mod = Modifiers.PUBLIC;
-                                       break;
-                               case MethodAttributes.Assembly:
-                                       mod = Modifiers.INTERNAL;
-                                       break;
-                               case MethodAttributes.Family:
-                                       mod = Modifiers.PROTECTED;
-                                       break;
-                               case MethodAttributes.FamORAssem:
-                                       mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
-                                       break;
-                               default:
-                                       mod = Modifiers.PRIVATE;
-                                       break;
-                       }
+                       int parent_owned_count;
+                       if (type.IsNested) {
+                               parent_owned_count = type.DeclaringType.GetGenericArguments ().Length;
 
-                       if ((ma & MethodAttributes.Static) != 0)
-                               mod |= Modifiers.STATIC;
-                       if ((ma & MethodAttributes.Virtual) != 0)
-                               mod |= Modifiers.VIRTUAL;
-                       if ((ma & MethodAttributes.Abstract) != 0)
-                               mod |= Modifiers.ABSTRACT;
-                       if ((ma & MethodAttributes.Final) != 0)
-                               mod |= Modifiers.SEALED;
+                               //
+                               // System.Reflection duplicates parent type parameters for each
+                               // nested type with slightly modified properties (eg. different owner)
+                               // This just makes things more complicated (think of cloned constraints)
+                               // therefore we remap any nested type owned by parent using `type_cache'
+                               // to the single TypeParameterSpec
+                               //
+                               if (declaringType != null && parent_owned_count > 0) {
+                                       int read_count = 0;
+                                       while (read_count != parent_owned_count) {
+                                               var tparams_count = declaringType.Arity;
+                                               if (tparams_count != 0) {
+                                                       var parent_tp = declaringType.MemberDefinition.TypeParameters;
+                                                       read_count += tparams_count;
+                                                       for (int i = 0; i < tparams_count; i++) {
+                                                               import_cache.Add (tparams[parent_owned_count - read_count + i], parent_tp[i]);
+                                                       }
+                                               }
 
-                       IMemberDefinition definition;
-                       var gmd = mb as MethodInfo;
-                       if (gmd != null && gmd.IsGenericMethodDefinition) {
-                               definition = new ImportedGenericMethodDefinition (gmd);
-                       } else if (mb.IsGenericMethod) {        // TODO MemberCache: Remove me
-                               definition = new ImportedGenericMethodDefinition ((MethodInfo) TypeManager.DropGenericMethodArguments (mb));
+                                               declaringType = declaringType.DeclaringType;
+                                       }
+                               }                       
                        } else {
-                               definition = new ImportedMemberDefinition (mb);
+                               parent_owned_count = 0;
                        }
 
-                       // TODO MemberCache: Use AParametersCollection p = ParametersImported.Create (mb);
-                       AParametersCollection p = TypeManager.GetParameterData (mb);
+                       if (tparams.Length - parent_owned_count == 0)
+                               return null;
+
+                       return CreateGenericParameters<T> (parent_owned_count, tparams);
+               }
+
+               static T[] CreateGenericParameters<T> (int first, Type[] tparams) where T : TypeSpec
+               {
+                       var tspec = new T [tparams.Length - first];
+                       for (int pos = first; pos < tparams.Length; ++pos) {
+                               tspec [pos - first] = (T) CreateType (tparams [pos]);
+                       }
+
+                       return tspec;
+               }
+
+               public static MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType)
+               {
+                       Modifiers mod = ReadMethodModifiers (mb, declaringType);
+                       //if (declaringType.IsInterface) {
+                       //    mod = (mod & ~Modifiers.ABSTRACT) | Modifiers.VIRTUAL;
+                       //}
+
+                       bool is_generic;
+                       ImportedMethodDefinition definition;
+
+                       var parameters = ParametersImported.Create (declaringType, mb);
+
+                       if (mb.IsGenericMethod) {
+                               if (!mb.IsGenericMethodDefinition)
+                                       throw new NotSupportedException ("assert");
+
+                               var tparams = CreateGenericParameters<TypeParameterSpec>(0, mb.GetGenericArguments ());
+                               definition = new ImportedGenericMethodDefinition ((MethodInfo) mb, parameters, tparams);
+                               is_generic = true;
+                       } else {
+                               definition = new ImportedMethodDefinition (mb, parameters);
+                               is_generic = false;
+                       }
 
                        MemberKind kind;
-                       if (mb.IsConstructor) {
+                       TypeSpec returnType;
+                       if (mb.MemberType == MemberTypes.Constructor) {
                                kind = MemberKind.Constructor;
+                               returnType = TypeManager.void_type;
                        } else {
                                //
                                // Detect operators and destructors
@@ -182,85 +219,362 @@ namespace Mono.CSharp
                                string name = mb.Name;
                                kind = MemberKind.Method;
                                if (!mb.DeclaringType.IsInterface && name.Length > 6) {
-                                       if ((mod & Modifiers.STATIC) != 0 && name[2] == '_' && name[1] == 'p' && name[0] == 'o') {
-                                               var op_type = Operator.GetType (name);
-                                               if (op_type.HasValue) {
-                                                       kind = MemberKind.Operator;
+                                       if ((mod & (Modifiers.STATIC | Modifiers.PUBLIC)) == (Modifiers.STATIC | Modifiers.PUBLIC)) {
+                                               if (name[2] == '_' && name[1] == 'p' && name[0] == 'o') {
+                                                       var op_type = Operator.GetType (name);
+                                                       if (op_type.HasValue) {
+                                                               kind = MemberKind.Operator;
+                                                       }
                                                }
-                                       } else if (p.IsEmpty && (mod & Modifiers.STATIC) == 0 && name == Destructor.MetadataName) {
+                                       } else if (parameters.IsEmpty && name == Destructor.MetadataName) {
                                                kind = MemberKind.Destructor;
                                        }
                                }
+
+                               returnType = ImportType (((MethodInfo)mb).ReturnType);
                        }
-                               
-                       MethodSpec ms = new MethodSpec (kind, definition, mb, p, mod);
+
+                       MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod);
+                       if (is_generic)
+                               ms.IsGeneric = true;
+
                        return ms;
                }
 
-               public static PropertySpec CreateProperty (PropertyInfo pi)
+               //
+               // Returns null when the property is not valid C# property
+               //
+               public static PropertySpec CreateProperty (PropertyInfo pi, TypeSpec declaringType, MethodSpec get, MethodSpec set)
                {
                        var definition = new ImportedMemberDefinition (pi);
-                       var mod = Modifiers.PRIVATE;    // TODO: modifiers
-                       return new PropertySpec (MemberKind.Property | MemberKind.Indexer, definition, pi, mod);
+
+                       Modifiers mod = 0;
+                       AParametersCollection param = null;
+                       TypeSpec type = null;
+                       if (get != null) {
+                               mod = get.Modifiers;
+                               param = get.Parameters;
+                               type = get.ReturnType;
+                       }
+
+                       bool is_valid_property = true;
+                       if (set != null) {
+                               if (set.ReturnType != TypeManager.void_type)
+                                       is_valid_property = false;
+
+                               var set_param_count = set.Parameters.Count - 1;
+                               if (set_param_count < 0)
+                                       is_valid_property = false;
+
+                               var data = new IParameterData [set_param_count];
+                               var types = new TypeSpec[set_param_count];
+                               for (int i = 0; i < set_param_count; ++i ) {
+                                       data[i] = set.Parameters.FixedParameters[i];
+                                       types[i] = set.Parameters.Types[i];
+                               }
+
+                               var set_param = new ParametersImported (data, types);
+                               var set_type = set.Parameters.Types[set_param_count];
+
+                               if (mod == 0) {
+                                       mod = set.Modifiers;
+                                       param = set_param;
+                                       type = set_type;
+                               } else {
+                                       if (set_param_count != get.Parameters.Count)
+                                               is_valid_property = false;
+
+                                       if (get.ReturnType != set_type)
+                                               is_valid_property = false;
+
+                                       // Possible custom accessor modifiers
+                                       if ((mod & ~Modifiers.AccessibilityMask) != (set.Modifiers & ~Modifiers.AccessibilityMask)) {
+                                               var get_acc = mod & Modifiers.AccessibilityMask;
+                                               if (get_acc != Modifiers.PUBLIC) {
+                                                       var set_acc = set.Modifiers & Modifiers.AccessibilityMask;
+                                                       // If the accessor modifiers are not same, do extra restriction checks
+                                                       if (get_acc != set_acc) {
+                                                               var get_restr = ModifiersExtensions.IsRestrictedModifier (get_acc, set_acc);
+                                                               var set_restr = ModifiersExtensions.IsRestrictedModifier (set_acc, get_acc);
+                                                               if (get_restr && set_restr) {
+                                                                       is_valid_property = false; // Neither is more restrictive
+                                                               }
+
+                                                               if (set_restr) {
+                                                                       mod &= ~Modifiers.AccessibilityMask;
+                                                                       mod |= set_acc;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       PropertySpec spec = null;
+                       if (!param.IsEmpty) {
+                               var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember ();
+                               if (index_name == null) {
+                                       is_valid_property = false;
+                               } else {
+                                       if (get != null) {
+                                               if (get.IsStatic)
+                                                       is_valid_property = false;
+                                               if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
+                                                       is_valid_property = false;
+                                       }
+                                       if (set != null) {
+                                               if (set.IsStatic)
+                                                       is_valid_property = false;
+                                               if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
+                                                       is_valid_property = false;
+                                       }
+                               }
+
+                               if (is_valid_property)
+                                       spec = new IndexerSpec (declaringType, definition, type, param, pi, mod);
+                       }
+
+                       if (spec == null)
+                               spec = new PropertySpec (MemberKind.Property, declaringType, definition, type, pi, mod);
+
+                       if (!is_valid_property) {
+                               spec.IsNotRealProperty = true;
+                               return spec;
+                       }
+
+                       if (set != null)
+                               spec.Set = set;
+                       if (get != null)
+                               spec.Get = get;
+
+                       return spec;
                }
 
-               static TypeSpec CreateType (Type type)
+               public static TypeSpec CreateType (Type type)
                {
-                       Modifiers mod = 0;
+                       return CreateType (type, null);
+               }
+
+               public static TypeSpec CreateType (Type type, TypeSpec declaringType)
+               {
+                       TypeSpec spec;
+                       if (import_cache.TryGetValue (type, out spec))
+                               return spec;
+
+                       if (type.IsGenericType && !type.IsGenericTypeDefinition) {      
+                               var type_def = type.GetGenericTypeDefinition ();
+                               spec = CreateType (type_def, declaringType);
+
+                               var targs = CreateGenericParameters<TypeSpec> (type, null);
+
+                               InflatedTypeSpec inflated;
+                               if (targs == null) {
+                                       // Inflating nested non-generic type, same in TypeSpec::InflateMember
+                                       inflated = new InflatedTypeSpec (spec, declaringType, TypeSpec.EmptyTypes);
+                               } else {
+                                       // CreateGenericParameters constraint could inflate type
+                                       if (import_cache.ContainsKey (type))
+                                               return import_cache[type];
+
+                                       inflated = spec.MakeGenericType (targs);
+
+                                       // Use of reading cache to speed up reading only
+                                       import_cache.Add (type, inflated);
+                               }
+
+                               return inflated;
+                       }
+
+                       Modifiers mod;
+                       MemberKind kind;
+
                        var ma = type.Attributes;
                        switch (ma & TypeAttributes.VisibilityMask) {
-                               case TypeAttributes.Public:
-                               case TypeAttributes.NestedPublic:
-                                       mod = Modifiers.PUBLIC;
-                                       break;
-                case TypeAttributes.NestedPrivate:
-                                       mod = Modifiers.PRIVATE;
-                                       break;
-                               case TypeAttributes.NestedFamily:
-                                       mod = Modifiers.PROTECTED;
-                                       break;
-                               case TypeAttributes.NestedFamORAssem:
-                                       mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
-                                       break;
-                               default:
-                                       mod = Modifiers.INTERNAL;
-                                       break;
+                       case TypeAttributes.Public:
+                       case TypeAttributes.NestedPublic:
+                               mod = Modifiers.PUBLIC;
+                               break;
+                       case TypeAttributes.NestedPrivate:
+                               mod = Modifiers.PRIVATE;
+                               break;
+                       case TypeAttributes.NestedFamily:
+                               mod = Modifiers.PROTECTED;
+                               break;
+                       case TypeAttributes.NestedFamORAssem:
+                               mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
+                               break;
+                       default:
+                               mod = Modifiers.INTERNAL;
+                               break;
                        }
 
-                       var type_def = TypeManager.DropGenericTypeArguments (type);
-
-                       MemberKind kind;
-                       if (type_def.IsInterface)
+                       if ((ma & TypeAttributes.Interface) != 0) {
                                kind = MemberKind.Interface;
-                       else if (type_def.IsEnum)
-                               kind = MemberKind.Enum;
-                       else if (type_def.IsClass) {
-                               if (type_def.BaseType == TypeManager.multicast_delegate_type)
+                       } else if (type.IsGenericParameter) {
+                               kind = MemberKind.TypeParameter;
+                       } else if (type.IsClass || type.IsAbstract) {                           // SRE: System.Enum returns false for IsClass
+                               if ((ma & TypeAttributes.Sealed) != 0 && type.IsSubclassOf (typeof (MulticastDelegate))) {
                                        kind = MemberKind.Delegate;
-                               else
+                               } else {
                                        kind = MemberKind.Class;
+
+                                       if (type == typeof (object)) {
+#if NET_4_0
+                                               var pa = PredefinedAttributes.Get.Dynamic.Type;
+                                               if (pa != null && type.IsDefined (typeof (DynamicAttribute), false))
+                                                       return InternalType.Dynamic;
+#endif
+                                       }
+
+                                       if ((ma & TypeAttributes.Sealed) != 0) {
+                                               mod |= Modifiers.SEALED;
+                                               if ((ma & TypeAttributes.Abstract) != 0)
+                                                       mod |= Modifiers.STATIC;
+                                       } else if ((ma & TypeAttributes.Abstract) != 0) {
+                                               mod |= Modifiers.ABSTRACT;
+                                       }
+                               }
+                       } else if (type.IsEnum) {
+                               kind = MemberKind.Enum;
                        } else {
                                kind = MemberKind.Struct;
+                               mod |= Modifiers.SEALED;
                        }
 
-                       if (type.IsGenericType) {
-                               throw new NotImplementedException ();
+                       var definition = new ImportedTypeDefinition (type);
+                       PredefinedTypeSpec pt;
+
+                       if (kind == MemberKind.Enum) {
+                               const BindingFlags any_member = BindingFlags.DeclaredOnly |
+                                       BindingFlags.Static | BindingFlags.Instance |
+                                       BindingFlags.Public | BindingFlags.NonPublic;
+
+                               var u_type = type.GetField (Enum.UnderlyingValueField, any_member);
+                               if (u_type != null) {
+                                       spec = new EnumSpec (declaringType, definition, Import.CreateType (u_type.FieldType), type, mod);
+                               }
+                       } else if (kind == MemberKind.TypeParameter) {
+                               // Return as type_cache was updated
+                               return CreateTypeParameter (type, declaringType);
+                       } else if (type.IsGenericTypeDefinition) {
+                               definition.TypeParameters = CreateGenericParameters<TypeParameterSpec>(type, declaringType);
+
+                               // Constraints are not loaded on demand and can reference this type
+                               if (import_cache.TryGetValue (type, out spec))
+                                       return spec;
+
+                       } else if (type_2_predefined.TryGetValue (type, out pt)) {
+                               spec = pt;
+                               pt.SetDefinition (definition, type);
                        }
 
-                       var definition = new ImportedTypeDefinition (type_def);
-                       var spec = new TypeSpec (kind, definition, type, type.Name, mod);
+                       if (spec == null)
+                               spec = new TypeSpec (kind, declaringType, definition, type, mod);
+
+                       import_cache.Add (type, spec);
 
-                       // TODO: BaseType for class only?
+                       if (kind == MemberKind.Interface)
+                               spec.BaseType = TypeManager.object_type;
+                       else if (type.BaseType != null)
+                               spec.BaseType = CreateType (type.BaseType);
+
+                       var ifaces = type.GetInterfaces ();
+                       if (ifaces.Length > 0) {
+                               foreach (Type iface in ifaces) {
+                                       spec.AddInterface (Import.CreateType (iface));
+                               }
+                       }
+
+                       return spec;
+               }
+
+               static TypeParameterSpec CreateTypeParameter (Type type, TypeSpec declaringType)
+               {
+                       Variance variance;
+                       switch (type.GenericParameterAttributes & GenericParameterAttributes.VarianceMask) {
+                       case GenericParameterAttributes.Covariant:
+                               variance = Variance.Covariant;
+                               break;
+                       case GenericParameterAttributes.Contravariant:
+                               variance = Variance.Contravariant;
+                               break;
+                       default:
+                               variance = Variance.None;
+                               break;
+                       }
+
+                       SpecialConstraint special = SpecialConstraint.None;
+                       var import_special = type.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
+
+                       if ((import_special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) {
+                               special |= SpecialConstraint.Struct;
+                       } else if ((import_special & GenericParameterAttributes.DefaultConstructorConstraint) != 0) {
+                               special = SpecialConstraint.Constructor;
+                       }
+
+                       if ((import_special & GenericParameterAttributes.ReferenceTypeConstraint) != 0) {
+                               special |= SpecialConstraint.Class;
+                       }
+
+                       TypeParameterSpec spec;
+                       var def = new ImportedTypeParameterDefinition (type);
+                       if (type.DeclaringMethod != null)
+                               spec = new TypeParameterSpec (type.GenericParameterPosition, def, special, variance, type);
+                       else
+                               spec = new TypeParameterSpec (declaringType, type.GenericParameterPosition, def, special, variance, type);
+
+                       // Add it now, so any constraint can reference it and get same instance
+                       import_cache.Add (type, spec);
+
+                       var constraints = type.GetGenericParameterConstraints ();
+                       foreach (var ct in constraints) {
+                               // TODO MemberCache: What to do ??
+                               if (ct.IsGenericParameter) {
+                                       continue;
+                               }
+
+                               if (ct.IsClass) {
+                                       if (ct == typeof (ValueType)) {
+                                               spec.BaseType = TypeManager.value_type;
+                                       } else {
+                                               spec.BaseType = CreateType (ct);
+                                       }
+
+                                       continue;
+                               }
+
+                               spec.AddInterface (CreateType (ct));
+                       }
+
+                       if (spec.BaseType == null)
+                               spec.BaseType = TypeManager.object_type;
 
                        return spec;
                }
 
                public static TypeSpec ImportType (Type type)
                {
-                       if (type.IsDefined (typeof (CompilerGeneratedAttribute), false))
-                               return null;
+                       if (type.HasElementType) {
+                               var element = type.GetElementType ();
+                               var spec = ImportType (element);
+
+                               if (type.IsArray)
+                                       return ArrayContainer.MakeType (spec, type.GetArrayRank ());
+                               if (type.IsByRef)
+                                       return ReferenceContainer.MakeType (spec);
+                               if (type.IsPointer)
+                                       return PointerContainer.MakeType (spec);
+
+                               throw new NotImplementedException ("Unknown element type " + type.ToString ());
+                       }
+
+                       TypeSpec dtype;
+                       if (type.IsNested)
+                               dtype = ImportType (type.DeclaringType);
+                       else
+                               dtype = null;
 
-                       return CreateType (type);
+                       return CreateType (type, dtype);
                }
 
                //
@@ -270,34 +584,211 @@ namespace Mono.CSharp
                //
                static Constant ReadDecimalConstant (FieldInfo fi)
                {
-                       PredefinedAttribute pa = PredefinedAttributes.Get.DecimalConstant;
-                       if (!pa.IsDefined)
-                               return null;
-
-                       object[] attrs = fi.GetCustomAttributes (pa.Type, false);
+                       object[] attrs = fi.GetCustomAttributes (typeof (DecimalConstantAttribute), false);
                        if (attrs.Length != 1)
                                return null;
 
                        return new DecimalConstant (((DecimalConstantAttribute) attrs [0]).Value, Location.Null);
                }
+
+               static Modifiers ReadMethodModifiers (MethodBase mb, TypeSpec declaringType)
+               {
+                       Modifiers mod;
+                       var ma = mb.Attributes;
+                       switch (ma & MethodAttributes.MemberAccessMask) {
+                       case MethodAttributes.Public:
+                               mod = Modifiers.PUBLIC;
+                               break;
+                       case MethodAttributes.Assembly:
+                               mod = Modifiers.INTERNAL;
+                               break;
+                       case MethodAttributes.Family:
+                               mod = Modifiers.PROTECTED;
+                               break;
+                       case MethodAttributes.FamORAssem:
+                               mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
+                               break;
+                       default:
+                               mod = Modifiers.PRIVATE;
+                               break;
+                       }
+
+                       if ((ma & MethodAttributes.Static) != 0) {
+                               mod |= Modifiers.STATIC;
+                       } else if ((ma & MethodAttributes.Final) != 0) {
+                               mod |= Modifiers.SEALED;
+                       } else if ((ma & MethodAttributes.Abstract) != 0 && declaringType.IsClass) {
+                               mod |= Modifiers.ABSTRACT;
+                       }
+
+                       // It can be sealed and override
+                       if ((ma & MethodAttributes.Virtual) != 0) {
+                               if ((ma & MethodAttributes.NewSlot) != 0 || !declaringType.IsClass || mod == Modifiers.PRIVATE) {
+                                       mod |= Modifiers.VIRTUAL;
+                               } else {
+                                       // Cannot set to OVERRIDE without full hierarchy checks
+                                       // this flag indicates that the method could be override
+                                       // but further validation is needed
+                                       mod |= Modifiers.OVERRIDE_UNCHECKED;
+                               }
+                       }
+
+                       return mod;
+               }
        }
 
        class ImportedMemberDefinition : IMemberDefinition
        {
-               protected readonly ICustomAttributeProvider provider;
+               protected class AttributesBag
+               {
+                       public static readonly AttributesBag Default = new AttributesBag ();
+
+                       public AttributeUsageAttribute AttributeUsage;
+                       public ObsoleteAttribute Obsolete;
+                       public string[] Conditionals;
+                       public string DefaultIndexerName;
+                       public bool IsNotCLSCompliant;
+
+                       public static AttributesBag Read (MemberInfo mi)
+                       {
+                               AttributesBag bag = null;
+                               List<string> conditionals = null;
+
+                               var attrs = CustomAttributeData.GetCustomAttributes (mi);
+                               foreach (var a in attrs) {
+                                       var type = a.Constructor.DeclaringType;
+                                       if (type == typeof (ObsoleteAttribute)) {
+                                               if (bag == null)
+                                                       bag = new AttributesBag ();
+
+                                               var args = a.ConstructorArguments;
+
+                                               if (args.Count == 1) {
+                                                       bag.Obsolete = new ObsoleteAttribute ((string) args[0].Value);
+                                               } else if (args.Count == 2) {
+                                                       bag.Obsolete = new ObsoleteAttribute ((string) args[0].Value, (bool) args[1].Value);
+                                               } else {
+                                                       bag.Obsolete = new ObsoleteAttribute ();
+                                               }
+
+                                               continue;
+                                       }
+
+                                       if (type == typeof (ConditionalAttribute)) {
+                                               if (bag == null)
+                                                       bag = new AttributesBag ();
+
+                                               if (conditionals == null)
+                                                       conditionals = new List<string> (2);
+
+                                               conditionals.Add ((string) a.ConstructorArguments[0].Value);
+                                               continue;
+                                       }
+
+                                       if (type == typeof (CLSCompliantAttribute)) {
+                                               if (bag == null)
+                                                       bag = new AttributesBag ();
+
+                                               bag.IsNotCLSCompliant = !(bool) a.ConstructorArguments[0].Value;
+                                               continue;
+                                       }
+
+                                       // Type only attributes
+                                       if (type == typeof (DefaultMemberAttribute)) {
+                                               if (bag == null)
+                                                       bag = new AttributesBag ();
+
+                                               bag.DefaultIndexerName = (string) a.ConstructorArguments[0].Value;
+                                               continue;
+                                       }
+
+                                       if (type == typeof (AttributeUsageAttribute)) {
+                                               if (bag == null)
+                                                       bag = new AttributesBag ();
+
+                                               bag.AttributeUsage = new AttributeUsageAttribute ((AttributeTargets) a.ConstructorArguments[0].Value);
+                                               foreach (var named in a.NamedArguments) {
+                                                       if (named.MemberInfo.Name == "AllowMultiple")
+                                                               bag.AttributeUsage.AllowMultiple = (bool) named.TypedValue.Value;
+                                                       else if (named.MemberInfo.Name == "Inherited")
+                                                               bag.AttributeUsage.Inherited = (bool) named.TypedValue.Value;
+                                               }
+                                               continue;
+                                       }
+                               }
+
+                               if (bag == null)
+                                       return Default;
+
+                               if (conditionals != null)
+                                       bag.Conditionals = conditionals.ToArray ();
+
+                               return bag;
+                       }
+               }
+
+               protected readonly MemberInfo provider;
+               protected AttributesBag cattrs;
 
-               public ImportedMemberDefinition (ICustomAttributeProvider provider)
+               public ImportedMemberDefinition (MemberInfo provider)
                {
                        this.provider = provider;
                }
 
-               public ObsoleteAttribute GetObsoleteAttribute ()
+               #region Properties
+
+               public Assembly Assembly {
+                       get { 
+                               return provider.Module.Assembly;
+                       }
+               }
+
+               public bool IsImported {
+                       get {
+                               return true;
+                       }
+               }
+
+               public virtual string Name {
+                       get {
+                               return provider.Name;
+                       }
+               }
+
+               #endregion
+
+               public string[] ConditionalConditions ()
                {
-                       var res = provider.GetCustomAttributes (typeof (ObsoleteAttribute), false);
-                       if (res == null || res.Length < 1)
-                               return null;
+                       if (cattrs == null)
+                               ReadAttributes ();
 
-                       return res [0] as ObsoleteAttribute;
+                       return cattrs.Conditionals;
+               }
+
+               public ObsoleteAttribute GetAttributeObsolete ()
+               {
+                       if (cattrs == null)
+                               ReadAttributes ();
+
+                       return cattrs.Obsolete;
+               }
+
+               public bool IsNotCLSCompliant ()
+               {
+                       if (cattrs == null)
+                               ReadAttributes ();
+
+                       return cattrs.IsNotCLSCompliant;
+               }
+
+               protected void ReadAttributes ()
+               {
+                       cattrs = AttributesBag.Read (provider);
+               }
+
+               public void SetIsAssigned ()
+               {
+                       // Unused for imported members
                }
 
                public void SetIsUsed ()
@@ -306,27 +797,322 @@ namespace Mono.CSharp
                }
        }
 
-       class ImportedGenericMethodDefinition : ImportedMemberDefinition, IGenericMethodDefinition
+       class ImportedMethodDefinition : ImportedMemberDefinition, IParametersMember
        {
-               public ImportedGenericMethodDefinition (MethodInfo provider)
+               readonly AParametersCollection parameters;
+
+               public ImportedMethodDefinition (MethodBase provider, AParametersCollection parameters)
                        : base (provider)
                {
+                       this.parameters = parameters;
+               }
+
+               #region Properties
+
+               public AParametersCollection Parameters {
+                       get {
+                               return parameters;
+                       }
                }
 
-               public MethodInfo MakeGenericMethod (Type[] targs)
+               public TypeSpec MemberType {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               #endregion
+       }
+
+       class ImportedGenericMethodDefinition : ImportedMethodDefinition, IGenericMethodDefinition
+       {
+               TypeParameterSpec[] tparams;
+
+               public ImportedGenericMethodDefinition (MethodInfo provider, AParametersCollection parameters, TypeParameterSpec[] tparams)
+                       : base (provider, parameters)
                {
-                       return ((MethodInfo) provider).MakeGenericMethod (targs);
+                       this.tparams = tparams;
+               }
+
+               #region Properties
+
+               public TypeParameterSpec[] TypeParameters {
+                       get {
+                               return tparams;
+                       }
                }
+
+               public int TypeParametersCount {
+                       get {
+                               return tparams.Length;
+                       }
+               }
+
+               #endregion
        }
 
        class ImportedTypeDefinition : ImportedMemberDefinition, ITypeDefinition
        {
+               TypeParameterSpec[] tparams;
+               string name;
+
                public ImportedTypeDefinition (Type type)
                        : base (type)
                {
                }
 
-               public void LoadMembers (MemberCache cache)
+               #region Properties
+
+               public override string Name {
+                       get {
+                               if (name == null) {
+                                       name = base.Name;
+                                       if (tparams != null)
+                                               name = name.Substring (0, name.IndexOf ('`'));
+                               }
+
+                               return name;
+                       }
+               }
+
+               public string Namespace {
+                       get {
+                               return ((Type) provider).Namespace;
+                       }
+               }
+
+               public int TypeParametersCount {
+                       get {
+                               return tparams == null ? 0 : tparams.Length;
+                       }
+               }
+
+               public TypeParameterSpec[] TypeParameters {
+                       get {
+                               return tparams;
+                       }
+                       set {
+                               tparams = value;
+                       }
+               }
+
+               #endregion
+
+               public TypeSpec GetAttributeCoClass ()
+               {
+                       // TODO: Use ReadAttributes
+                       var attr =  provider.GetCustomAttributes (typeof (CoClassAttribute), false);
+                       if (attr.Length < 1)
+                               return null;
+
+                       return Import.CreateType (((CoClassAttribute) attr[0]).CoClass);
+               }
+
+               public string GetAttributeDefaultMember ()
+               {
+                       if (cattrs == null)
+                               ReadAttributes ();
+
+                       return cattrs.DefaultIndexerName;
+               }
+
+               public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+               {
+                       if (cattrs == null)
+                               ReadAttributes ();
+
+                       return cattrs.AttributeUsage;
+               }
+
+               public MemberCache LoadMembers (TypeSpec declaringType)
+               {
+                       var loading_type = (Type) provider;
+                       const BindingFlags all_members = BindingFlags.DeclaredOnly |
+                               BindingFlags.Static | BindingFlags.Instance |
+                               BindingFlags.Public | BindingFlags.NonPublic;
+
+                       const MethodAttributes explicit_impl = MethodAttributes.NewSlot |
+                                       MethodAttributes.Virtual | MethodAttributes.HideBySig |
+                                       MethodAttributes.Final | MethodAttributes.Private;
+
+                       Dictionary<MethodBase, MethodSpec> possible_accessors = null;
+                       MemberSpec imported;
+                       MethodInfo m;
+                       List<string> fields_to_ignore = null;
+
+                       //
+                       // This requires methods to be returned first which seems to work for both Mono and .NET
+                       //
+                       var all = loading_type.GetMembers (all_members);
+
+                       var cache = new MemberCache (all.Length);
+                       foreach (var member in all) {
+                               switch (member.MemberType) {
+                               case MemberTypes.Constructor:
+                               case MemberTypes.Method:
+                                       MethodBase mb = (MethodBase) member;
+
+                                       // Ignore explicitly implemented members
+                                       if ((mb.Attributes & explicit_impl) == explicit_impl)
+                                               continue;
+
+                                       // Ignore compiler generated methods
+                                       if (mb.IsPrivate && mb.IsDefined (typeof (CompilerGeneratedAttribute), false))
+                                               continue;
+
+                                       imported = Import.CreateMethod (mb, declaringType);
+                                       var name = imported.Name;
+                                       if (imported.Kind == MemberKind.Method && name.Length > 4) {
+                                               if ((name[3] == '_' && (name.StartsWith ("get", StringComparison.Ordinal) ||
+                                                        name.StartsWith ("set", StringComparison.Ordinal) || 
+                                                        name.StartsWith ("add", StringComparison.Ordinal))) ||
+                                                       name.Length > 7 && name[6] == '_' && name.StartsWith ("remove", StringComparison.Ordinal)) {
+
+                                                       if (possible_accessors == null)
+                                                               possible_accessors = new Dictionary<MethodBase, MethodSpec> ();
+
+                                                       possible_accessors.Add (mb, (MethodSpec) imported);
+                                               }
+                                       }
+
+                                       break;
+                               case MemberTypes.Property:
+                                       if (possible_accessors == null)
+                                               continue;
+
+                                       var p = (PropertyInfo) member;
+                                       //
+                                       // Links possible accessors with property
+                                       //
+                                       MethodSpec get, set;
+                                       m = p.GetGetMethod (true);
+                                       if (m == null || !possible_accessors.TryGetValue (m, out get))
+                                               get = null;
+
+                                       m = p.GetSetMethod (true);
+                                       if (m == null || !possible_accessors.TryGetValue (m, out set))
+                                               set = null;
+
+                                       // No accessors registered (e.g. explicit implementation)
+                                       if (get == null && set == null)
+                                               continue;
+
+                                       imported = Import.CreateProperty (p, declaringType, get, set);
+                                       if (imported == null)
+                                               continue;
+
+                                       break;
+                               case MemberTypes.Event:
+                                       if (possible_accessors == null)
+                                               continue;
+
+                                       var e = (EventInfo) member;
+                                       //
+                                       // Links accessors with event
+                                       //
+                                       MethodSpec add, remove;
+                                       m = e.GetAddMethod (true);
+                                       if (m == null || !possible_accessors.TryGetValue (m, out add))
+                                               add = null;
+
+                                       m = e.GetRemoveMethod (true);
+                                       if (m == null || !possible_accessors.TryGetValue (m, out remove))
+                                               remove = null;
+
+                                       // Both accessors are required
+                                       if (add == null || remove == null)
+                                               continue;
+
+                                       if (fields_to_ignore == null)
+                                               fields_to_ignore = new List<string> ();
+
+                                       fields_to_ignore.Add (e.Name);
+
+                                       imported = Import.CreateEvent (e, declaringType, add, remove);
+                                       break;
+                               case MemberTypes.Field:
+                                       var fi = (FieldInfo) member;
+
+                                       // Ignore compiler generated fields
+                                       if (fi.IsPrivate && fi.IsDefined (typeof (CompilerGeneratedAttribute), false))
+                                               continue;
+
+                                       if (fields_to_ignore != null && fields_to_ignore.Contains (fi.Name))
+                                               continue;
+
+                                       imported = Import.CreateField (fi, declaringType);
+                                       break;
+                               case MemberTypes.NestedType:
+                                       Type t = (Type) member;
+
+                                       // Ignore compiler generated types, mostly lambda containers
+                                       if (t.IsNotPublic && t.IsDefined (typeof (CompilerGeneratedAttribute), false))
+                                               continue;
+
+                                       imported = Import.CreateType (t, declaringType);
+                                       break;
+                               default:
+                                       throw new NotImplementedException (member.ToString ());
+                               }
+
+                               cache.AddMember (imported);
+                       }
+
+                       if (declaringType.IsInterface && declaringType.Interfaces != null) {
+                               foreach (var iface in declaringType.Interfaces) {
+                                       cache.AddInterface (iface);
+                               }
+                       }
+
+                       return cache;
+               }
+       }
+
+       class ImportedTypeParameterDefinition : ImportedMemberDefinition, ITypeDefinition
+       {
+               public ImportedTypeParameterDefinition (Type type)
+                       : base (type)
+               {
+               }
+
+               #region Properties
+
+               public string Namespace {
+                       get {
+                               return null;
+                       }
+               }
+
+               public int TypeParametersCount {
+                       get {
+                               return 0;
+                       }
+               }
+
+               public TypeParameterSpec[] TypeParameters {
+                       get {
+                               return null;
+                       }
+               }
+
+               #endregion
+
+               public TypeSpec GetAttributeCoClass ()
+               {
+                       return null;
+               }
+
+               public string GetAttributeDefaultMember ()
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public MemberCache LoadMembers (TypeSpec declaringType)
                {
                        throw new NotImplementedException ();
                }
index 20d6741406bac6b9cae6b96914458872c908bfca..b25dff540fc03dbaa26a73ea14a188e70b2f2cc8 100644 (file)
@@ -49,11 +49,6 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-               }
-               
                public override bool Resolve (BlockContext ec)
                {
                        expr = expr.Resolve (ec);
@@ -120,12 +115,7 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       iterator.EmitYieldBreak (ec.ig, unwind_protect);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       // nothing to do
+                       iterator.EmitYieldBreak (ec, unwind_protect);
                }
        }
 
@@ -163,12 +153,6 @@ namespace Mono.CSharp {
                {
                        iterator.EmitMoveNext (ec, original_block);
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       original_block.MutateHoistedGenericType (storey);
-                       iterator.MutateHoistedGenericType (storey);
-               }
        }
 
        public class IteratorStorey : AnonymousMethodStorey
@@ -218,7 +202,7 @@ namespace Mono.CSharp {
 
                                public override bool Resolve (BlockContext ec)
                                {
-                                       TypeExpression storey_type_expr = new TypeExpression (host.TypeBuilder, loc);
+                                       TypeExpression storey_type_expr = new TypeExpression (host.Definition, loc);
                                        List<Expression> init = null;
                                        if (host.hoisted_this != null) {
                                                init = new List<Expression> (host.hoisted_params == null ? 1 : host.HoistedParameters.Count + 1);
@@ -255,11 +239,20 @@ namespace Mono.CSharp {
                                                new_storey = Convert.ImplicitConversionRequired (ec, new_storey, host_method.MemberType, loc);
 
                                        if (TypeManager.int_interlocked_compare_exchange == null) {
-                                               Type t = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Interlocked", MemberKind.Class, true);
+                                               TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Interlocked", MemberKind.Class, true);
                                                if (t != null) {
-                                                       TypeManager.int_interlocked_compare_exchange = TypeManager.GetPredefinedMethod (
-                                                               t, "CompareExchange", loc, TypeManager.int32_type,
-                                                               TypeManager.int32_type, TypeManager.int32_type);
+                                                       var p = ParametersCompiled.CreateFullyResolved (
+                                                               new[] {
+                                                                       new ParameterData (null, Parameter.Modifier.REF),
+                                                                       new ParameterData (null, Parameter.Modifier.NONE),
+                                                                       new ParameterData (null, Parameter.Modifier.NONE)
+                                                               },
+                                                               new[] {
+                                                                       TypeManager.int32_type, TypeManager.int32_type, TypeManager.int32_type
+                                                               }
+                                                               );
+                                                       var f = new MemberFilter ("CompareExchange", 0, MemberKind.Method, p, TypeManager.int32_type);
+                                                       TypeManager.int_interlocked_compare_exchange = TypeManager.GetPredefinedMethod (t, f, loc);
                                                }
                                        }
 
@@ -269,30 +262,24 @@ namespace Mono.CSharp {
 
                                protected override void DoEmit (EmitContext ec)
                                {
-                                       ILGenerator ig = ec.ig;
-                                       Label label_init = ig.DefineLabel ();
+                                       Label label_init = ec.DefineLabel ();
 
-                                       ig.Emit (OpCodes.Ldarg_0);
-                                       ig.Emit (OpCodes.Ldflda, host.PC.Spec.MetaInfo);
-                                       IntConstant.EmitInt (ig, (int) Iterator.State.Start);
-                                       IntConstant.EmitInt (ig, (int) Iterator.State.Uninitialized);
-                                       ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.int_interlocked_compare_exchange.MetaInfo);
+                                       ec.Emit (OpCodes.Ldarg_0);
+                                       ec.Emit (OpCodes.Ldflda, host.PC.Spec);
+                                       ec.EmitInt ((int) Iterator.State.Start);
+                                       ec.EmitInt ((int) Iterator.State.Uninitialized);
+                                       ec.Emit (OpCodes.Call, TypeManager.int_interlocked_compare_exchange);
 
-                                       IntConstant.EmitInt (ig, (int) Iterator.State.Uninitialized);
-                                       ig.Emit (OpCodes.Bne_Un_S, label_init);
+                                       ec.EmitInt ((int) Iterator.State.Uninitialized);
+                                       ec.Emit (OpCodes.Bne_Un_S, label_init);
 
-                                       ig.Emit (OpCodes.Ldarg_0);
-                                       ig.Emit (OpCodes.Ret);
+                                       ec.Emit (OpCodes.Ldarg_0);
+                                       ec.Emit (OpCodes.Ret);
 
-                                       ig.MarkLabel (label_init);
+                                       ec.MarkLabel (label_init);
 
                                        new_storey.Emit (ec);
-                                       ig.Emit (OpCodes.Ret);
-                               }
-
-                               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                               {
-                                       throw new NotSupportedException ();
+                                       ec.Emit (OpCodes.Ret);
                                }
                        }
 
@@ -329,11 +316,6 @@ namespace Mono.CSharp {
                                {
                                        iterator.EmitDispose (ec);
                                }
-
-                               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                               {
-                                       throw new NotSupportedException ();
-                               }
                        }
 
                        public DisposeMethod (IteratorStorey host)
@@ -362,8 +344,8 @@ namespace Mono.CSharp {
 
                        protected override Expression DoResolve (ResolveContext ec)
                        {
-                               Methods = new [] { method.Spec };
-                               type = method.Parent.TypeBuilder;
+                               Methods = new List<MemberSpec> (1) { method.Spec };
+                               type = method.Parent.Definition;
                                InstanceExpression = new CompilerGeneratedThis (type, Location);
                                return base.DoResolve (ec);
                        }
@@ -382,7 +364,7 @@ namespace Mono.CSharp {
                        protected override Expression DoResolve (ResolveContext ec)
                        {
                                spec = field.Spec;
-                               type = TypeManager.TypeToCoreType (spec.FieldType);
+                               type = spec.MemberType;
                                InstanceExpression = new CompilerGeneratedThis (type, Location);
                                return base.DoResolve (ec);
                        }
@@ -424,7 +406,11 @@ namespace Mono.CSharp {
 
                protected override TypeExpr [] ResolveBaseTypes (out TypeExpr base_class)
                {
-                       iterator_type_expr = new TypeExpression (MutateType (Iterator.OriginalIteratorType), Location);
+                       var mtype = Iterator.OriginalIteratorType;
+                       if (Mutator != null)
+                               mtype = Mutator.Mutate (mtype);
+
+                       iterator_type_expr = new TypeExpression (mtype, Location);
                        generic_args = new TypeArguments (iterator_type_expr);
 
                        var list = new List<FullNamedExpression> ();
@@ -464,7 +450,13 @@ namespace Mono.CSharp {
                        return "<" + local_info.Name + ">__" + local_name_idx++.ToString ();
                }
 
-               public void DefineIteratorMembers ()
+               protected override bool DoDefineMembers ()
+               {
+                       DefineIteratorMembers ();
+                       return base.DoDefineMembers ();
+               }
+
+               void DefineIteratorMembers ()
                {
                        pc_field = AddCompilerGeneratedField ("$PC", TypeManager.system_int32_expr);
                        current_field = AddCompilerGeneratedField ("$current", iterator_type_expr);
@@ -563,7 +555,7 @@ namespace Mono.CSharp {
 
                        reset.Block = new ToplevelBlock (Compiler, Location);
 
-                       Type ex_type = TypeManager.CoreLookupType (Compiler, "System", "NotSupportedException", MemberKind.Class, true);
+                       TypeSpec ex_type = TypeManager.CoreLookupType (Compiler, "System", "NotSupportedException", MemberKind.Class, true);
                        if (ex_type == null)
                                return;
 
@@ -603,7 +595,7 @@ namespace Mono.CSharp {
                        get { return OriginalMethod.GenericMethod; }
                }
 
-               public readonly Type OriginalIteratorType;
+               public readonly TypeSpec OriginalIteratorType;
 
                readonly IteratorStorey IteratorHost;
 
@@ -614,40 +606,36 @@ namespace Mono.CSharp {
                        Start = 0
                }
 
-               public void EmitYieldBreak (ILGenerator ig, bool unwind_protect)
+               public void EmitYieldBreak (EmitContext ec, bool unwind_protect)
                {
-                       ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_error);
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_error);
                }
 
                void EmitMoveNext_NoResumePoints (EmitContext ec, Block original_block)
                {
-                       ILGenerator ig = ec.ig;
-
-                       ig.Emit (OpCodes.Ldarg_0);
-                       ig.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec.MetaInfo);
+                       ec.Emit (OpCodes.Ldarg_0);
+                       ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);
 
-                       ig.Emit (OpCodes.Ldarg_0);
-                       IntConstant.EmitInt (ig, (int) State.After);
-                       ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+                       ec.Emit (OpCodes.Ldarg_0);
+                       ec.EmitInt ((int) State.After);
+                       ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
 
                        // We only care if the PC is zero (start executing) or non-zero (don't do anything)
-                       ig.Emit (OpCodes.Brtrue, move_next_error);
+                       ec.Emit (OpCodes.Brtrue, move_next_error);
 
-                       SymbolWriter.StartIteratorBody (ec.ig);
+                       SymbolWriter.StartIteratorBody (ec);
                        original_block.Emit (ec);
-                       SymbolWriter.EndIteratorBody (ec.ig);
+                       SymbolWriter.EndIteratorBody (ec);
 
-                       ig.MarkLabel (move_next_error);
-                       ig.Emit (OpCodes.Ldc_I4_0);
-                       ig.Emit (OpCodes.Ret);
+                       ec.MarkLabel (move_next_error);
+                       ec.Emit (OpCodes.Ldc_I4_0);
+                       ec.Emit (OpCodes.Ret);
                }
 
                internal void EmitMoveNext (EmitContext ec, Block original_block)
                {
-                       ILGenerator ig = ec.ig;
-
-                       move_next_ok = ig.DefineLabel ();
-                       move_next_error = ig.DefineLabel ();
+                       move_next_ok = ec.DefineLabel ();
+                       move_next_error = ec.DefineLabel ();
 
                        if (resume_points == null) {
                                EmitMoveNext_NoResumePoints (ec, original_block);
@@ -655,17 +643,17 @@ namespace Mono.CSharp {
                        }
 
                        current_pc = ec.GetTemporaryLocal (TypeManager.uint32_type);
-                       ig.Emit (OpCodes.Ldarg_0);
-                       ig.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec.MetaInfo);
-                       ig.Emit (OpCodes.Stloc, current_pc);
+                       ec.Emit (OpCodes.Ldarg_0);
+                       ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);
+                       ec.Emit (OpCodes.Stloc, current_pc);
 
                        // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
-                       ig.Emit (OpCodes.Ldarg_0);
-                       IntConstant.EmitInt (ig, (int) State.After);
-                       ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+                       ec.Emit (OpCodes.Ldarg_0);
+                       ec.EmitInt ((int) State.After);
+                       ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
 
                        Label [] labels = new Label [1 + resume_points.Count];
-                       labels [0] = ig.DefineLabel ();
+                       labels [0] = ec.DefineLabel ();
 
                        bool need_skip_finally = false;
                        for (int i = 0; i < resume_points.Count; ++i) {
@@ -676,45 +664,43 @@ namespace Mono.CSharp {
 
                        if (need_skip_finally) {
                                skip_finally = ec.GetTemporaryLocal (TypeManager.bool_type);
-                               ig.Emit (OpCodes.Ldc_I4_0);
-                               ig.Emit (OpCodes.Stloc, skip_finally);
+                               ec.Emit (OpCodes.Ldc_I4_0);
+                               ec.Emit (OpCodes.Stloc, skip_finally);
                        }
 
-                       SymbolWriter.StartIteratorDispatcher (ec.ig);
-                       ig.Emit (OpCodes.Ldloc, current_pc);
-                       ig.Emit (OpCodes.Switch, labels);
+                       SymbolWriter.StartIteratorDispatcher (ec);
+                       ec.Emit (OpCodes.Ldloc, current_pc);
+                       ec.Emit (OpCodes.Switch, labels);
 
-                       ig.Emit (OpCodes.Br, move_next_error);
-                       SymbolWriter.EndIteratorDispatcher (ec.ig);
+                       ec.Emit (OpCodes.Br, move_next_error);
+                       SymbolWriter.EndIteratorDispatcher (ec);
 
-                       ig.MarkLabel (labels [0]);
+                       ec.MarkLabel (labels [0]);
 
-                       SymbolWriter.StartIteratorBody (ec.ig);
+                       SymbolWriter.StartIteratorBody (ec);
                        original_block.Emit (ec);
-                       SymbolWriter.EndIteratorBody (ec.ig);
+                       SymbolWriter.EndIteratorBody (ec);
 
-                       SymbolWriter.StartIteratorDispatcher (ec.ig);
+                       SymbolWriter.StartIteratorDispatcher (ec);
 
-                       ig.Emit (OpCodes.Ldarg_0);
-                       IntConstant.EmitInt (ig, (int) State.After);
-                       ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+                       ec.Emit (OpCodes.Ldarg_0);
+                       ec.EmitInt ((int) State.After);
+                       ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
 
-                       ig.MarkLabel (move_next_error);
-                       ig.Emit (OpCodes.Ldc_I4_0);
-                       ig.Emit (OpCodes.Ret);
+                       ec.MarkLabel (move_next_error);
+                       ec.EmitInt (0);
+                       ec.Emit (OpCodes.Ret);
 
-                       ig.MarkLabel (move_next_ok);
-                       ig.Emit (OpCodes.Ldc_I4_1);
-                       ig.Emit (OpCodes.Ret);
+                       ec.MarkLabel (move_next_ok);
+                       ec.Emit (OpCodes.Ldc_I4_1);
+                       ec.Emit (OpCodes.Ret);
 
-                       SymbolWriter.EndIteratorDispatcher (ec.ig);
+                       SymbolWriter.EndIteratorDispatcher (ec);
                }
 
                public void EmitDispose (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
-                       Label end = ig.DefineLabel ();
+                       Label end = ec.DefineLabel ();
 
                        Label [] labels = null;
                        int n_resume_points = resume_points == null ? 0 : resume_points.Count;
@@ -733,26 +719,26 @@ namespace Mono.CSharp {
 
                        if (labels != null) {
                                current_pc = ec.GetTemporaryLocal (TypeManager.uint32_type);
-                               ig.Emit (OpCodes.Ldarg_0);
-                               ig.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec.MetaInfo);
-                               ig.Emit (OpCodes.Stloc, current_pc);
+                               ec.Emit (OpCodes.Ldarg_0);
+                               ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);
+                               ec.Emit (OpCodes.Stloc, current_pc);
                        }
 
-                       ig.Emit (OpCodes.Ldarg_0);
-                       IntConstant.EmitInt (ig, (int) State.After);
-                       ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+                       ec.Emit (OpCodes.Ldarg_0);
+                       ec.EmitInt ((int) State.After);
+                       ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
 
                        if (labels != null) {
                                //SymbolWriter.StartIteratorDispatcher (ec.ig);
-                               ig.Emit (OpCodes.Ldloc, current_pc);
-                               ig.Emit (OpCodes.Switch, labels);
+                               ec.Emit (OpCodes.Ldloc, current_pc);
+                               ec.Emit (OpCodes.Switch, labels);
                                //SymbolWriter.EndIteratorDispatcher (ec.ig);
 
                                foreach (ResumableStatement s in resume_points)
                                        s.EmitForDispose (ec, this, end, true);
                        }
 
-                       ig.MarkLabel (end);
+                       ec.MarkLabel (end);
                }
 
                public int AddResumePoint (ResumableStatement stmt)
@@ -769,28 +755,26 @@ namespace Mono.CSharp {
                //
                public void MarkYield (EmitContext ec, Expression expr, int resume_pc, bool unwind_protect, Label resume_point)
                {
-                       ILGenerator ig = ec.ig;
-
                        // Store the new current
-                       ig.Emit (OpCodes.Ldarg_0);
+                       ec.Emit (OpCodes.Ldarg_0);
                        expr.Emit (ec);
-                       ig.Emit (OpCodes.Stfld, IteratorHost.CurrentField.Spec.MetaInfo);
+                       ec.Emit (OpCodes.Stfld, IteratorHost.CurrentField.Spec);
 
                        // store resume program-counter
-                       ig.Emit (OpCodes.Ldarg_0);
-                       IntConstant.EmitInt (ig, resume_pc);
-                       ig.Emit (OpCodes.Stfld, IteratorHost.PC.Spec.MetaInfo);
+                       ec.Emit (OpCodes.Ldarg_0);
+                       ec.EmitInt (resume_pc);
+                       ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
 
                        // mark finally blocks as disabled
                        if (unwind_protect && skip_finally != null) {
-                               ig.Emit (OpCodes.Ldc_I4_1);
-                               ig.Emit (OpCodes.Stloc, skip_finally);
+                               ec.EmitInt (1);
+                               ec.Emit (OpCodes.Stloc, skip_finally);
                        }
 
                        // Return ok
-                       ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_ok);
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_ok);
 
-                       ig.MarkLabel (resume_point);
+                       ec.MarkLabel (resume_point);
                }
 
                public override string ContainerType {
@@ -808,7 +792,7 @@ namespace Mono.CSharp {
                //
                // Our constructor
                //
-               private Iterator (CompilerContext ctx, IMethodData method, TypeContainer host, Type iterator_type, bool is_enumerable)
+               private Iterator (CompilerContext ctx, IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable)
                        : base (
                                new ToplevelBlock (ctx, method.Block, ParametersCompiled.EmptyReadOnlyParameters, method.Block.StartLocation),
                                TypeManager.bool_type,
@@ -839,8 +823,6 @@ namespace Mono.CSharp {
                        if (Compatible (ec) == null)
                                return null;
 
-                       IteratorHost.DefineIteratorMembers ();
-
                        eclass = ExprClass.Value;
                        return this;
                }
@@ -856,15 +838,15 @@ namespace Mono.CSharp {
                        // Initialize iterator PC when it's unitialized
                        //
                        if (IsEnumerable) {
-                               ILGenerator ig = ec.ig;
-                               ig.Emit (OpCodes.Dup);
-                               IntConstant.EmitInt (ig, (int)State.Uninitialized);
+                               ec.Emit (OpCodes.Dup);
+                               ec.EmitInt ((int)State.Uninitialized);
 
-                               FieldInfo field = IteratorHost.PC.Spec.MetaInfo;
-                               if (Storey.MemberName.IsGeneric)
-                                       field = TypeBuilder.GetField (Storey.Instance.Type, field);
+                               var field = IteratorHost.PC.Spec;
+                               if (Storey.MemberName.IsGeneric) {
+                                       field = MemberCache.GetMember (Storey.Instance.Type, field);
+                               }
 
-                               ig.Emit (OpCodes.Stfld, field);
+                               ec.Emit (OpCodes.Stfld, field);
                        }
                }
 
@@ -876,9 +858,9 @@ namespace Mono.CSharp {
                public static void CreateIterator (IMethodData method, TypeContainer parent, Modifiers modifiers, CompilerContext ctx)
                {
                        bool is_enumerable;
-                       Type iterator_type;
+                       TypeSpec iterator_type;
 
-                       Type ret = method.ReturnType;
+                       TypeSpec ret = method.ReturnType;
                        if (ret == null)
                                return;
 
@@ -920,11 +902,11 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       Iterator iter = new Iterator (ctx, method, parent, iterator_type, is_enumerable);
-                       iter.Storey.DefineType ();
+                       // TODO: Ugly leftover
+                       new Iterator (ctx, method, parent, iterator_type, is_enumerable);
                }
 
-               static bool CheckType (Type ret, out Type original_iterator_type, out bool is_enumerable)
+               static bool CheckType (TypeSpec ret, out TypeSpec original_iterator_type, out bool is_enumerable)
                {
                        original_iterator_type = null;
                        is_enumerable = false;
@@ -940,22 +922,19 @@ namespace Mono.CSharp {
                                return true;
                        }
 
-                       if (!TypeManager.IsGenericType (ret))
-                               return false;
-
-                       Type[] args = TypeManager.GetTypeArguments (ret);
-                       if (args.Length != 1)
+                       InflatedTypeSpec inflated = ret as InflatedTypeSpec;
+                       if (inflated == null)
                                return false;
 
-                       Type gt = TypeManager.DropGenericTypeArguments (ret);
-                       if (gt == TypeManager.generic_ienumerable_type) {
-                               original_iterator_type = TypeManager.TypeToCoreType (args [0]);
+                       ret = inflated.GetDefinition ();
+                       if (ret == TypeManager.generic_ienumerable_type) {
+                               original_iterator_type = inflated.TypeArguments[0];
                                is_enumerable = true;
                                return true;
                        }
                        
-                       if (gt == TypeManager.generic_ienumerator_type) {
-                               original_iterator_type = TypeManager.TypeToCoreType (args [0]);
+                       if (ret == TypeManager.generic_ienumerator_type) {
+                               original_iterator_type = inflated.TypeArguments[0];
                                is_enumerable = false;
                                return true;
                        }
index 4289814fb92bd7048d0281bc80f91bdd7ccb0031..eb4907b1816bd663a7df3120411ff50119a3f3ca 100644 (file)
@@ -26,7 +26,7 @@ namespace Mono.CSharp {
                {
                }
 
-               protected override Expression CreateExpressionTree (ResolveContext ec, Type delegate_type)
+               protected override Expression CreateExpressionTree (ResolveContext ec, TypeSpec delegate_type)
                {
                        if (ec.IsInProbingMode)
                                return this;
@@ -54,12 +54,12 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected override ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, Type delegateType)
+               protected override ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegateType)
                {
-                       if (!TypeManager.IsDelegateType (delegateType))
+                       if (!delegateType.IsDelegate)
                                return null;
 
-                       AParametersCollection d_params = TypeManager.GetDelegateParameters (ec, delegateType);
+                       AParametersCollection d_params = Delegate.GetParameters (ec.Compiler, delegateType);
 
                        if (HasExplicitParameters) {
                                if (!VerifyExplicitParameters (ec, delegateType, d_params))
@@ -75,19 +75,14 @@ namespace Mono.CSharp {
                        if (!VerifyParameterCompatibility (ec, delegateType, d_params, ec.IsInProbingMode))
                                return null;
 
-                       Type [] ptypes = new Type [Parameters.Count];
+                       TypeSpec [] ptypes = new TypeSpec [Parameters.Count];
                        for (int i = 0; i < d_params.Count; i++) {
                                // D has no ref or out parameters
                                if ((d_params.FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) != 0)
                                        return null;
 
-                               Type d_param = d_params.Types [i];
+                               TypeSpec d_param = d_params.Types [i];
 
-#if MS_COMPATIBLE
-                               // Blablabla, because reflection does not work with dynamic types
-                               if (d_param.IsGenericParameter)
-                                       d_param = delegateType.GetGenericArguments () [d_param.GenericParameterPosition];
-#endif
                                //
                                // When type inference context exists try to apply inferred type arguments
                                //
@@ -96,7 +91,9 @@ namespace Mono.CSharp {
                                }
 
                                ptypes [i] = d_param;
-                               ((ImplicitLambdaParameter) Parameters.FixedParameters [i]).Type = d_param;
+                               ImplicitLambdaParameter ilp = (ImplicitLambdaParameter) Parameters.FixedParameters [i];
+                               ilp.Type = d_param;
+                               ilp.Resolve (null, i);
                        }
 
                        Parameters.Types = ptypes;
@@ -118,7 +115,7 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               protected override AnonymousMethodBody CompatibleMethodFactory (Type returnType, Type delegateType, ParametersCompiled p, ToplevelBlock b)
+               protected override AnonymousMethodBody CompatibleMethodFactory (TypeSpec returnType, TypeSpec delegateType, ParametersCompiled p, ToplevelBlock b)
                {
                        return new LambdaMethod (p, b, returnType, delegateType, loc);
                }
@@ -132,7 +129,7 @@ namespace Mono.CSharp {
        public class LambdaMethod : AnonymousMethodBody
        {
                public LambdaMethod (ParametersCompiled parameters,
-                                       ToplevelBlock block, Type return_type, Type delegate_type,
+                                       ToplevelBlock block, TypeSpec return_type, TypeSpec delegate_type,
                                        Location loc)
                        : base (parameters, block, return_type, delegate_type, loc)
                {
@@ -189,7 +186,7 @@ namespace Mono.CSharp {
                {
                        if (statement != null) {
                                statement.EmitStatement (ec);
-                               ec.ig.Emit (OpCodes.Ret);
+                               ec.Emit (OpCodes.Ret);
                                return;
                        }
 
index 2932b650646114ce1122a6e1431730b7a79cd1fa..420dae4bf832e7c4fcc18125e7c51c3f31bb855b 100644 (file)
@@ -70,8 +70,8 @@ namespace Mono.CSharp.Linq
                        {
                        }
 
-                       protected override Expression Error_MemberLookupFailed (ResolveContext ec, Type container_type, Type qualifier_type,
-                               Type queried_type, string name, string class_name, MemberTypes mt, BindingFlags bf)
+                       protected override Expression Error_MemberLookupFailed (ResolveContext ec, TypeSpec container_type, TypeSpec qualifier_type,
+                               TypeSpec queried_type, string name, int arity, string class_name, MemberKind mt, BindingRestriction bf)
                        {
                                ec.Report.Error (1935, loc, "An implementation of `{0}' query expression pattern could not be found. " +
                                        "Are you missing `System.Linq' using directive or `System.Core.dll' assembly reference?",
@@ -96,8 +96,8 @@ namespace Mono.CSharp.Linq
 
                        public bool AmbiguousCall (ResolveContext ec, MethodSpec ambiguous)
                        {
-                               ec.Report.SymbolRelatedToPreviousError (mg.BestCandidate.MetaInfo);
-                               ec.Report.SymbolRelatedToPreviousError (ambiguous.MetaInfo);
+                               ec.Report.SymbolRelatedToPreviousError (mg.BestCandidate);
+                               ec.Report.SymbolRelatedToPreviousError (ambiguous);
                                ec.Report.Error (1940, loc, "Ambiguous implementation of the query pattern `{0}' for source type `{1}'",
                                        mg.Name, mg.InstanceExpression.GetSignatureForError ());
                                return true;
@@ -106,15 +106,15 @@ namespace Mono.CSharp.Linq
                        public bool NoExactMatch (ResolveContext ec, MethodSpec method)
                        {
                                var pd = method.Parameters;
-                               Type source_type = pd.ExtensionMethodType;
+                               TypeSpec source_type = pd.ExtensionMethodType;
                                if (source_type != null) {
                                        Argument a = arguments [0];
 
                                        if (TypeManager.IsGenericType (source_type) && TypeManager.ContainsGenericParameters (source_type)) {
-                                               TypeInferenceContext tic = new TypeInferenceContext (TypeManager.GetTypeArguments (source_type));
+                                               TypeInferenceContext tic = new TypeInferenceContext (source_type.TypeArguments);
                                                tic.OutputTypeInference (ec, a.Expr, source_type);
                                                if (tic.FixAllTypes (ec)) {
-                                                       source_type = TypeManager.DropGenericTypeArguments (source_type).MakeGenericType (tic.InferredTypeArguments);
+                                                       source_type = source_type.GetDefinition ().MakeGenericType (tic.InferredTypeArguments);
                                                }
                                        }
 
@@ -125,7 +125,7 @@ namespace Mono.CSharp.Linq
                                        }
                                }
 
-                               if (!method.IsGenericMethod)
+                               if (!method.IsGeneric)
                                        return false;
 
                                if (mg.Name == "SelectMany") {
@@ -251,12 +251,12 @@ namespace Mono.CSharp.Linq
                {
                }
 
-               protected static Expression CreateRangeVariableType (ToplevelBlock block, IMemberContext context, SimpleMemberName name, Expression init)
+               protected static Expression CreateRangeVariableType (ToplevelBlock block, TypeContainer container, SimpleMemberName name, Expression init)
                {
                        var args = new List<AnonymousTypeParameter> (2);
                        args.Add (new AnonymousTypeParameter (block.Parameters [0]));
                        args.Add (new RangeAnonymousTypeParameter (init, name));
-                       return new NewAnonymousType (args, context.CurrentTypeDefinition, name.Location);
+                       return new NewAnonymousType (args, container, name.Location);
                }
        }
 
@@ -273,7 +273,7 @@ namespace Mono.CSharp.Linq
                        if (expr == null)
                                return null;
 
-                       if (TypeManager.IsDynamicType (expr.Type) || expr.Type == TypeManager.void_type) {
+                       if (expr.Type == InternalType.Dynamic || expr.Type == TypeManager.void_type) {
                                ec.Report.Error (1979, expr.Location,
                                        "Query expression with a source or join sequence of type `{0}' is not allowed",
                                        TypeManager.CSharpName (expr.Type));
@@ -400,7 +400,7 @@ namespace Mono.CSharp.Linq
                                result_selector_expr = next.Expr;
                                next = next.next;
                        } else {
-                               result_selector_expr = CreateRangeVariableType (block, ec.MemberContext, into_variable,
+                               result_selector_expr = CreateRangeVariableType (block, ec.MemberContext.CurrentMemberDefinition.Parent, into_variable,
                                        new SimpleName (into_variable.Value, into_variable.Location));
                        }
 
@@ -510,7 +510,7 @@ namespace Mono.CSharp.Linq
                                result_selector_expr = next.Expr;
                                next = next.next;
                        } else {
-                               result_selector_expr = CreateRangeVariableType (block, ec.MemberContext, lt, new SimpleName (lt.Value, lt.Location));
+                               result_selector_expr = CreateRangeVariableType (block, ec.MemberContext.CurrentMemberDefinition.Parent, lt, new SimpleName (lt.Value, lt.Location));
                        }
 
                        LambdaExpression result_selector = new LambdaExpression (lt.Location);
@@ -609,7 +609,7 @@ namespace Mono.CSharp.Linq
                                Identifier = identifier.Value;
                        }
 
-                       public static void Reset ()
+                       public new static void Reset ()
                        {
                                Counter = 0;
                        }
index f371812c6268f0a5fba0704f4aed6a06d7d4a44b..7b1243f1112b22b09d63ff8b6ee18baadbfbaa6b 100644 (file)
@@ -36,7 +36,7 @@ namespace Mono.CSharp {
                // Default type of null is an object
                //
                public NullLiteral (Location loc)
-                       : base (typeof (NullLiteral), loc)
+                       : base (InternalType.Null, loc)
                {
                }
 
@@ -48,9 +48,9 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Constant", args);
                }               
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type t, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec t, bool expl)
                {
-                       if (TypeManager.IsGenericParameter (t)) {
+                       if (t.IsGenericParameter) {
                                ec.Report.Error(403, loc,
                                        "Cannot convert null to the type parameter `{0}' because it could be a value " +
                                        "type. Consider using `default ({0})' instead", t.Name);
@@ -66,7 +66,7 @@ namespace Mono.CSharp {
                        base.Error_ValueCannotBeConverted (ec, loc, t, expl);
                }
 
-               public override Constant ConvertImplicitly (ResolveContext rc, Type targetType)
+               public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec targetType)
                {
                        //
                        // Null literal is of object type
@@ -99,13 +99,11 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                               
                        //
                        // Emits null pointer
                        //
-                       ig.Emit (OpCodes.Ldc_I4_0);
-                       ig.Emit (OpCodes.Conv_U);
+                       ec.Emit (OpCodes.Ldc_I4_0);
+                       ec.Emit (OpCodes.Conv_U);
                }
        }
 
@@ -134,13 +132,13 @@ namespace Mono.CSharp {
                {
                }
 
-               public override Constant ConvertImplicitly (ResolveContext rc, Type type)
+               public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type)
                {
                        //
                        // The 0 literal can be converted to an enum value
                        //
                        if (Value == 0 && TypeManager.IsEnumType (type)) {
-                               Constant c = ConvertImplicitly (rc, TypeManager.GetEnumUnderlyingType (type));
+                               Constant c = ConvertImplicitly (rc, EnumSpec.GetUnderlyingType (type));
                                if (c == null)
                                        return null;
 
@@ -202,7 +200,7 @@ namespace Mono.CSharp {
                {
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, Type target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
                {
                        if (target == TypeManager.float_type) {
                                Error_664 (ec, loc, "float", "f");
index 9e22cdf99d1fa86d6ffcbbfaedb63fb4dedad2f1..22cff126c0c5dc7cc75b0e984b0da9e99b352aa3 100644 (file)
@@ -17,6 +17,7 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.Reflection.Emit;
 using System.Reflection;
+using System.Linq;
 
 namespace Mono.CSharp {
 
@@ -31,17 +32,21 @@ namespace Mono.CSharp {
                Indexer = 1 << 5,
                Operator = 1 << 6,
                Destructor      = 1 << 7,
-               //Constant = 1 << 8,
-
-               NestedType      = 1 << 10,
 
                Class           = 1 << 11,
                Struct          = 1 << 12,
                Delegate        = 1 << 13,
                Enum            = 1 << 14,
                Interface       = 1 << 15,
+               TypeParameter = 1 << 16,
+
+               PointerType = 1 << 20,
+               InternalCompilerType = 1 << 21,
+               FakeMethod = 1 << 22,
 
-               MaskType = Constructor | Event | Field | Method | Property | NestedType | Indexer | Operator | Destructor,
+               NestedMask = Class | Struct | Delegate | Enum | Interface,
+               GenericMask = Method | Class | Struct | Delegate | Interface,
+               MaskType = Constructor | Event | Field | Method | Property | Indexer | Operator | Destructor | NestedMask,
                All = MaskType
        }
 
@@ -56,1332 +61,1122 @@ namespace Mono.CSharp {
                // Inspect only queried type members
                DeclaredOnly = 1 << 1,
 
-               // Excluded static
+               // Exclude static
                InstanceOnly = 1 << 2,
 
-               // 
-               NoOverloadableOverrides = 1 << 3
+               // Ignore member overrides
+               NoOverrides     = 1 << 3
        }
-/*
-       public struct MemberFilter : IEquatable<MemberCore>
+
+       public struct MemberFilter : IEquatable<MemberSpec>
        {
                public readonly string Name;
                public readonly MemberKind Kind;
-               public readonly TypeSpec[] Parameters;
+               public readonly AParametersCollection Parameters;
                public readonly TypeSpec MemberType;
 
-               public MemberFilter (IMethod m)
-               {
-                       Name = m.MethodBuilder.Name;
-                       Kind = MemberKind.Method;
-                       Parameters = m.Parameters.Types;
-                       MemberType = m.ReturnType;
-               }
+               int arity; // -1 to ignore the check
+               TypeSpec invocation_type;
 
-               public MemberFilter (string name, MemberKind kind)
+               private MemberFilter (string name, MemberKind kind)
                {
                        Name = name;
                        Kind = kind;
                        Parameters = null;
                        MemberType = null;
+                       arity = -1;
+                       invocation_type = null;
+               }
+
+               public MemberFilter (MethodSpec m)
+               {
+                       Name = m.Name;
+                       Kind = MemberKind.Method;
+                       Parameters = m.Parameters;
+                       MemberType = m.ReturnType;
+                       arity = m.Arity;
+                       invocation_type = null;
                }
 
-               public MemberFilter (string name, MemberKind kind, TypeSpec[] param, TypeSpec type)
-                       : this (name, kind)
+               public MemberFilter (string name, int arity, MemberKind kind, AParametersCollection param, TypeSpec type)
                {
                        Name = name;
                        Kind = kind;
                        Parameters = param;
                        MemberType = type;
+                       this.arity = arity;
+                       invocation_type = null;
                }
 
-               public static MemberFilter Constuctor (TypeSpec[] param)
+               public TypeSpec InvocationType {
+                       get {
+                               return invocation_type;
+                       }
+                       set {
+                               invocation_type = value;
+                       }
+               }
+
+               public static MemberFilter Constructor (AParametersCollection param)
                {
-                       return new MemberFilter (System.Reflection.ConstructorInfo.ConstructorName, MemberKind.Constructor, param, null);
+                       return new MemberFilter (System.Reflection.ConstructorInfo.ConstructorName, 0, MemberKind.Constructor, param, null);
                }
 
                public static MemberFilter Property (string name, TypeSpec type)
                {
-                       return new MemberFilter (name, MemberKind.Property, null, type);
+                       return new MemberFilter (name, 0, MemberKind.Property, null, type);
                }
 
                public static MemberFilter Field (string name, TypeSpec type)
                {
-                       return new MemberFilter (name, MemberKind.Field, null, type);
+                       return new MemberFilter (name, 0, MemberKind.Field, null, type);
                }
 
-               public static MemberFilter Method (string name, TypeSpec[] param, TypeSpec type)
+               public static MemberFilter Method (string name, int arity, AParametersCollection param, TypeSpec type)
                {
-                       return new MemberFilter (name, MemberKind.Method, param, type);
+                       return new MemberFilter (name, arity, MemberKind.Method, param, type);
                }
 
-               #region IEquatable<MemberCore> Members
+               #region IEquatable<MemberSpec> Members
 
-               public bool Equals (MemberCore other)
+               public bool Equals (MemberSpec other)
                {
                        // Is the member of the correct type ?
-                       if ((other.MemberKind & Kind & MemberKind.MaskType) == 0)
+                       // TODO: Isn't this redundant ?
+                       if ((other.Kind & Kind & MemberKind.MaskType) == 0)
+                               return false;
+
+                       // Check arity when not disabled
+                       if (arity >= 0 && arity != other.Arity)
                                return false;
 
                        if (Parameters != null) {
                                if (other is IParametersMember) {
-                                       AParametersCollection other_param = ((IParametersMember) other).Parameters;
-                                       if (TypeSpecArrayComparer.Default.Equals (Parameters, other_param.Types))
-                                               return true;
+                                       var other_param = ((IParametersMember) other).Parameters;
+                                       if (!TypeSpecComparer.Override.IsEqual (Parameters, other_param))
+                                               return false;
+                               } else {
+                                       return false;
                                }
-
-                               return false;
                        }
 
                        if (MemberType != null) {
-                               //throw new NotImplementedException ();
+                               if (other is IInterfaceMemberSpec) {
+                                       var other_type = ((IInterfaceMemberSpec) other).MemberType;
+                                       if (!TypeSpecComparer.Override.IsEqual (other_type, MemberType))
+                                               return false;
+                               } else {
+                                       return false;
+                               }
                        }
 
+                       if (invocation_type != null && !IsAccessible (other))
+                               return false;
+
                        return true;
                }
 
+               bool IsAccessible (MemberSpec other)
+               {
+                       bool extra;
+                       return Expression.IsMemberAccessible (invocation_type, other, out extra);
+               }
+
                #endregion
        }
-*/ 
+
        /// <summary>
-       ///   This is a readonly list of MemberInfo's.      
+       ///   The MemberCache is used by dynamic and non-dynamic types to speed up
+       ///   member lookups.  It has a member name based hash table; it maps each member
+       ///   name to a list of CacheEntry objects.  Each CacheEntry contains a MemberInfo
+       ///   and the BindingFlags that were initially used to get it.  The cache contains
+       ///   all members of the current class and all inherited members.  If this cache is
+       ///   for an interface types, it also contains all inherited members.
+       ///
+       ///   There are two ways to get a MemberCache:
+       ///   * if this is a dynamic type, lookup the corresponding DeclSpace and then
+       ///     use the DeclSpace.MemberCache property.
+       ///   * if this not a dynamic type, call TypeHandle.GetTypeHandle() to get a
+       ///     TypeHandle instance for the type and then use TypeHandle.MemberCache.
        /// </summary>
-       public class MemberList : IList<MemberInfo> {
-               public readonly IList<MemberInfo> List;
-               int count;
-
-               /// <summary>
-               ///   Create a new MemberList from the given IList.
-               /// </summary>
-               public MemberList (IList<MemberInfo> list)
-               {
-                       if (list != null)
-                               this.List = list;
-                       else
-                               this.List = new List<MemberInfo> ();
-                       count = List.Count;
-               }
+       public class MemberCache
+       {
+               readonly Dictionary<string, IList<MemberSpec>> member_hash;
+               Dictionary<string, MemberSpec[]> locase_members;
+               IList<MethodSpec> missing_abstract;
 
-               /// <summary>
-               ///   Concatenate the ILists `first' and `second' to a new MemberList.
-               /// </summary>
-               public MemberList (IList<MemberInfo> first, IList<MemberInfo> second)
-               {
-                       var list = new List<MemberInfo> ();
-                       list.AddRange (first);
-                       list.AddRange (second);
-                       count = list.Count;
-                       List = list;
-               }
+               public static readonly string IndexerNameAlias = "<this>";
 
-               public static readonly MemberList Empty = new MemberList (Array.AsReadOnly (new MemberInfo[0]));
+               public static readonly MemberCache Empty = new MemberCache (0);
 
-               /// <summary>
-               ///   Cast the MemberList into a MemberInfo[] array.
-               /// </summary>
-               /// <remarks>
-               ///   This is an expensive operation, only use it if it's really necessary.
-               /// </remarks>
-               public static explicit operator MemberInfo [] (MemberList list)
+               public MemberCache ()
+                       : this (16)
                {
-                       Timer.StartTimer (TimerType.MiscTimer);
-                       MemberInfo [] result = new MemberInfo [list.Count];
-                       list.CopyTo (result, 0);
-                       Timer.StopTimer (TimerType.MiscTimer);
-                       return result;
                }
 
-               // ICollection
-
-               public int Count {
-                       get {
-                               return count;
-                       }
-               }
-
-               public void CopyTo (MemberInfo[] array, int index)
+               public MemberCache (int capacity)
                {
-                       List.CopyTo (array, index);
+                       member_hash = new Dictionary<string, IList<MemberSpec>> (capacity);
                }
 
-               // IEnumerable
-
-               public IEnumerator<MemberInfo> GetEnumerator ()
+               public MemberCache (MemberCache cache)
+                       : this (cache.member_hash.Count)
                {
-                       return List.GetEnumerator ();
                }
 
-               System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
+               //
+               // Creates a new MemberCache for the given `container'.
+               //
+               public MemberCache (TypeContainer container)
+                       : this ()                               // TODO: Optimize the size
                {
-                       return List.GetEnumerator ();
                }
 
-               // IList
+               //
+               // Member-cache does not contain base members but it does
+               // contain all base interface members, so the Lookup code
+               // can use simple inheritance rules.
+               //
+               public void AddInterface (TypeSpec iface)
+               {
+                       var cache = iface.MemberCache;
 
-               public bool IsFixedSize {
-                       get {
-                               return true;
-                       }
-               }
+                       IList<MemberSpec> list;
+                       foreach (var entry in cache.member_hash) {
+                               if (!member_hash.TryGetValue (entry.Key, out list)) {
+                                       if (entry.Value.Count == 1) {
+                                               list = entry.Value;
+                                       } else {
+                                               list = new List<MemberSpec> (entry.Value);
+                                       }
 
-               public bool IsReadOnly {
-                       get {
-                               return true;
-                       }
-               }
+                                       member_hash.Add (entry.Key, list);
+                                       continue;
+                               }
 
-               MemberInfo IList<MemberInfo>.this [int index] {
-                       get {
-                               return List [index];
-                       }
+                               foreach (var ce in entry.Value) {
+                                       if (ce.DeclaringType != iface)
+                                               break;
 
-                       set {
-                               throw new NotSupportedException ();
-                       }
-               }
+                                       if (list.Contains (ce))
+                                               continue;
 
-               // FIXME: try to find out whether we can avoid the cast in this indexer.
-               public MemberInfo this [int index] {
-                       get {
-                               return (MemberInfo) List [index];
+                                       if (AddInterfaceMember (ce, ref list))
+                                               member_hash[entry.Key] = list;
+                               }
                        }
                }
 
-               public void Add (MemberInfo value)
+               public void AddMember (InterfaceMemberBase imb, string exlicitName, MemberSpec ms)
                {
-                       throw new NotSupportedException ();
+                       // Explicit names cannot be looked-up but can be used for
+                       // collision checking (no name mangling needed)
+                       if (imb.IsExplicitImpl)
+                               AddMember (exlicitName, ms);
+                       else
+                               AddMember (ms);
                }
 
-               public void Clear ()
+               //
+               // Add non-explicit member to member cache
+               //
+               public void AddMember (MemberSpec ms)
                {
-                       throw new NotSupportedException ();
+                       AddMember (GetLookupName (ms), ms);
                }
 
-               public bool Contains (MemberInfo value)
+               void AddMember (string name, MemberSpec member)
                {
-                       return List.Contains (value);
-               }
+                       IList<MemberSpec> list;
+                       if (!member_hash.TryGetValue (name, out list)) {
+                               member_hash.Add (name, new MemberSpec[] { member });
+                               return;
+                       }
 
-               public int IndexOf (MemberInfo value)
-               {
-                       return List.IndexOf (value);
-               }
+                       if (member.DeclaringType.IsInterface) {
+                               if (AddInterfaceMember (member, ref list))
+                                       member_hash[name] = list;
+                       } else {
+                               if (list is MemberSpec[]) {
+                                       list = new List<MemberSpec> () { list[0] };
+                                       member_hash[name] = list;
+                               }
 
-               public void Insert (int index, MemberInfo value)
-               {
-                       throw new NotSupportedException ();
+                               list.Add (member);
+                       }
                }
 
-               public bool Remove (MemberInfo value)
+               //
+               // Ignores any base interface member which can be hidden
+               // by this interface
+               //
+               static bool AddInterfaceMember (MemberSpec member, ref IList<MemberSpec> existing)
                {
-                       throw new NotSupportedException ();
-               }
+                       var member_param = member is IParametersMember ? ((IParametersMember) member).Parameters : ParametersCompiled.EmptyReadOnlyParameters;
 
-               public void RemoveAt (int index)
-               {
-                       throw new NotSupportedException ();
-               }
-       }
+                       //
+                       // interface IA : IB { int Prop { set; } }
+                       // interface IB { bool Prop { get; } }
+                       //
+                       // IB.Prop is never accessible from IA interface
+                       //
+                       for (int i = 0; i < existing.Count; ++i) {
+                               var entry = existing[i];
 
-       /// <summary>
-       ///   This interface is used to get all members of a class when creating the
-       ///   member cache.  It must be implemented by all DeclSpace derivatives which
-       ///   want to support the member cache and by TypeHandle to get caching of
-       ///   non-dynamic types.
-       /// </summary>
-       public interface IMemberContainer {
-               /// <summary>
-               ///   The name of the IMemberContainer.  This is only used for
-               ///   debugging purposes.
-               /// </summary>
-               string Name {
-                       get;
-               }
+                               if (entry.Arity != member.Arity)
+                                       continue;
 
-               /// <summary>
-               ///   The type of this IMemberContainer.
-               /// </summary>
-               Type Type {
-                       get;
-               }
+                               if (entry is IParametersMember) {
+                                       var entry_param = ((IParametersMember) entry).Parameters;
+                                       if (!TypeSpecComparer.Override.IsEqual (entry_param, member_param))
+                                               continue;
+                               }
 
-               /// <summary>
-               ///   Returns the IMemberContainer of the base class or null if this
-               ///   is an interface or TypeManger.object_type.
-               ///   This is used when creating the member cache for a class to get all
-               ///   members from the base class.
-               /// </summary>
-               MemberCache BaseCache {
-                       get;
-               }
+                               if (member.DeclaringType.ImplementsInterface (entry.DeclaringType)) {
+                                       if (existing is MemberSpec[]) {
+                                               existing = new MemberSpec[] { member };
+                                               return true;
+                                       }
 
-               /// <summary>
-               ///   Whether this is an interface.
-               /// </summary>
-               bool IsInterface {
-                       get;
-               }
+                                       existing.RemoveAt (i--);
+                                       continue;
+                               }
 
-               /// <summary>
-               ///   Returns all members of this class with the corresponding MemberTypes
-               ///   and BindingFlags.
-               /// </summary>
-               /// <remarks>
-               ///   When implementing this method, make sure not to return any inherited
-               ///   members and check the MemberTypes and BindingFlags properly.
-               ///   Unfortunately, System.Reflection is lame and doesn't provide a way to
-               ///   get the BindingFlags (static/non-static,public/non-public) in the
-               ///   MemberInfo class, but the cache needs this information.  That's why
-               ///   this method is called multiple times with different BindingFlags.
-               /// </remarks>
-               MemberList GetMembers (MemberTypes mt, BindingFlags bf);
-       }
+                               if (entry.DeclaringType == member.DeclaringType || entry.DeclaringType.ImplementsInterface (member.DeclaringType))
+                                       return false;
+                       }
 
-       /// <summary>
-       ///   The MemberCache is used by dynamic and non-dynamic types to speed up
-       ///   member lookups.  It has a member name based hash table; it maps each member
-       ///   name to a list of CacheEntry objects.  Each CacheEntry contains a MemberInfo
-       ///   and the BindingFlags that were initially used to get it.  The cache contains
-       ///   all members of the current class and all inherited members.  If this cache is
-       ///   for an interface types, it also contains all inherited members.
-       ///
-       ///   There are two ways to get a MemberCache:
-       ///   * if this is a dynamic type, lookup the corresponding DeclSpace and then
-       ///     use the DeclSpace.MemberCache property.
-       ///   * if this not a dynamic type, call TypeHandle.GetTypeHandle() to get a
-       ///     TypeHandle instance for the type and then use TypeHandle.MemberCache.
-       /// </summary>
-       public class MemberCache {
-               public readonly IMemberContainer Container;
-               protected Dictionary<string, List<CacheEntry>> member_hash;
-               protected Dictionary<string, List<CacheEntry>> method_hash;
+                       if (existing is MemberSpec[]) {
+                               existing = new List<MemberSpec> () { existing[0], member };
+                               return true;
+                       }
 
-               Dictionary<string, object> locase_table;
+                       existing.Add (member);
+                       return false;
+               }
 
-               static List<MethodInfo> overrides = new List<MethodInfo> ();
+               public static IEnumerable<IndexerSpec> FindIndexers (TypeSpec container, BindingRestriction restrictions)
+               {
+                       var filter = new MemberFilter (IndexerNameAlias, 0, MemberKind.Indexer, null, null);
+                       var found = FindMembers (container, filter, restrictions);
+                       return found == null ? null : found.Cast<IndexerSpec> ();
+               }
 
-               /// <summary>
-               ///   Create a new MemberCache for the given IMemberContainer `container'.
-               /// </summary>
-               public MemberCache (IMemberContainer container)
+               public static MemberSpec FindMember (TypeSpec container, MemberFilter filter, BindingRestriction restrictions)
                {
-                       this.Container = container;
+                       do {
+                               IList<MemberSpec> applicable;
+                               if (container.MemberCache.member_hash.TryGetValue (filter.Name, out applicable)) {
+                                       // Start from the end because interface members are in reverse order
+                                       for (int i = applicable.Count - 1; i >= 0; i--) {
+                                               var entry = applicable [i];
+
+                                               if ((restrictions & BindingRestriction.InstanceOnly) != 0 && entry.IsStatic)
+                                                       continue;
 
-                       Timer.IncrementCounter (CounterType.MemberCache);
-                       Timer.StartTimer (TimerType.CacheInit);
+                                               if (filter.Equals (entry))
+                                                       return entry;
 
-                       // If we have a base class (we have a base class unless we're
-                       // TypeManager.object_type), we deep-copy its MemberCache here.
-                       if (Container.BaseCache != null)
-                               member_hash = SetupCache (Container.BaseCache);
-                       else
-                               member_hash = new Dictionary<string, List<CacheEntry>> ();
-
-                       // If this is neither a dynamic type nor an interface, create a special
-                       // method cache with all declared and inherited methods.
-                       Type type = container.Type;
-                       if (!(type is TypeBuilder) && !type.IsInterface &&
-                           // !(type.IsGenericType && (type.GetGenericTypeDefinition () is TypeBuilder)) &&
-                           !TypeManager.IsGenericType (type) && !TypeManager.IsGenericParameter (type) &&
-                           (Container.BaseCache == null || Container.BaseCache.method_hash != null)) {
-                                       method_hash = new Dictionary<string, List<CacheEntry>> ();
-                                       AddMethods (type);
-                       }
+                                               // TODO MemberCache:
+                                               //if ((restrictions & BindingRestriction.AccessibleOnly) != 0)
+                                               //      throw new NotImplementedException ("net");
+                                       }
+                               }
 
-                       // Add all members from the current class.
-                       AddMembers (Container);
+                               container = container.BaseType;
+                       } while (container != null && (restrictions & BindingRestriction.DeclaredOnly) == 0);
 
-                       Timer.StopTimer (TimerType.CacheInit);
+                       return null;
                }
 
-               public MemberCache (Type baseType, IMemberContainer container)
+               //
+               // Returns the first set of members starting from container
+               //
+               public static IList<MemberSpec> FindMembers (TypeSpec container, MemberFilter filter, BindingRestriction restrictions)
                {
-                       this.Container = container;
-                       if (baseType == null)
-                               this.member_hash = new Dictionary<string, List<CacheEntry>> ();
-                       else
-                               this.member_hash = SetupCache (TypeManager.LookupMemberCache (baseType));
-               }
+                       IList<MemberSpec> applicable;
+                       IList<MemberSpec> found = null;
 
-               public MemberCache (Type[] ifaces)
-               {
-                       //
-                       // The members of this cache all belong to other caches.  
-                       // So, 'Container' will not be used.
-                       //
-                       this.Container = null;
+                       do {
+                               if (container.MemberCache.member_hash.TryGetValue (filter.Name, out applicable)) {
+                                       for (int i = 0; i < applicable.Count; ++i) {
+                                               var entry = applicable [i];
 
-                       member_hash = new Dictionary<string, List<CacheEntry>> ();
-                       if (ifaces == null)
-                               return;
+                                               // Is the member of the correct type
+                                               if ((entry.Kind & filter.Kind & MemberKind.MaskType) == 0)
+                                                       continue;
 
-                       foreach (Type itype in ifaces)
-                               AddCacheContents (TypeManager.LookupMemberCache (itype));
-               }
+                                               //
+                                               // When using overloadable overrides filter ignore members which
+                                               // are not base members. Including properties because overrides can
+                                               // implement get or set only and we are looking for complete base member
+                                               //
+                                               const MemberKind overloadable = MemberKind.Indexer | MemberKind.Method | MemberKind.Property;
+                                               if ((restrictions & BindingRestriction.NoOverrides) != 0 && (entry.Kind & overloadable) != 0) {
+                                                       if ((entry.Modifiers & Modifiers.OVERRIDE) != 0)
+                                                               continue;
 
-               public MemberCache (IMemberContainer container, Type base_class, Type[] ifaces)
-               {
-                       this.Container = container;
+                                                       if ((entry.Modifiers & Modifiers.OVERRIDE_UNCHECKED) != 0) {
+                                                               // TODO: Implement this correctly for accessors
+                                                               var ms = entry as MethodSpec;
+                                                               if (ms == null || IsRealMethodOverride (ms)) {
+                                                                       entry.Modifiers = (entry.Modifiers & ~Modifiers.OVERRIDE_UNCHECKED) | Modifiers.OVERRIDE;
+                                                                       continue;
+                                                               }
+                                                       }
+                                               }
 
-                       // If we have a base class (we have a base class unless we're
-                       // TypeManager.object_type), we deep-copy its MemberCache here.
-                       if (Container.BaseCache != null)
-                               member_hash = SetupCache (Container.BaseCache);
-                       else
-                               member_hash = new Dictionary<string, List<CacheEntry>> ();
-
-                       if (base_class != null)
-                               AddCacheContents (TypeManager.LookupMemberCache (base_class));
-                       if (ifaces != null) {
-                               foreach (Type itype in ifaces) {
-                                       MemberCache cache = TypeManager.LookupMemberCache (itype);
-                                       if (cache != null)
-                                               AddCacheContents (cache);
+                                               if ((restrictions & BindingRestriction.InstanceOnly) != 0 && entry.IsStatic)
+                                                       continue;
+
+                                               // Apply the filter to it.
+                                               if (!filter.Equals (entry))
+                                                       continue;
+
+                                               if (found == null) {
+                                                       if (i == 0) {
+                                                               found = applicable;
+                                                       } else {
+                                                               found = new List<MemberSpec> ();
+                                                               found.Add (entry);
+                                                       }
+                                               } else if (found == applicable) {
+                                                       found = new List<MemberSpec> ();
+                                                       found.Add (applicable[0]);
+                                                       found.Add (entry);
+                                               } else {
+                                                       found.Add (entry);
+                                               }
+                                       }
+
+                                       if (found != null) {
+                                               if (found == applicable && applicable.Count != 1)
+                                                       return new MemberSpec[] { found[0] };
+
+                                               return found;
+                                       }
                                }
-                       }
-               }
 
-               /// <summary>
-               ///   Bootstrap this member cache by doing a deep-copy of our base.
-               /// </summary>
-               static Dictionary<string, List<CacheEntry>> SetupCache (MemberCache base_class)
-               {
-                       if (base_class == null)
-                               return new Dictionary<string, List<CacheEntry>> ();
+                               container = container.BaseType;
+                       } while (container != null && (restrictions & BindingRestriction.DeclaredOnly) == 0);
 
-                       var hash = new Dictionary<string, List<CacheEntry>> (base_class.member_hash.Count);
-                       var it = base_class.member_hash.GetEnumerator ();
-                       while (it.MoveNext ()) {
-                               hash.Add (it.Current.Key, new List<CacheEntry> (it.Current.Value));
-                       }
-                                
-                       return hash;
+                       return found;
                }
-               
+
                //
-               // Converts ModFlags to BindingFlags
+               // Finds the nested type in container
                //
-               static BindingFlags GetBindingFlags (Modifiers modifiers)
+               public static TypeSpec FindNestedType (TypeSpec container, string name, int arity)
                {
-                       BindingFlags bf;
-                       if ((modifiers & Modifiers.STATIC) != 0)
-                               bf = BindingFlags.Static;
-                       else
-                               bf = BindingFlags.Instance;
-
-                       if ((modifiers & Modifiers.PRIVATE) != 0)
-                               bf |= BindingFlags.NonPublic;
-                       else
-                               bf |= BindingFlags.Public;
-
-                       return bf;
-               }               
-
-               /// <summary>
-               ///   Add the contents of `cache' to the member_hash.
-               /// </summary>
-               void AddCacheContents (MemberCache cache)
-               {
-                       var it = cache.member_hash.GetEnumerator ();
-                       while (it.MoveNext ()) {
-                               List<CacheEntry> list;
-                               if (!member_hash.TryGetValue (it.Current.Key, out list))
-                                       member_hash [it.Current.Key] = list = new List<CacheEntry> ();
+                       IList<MemberSpec> applicable;
+                       TypeSpec best_match = null;
+                       do {
+                               // TODO: Don't know how to handle this yet
+                               // When resolving base type of nested type, parent type must have
+                               // base type resolved to scan full hierarchy correctly
+                               // Similarly MemberCacheTypes will inflate BaseType and Interfaces
+                               // based on type definition
+                               var tc = container.MemberDefinition as TypeContainer;
+                               if (tc != null)
+                                       tc.DefineType ();
+
+                               if (container.MemberCacheTypes.member_hash.TryGetValue (name, out applicable)) {
+                                       for (int i = applicable.Count - 1; i >= 0; i--) {
+                                               var entry = applicable[i];
+                                               if ((entry.Kind & MemberKind.NestedMask) == 0)
+                                                       continue;
 
-                               var entries = it.Current.Value;
-                               for (int i = entries.Count-1; i >= 0; i--) {
-                                       var entry = entries [i];
+                                               var ts = (TypeSpec) entry;
+                                               if (arity == ts.Arity)
+                                                       return ts;
 
-                                       if (entry.Container != cache.Container)
-                                               break;
-                                       list.Add (entry);
+                                               if (arity < 0) {
+                                                       if (best_match == null) {
+                                                               best_match = ts;
+                                                       } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (ts.Arity + arity)) {
+                                                               best_match = ts;
+                                                       }
+                                               }
+                                       }
                                }
-                       }
-               }
 
-               /// <summary>
-               ///   Add all members from class `container' to the cache.
-               /// </summary>
-               void AddMembers (IMemberContainer container)
-               {
-                       // We need to call AddMembers() with a single member type at a time
-                       // to get the member type part of CacheEntry.EntryType right.
-                       if (!container.IsInterface) {
-                               AddMembers (MemberTypes.Constructor, container);
-                               AddMembers (MemberTypes.Field, container);
-                       }
-                       AddMembers (MemberTypes.Method, container);
-                       AddMembers (MemberTypes.Property, container);
-                       AddMembers (MemberTypes.Event, container);
-                       // Nested types are returned by both Static and Instance searches.
-                       AddMembers (MemberTypes.NestedType,
-                                   BindingFlags.Static | BindingFlags.Public, container);
-                       AddMembers (MemberTypes.NestedType,
-                                   BindingFlags.Static | BindingFlags.NonPublic, container);
-               }
+                               container = container.BaseType;
+                       } while (container != null);
 
-               void AddMembers (MemberTypes mt, IMemberContainer container)
-               {
-                       AddMembers (mt, BindingFlags.Static | BindingFlags.Public, container);
-                       AddMembers (mt, BindingFlags.Static | BindingFlags.NonPublic, container);
-                       AddMembers (mt, BindingFlags.Instance | BindingFlags.Public, container);
-                       AddMembers (mt, BindingFlags.Instance | BindingFlags.NonPublic, container);
+                       return best_match;
                }
 
-               public void AddMember (MemberInfo mi, MemberSpec mc)
+               //
+               // Looks for extension methods with defined name and extension type
+               //
+               public List<MethodSpec> FindExtensionMethods (TypeSpec invocationType, TypeSpec extensionType, string name, int arity)
                {
-                       AddMember (mi.MemberType, GetBindingFlags (mc.Modifiers), Container, mi.Name, mi);
-               }
+                       IList<MemberSpec> entries;
+                       if (!member_hash.TryGetValue (name, out entries))
+                               return null;
 
-               public void AddGenericMember (MemberInfo mi, InterfaceMemberBase mc)
-               {
-                       AddMember (mi.MemberType, GetBindingFlags (mc.ModFlags), Container,
-                               MemberName.MakeName (mc.GetFullName (mc.MemberName), mc.MemberName.TypeArguments), mi);
-               }
+                       List<MethodSpec> candidates = null;
+                       foreach (var entry in entries) {
+                               if (entry.Kind != MemberKind.Method || (arity >= 0 && entry.Arity != arity))
+                                       continue;
 
-               public void AddNestedType (DeclSpace type)
-               {
-                       AddMember (MemberTypes.NestedType, GetBindingFlags (type.ModFlags), (IMemberContainer) type.Parent,
-                               type.TypeBuilder.Name, type.TypeBuilder);
-               }
+                               var ms = (MethodSpec) entry;
+                               if (!ms.IsExtensionMethod)
+                                       continue;
 
-               public void AddInterface (MemberCache baseCache)
-               {
-                       if (baseCache.member_hash.Count > 0)
-                               AddCacheContents (baseCache);
-               }
+                               bool extra;
+                               if (!Expression.IsMemberAccessible (invocationType, ms, out extra))
+                                       continue;
 
-               void AddMember (MemberTypes mt, BindingFlags bf, IMemberContainer container,
-                               string name, MemberInfo member)
-               {
-                       // We use a name-based hash table of ArrayList's.
-                       List<CacheEntry> list;
-                       if (!member_hash.TryGetValue (name, out list)) {
-                               list = new List<CacheEntry> (1);
-                               member_hash.Add (name, list);
+                               // TODO: CodeGen.Assembly.Builder
+                               if ((ms.DeclaringType.Modifiers & Modifiers.INTERNAL) != 0 &&
+                                       !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, ms.Assembly))
+                                       continue;
+
+                               if (candidates == null)
+                                       candidates = new List<MethodSpec> ();
+                               candidates.Add (ms);
                        }
 
-                       // When this method is called for the current class, the list will
-                       // already contain all inherited members from our base classes.
-                       // We cannot add new members in front of the list since this'd be an
-                       // expensive operation, that's why the list is sorted in reverse order
-                       // (ie. members from the current class are coming last).
-                       list.Add (new CacheEntry (container, member, mt, bf));
+                       return candidates;
                }
 
-               /// <summary>
-               ///   Add all members from class `container' with the requested MemberTypes and
-               ///   BindingFlags to the cache.  This method is called multiple times with different
-               ///   MemberTypes and BindingFlags.
-               /// </summary>
-               void AddMembers (MemberTypes mt, BindingFlags bf, IMemberContainer container)
+               //
+               // Returns base members of @member member if no exact match is found @bestCandidate returns
+               // the best match
+               //
+               public static MemberSpec FindBaseMember (MemberCore member, out MemberSpec bestCandidate)
                {
-                       MemberList members = container.GetMembers (mt, bf);
+                       bestCandidate = null;
+                       var container = member.Parent.PartialContainer.Definition;
+                       if (!container.IsInterface)
+                               container = container.BaseType;
 
-                       foreach (MemberInfo member in members) {
-                               string name = member.Name;
+                       string name = GetLookupName (member);
+                       IList<MemberSpec> applicable;
+                       var member_param = member is IParametersMember ? ((IParametersMember) member).Parameters : null;
 
-                               AddMember (mt, bf, container, name, member);
+                       var mkind = GetMemberCoreKind (member);
 
-                               if (member is MethodInfo) {
-                                       string gname = TypeManager.GetMethodName ((MethodInfo) member);
-                                       if (gname != name)
-                                               AddMember (mt, bf, container, gname, member);
-                               }
-                       }
-               }
+                       do {
+                               if (container.MemberCache.member_hash.TryGetValue (name, out applicable)) {
+                                       for (int i = 0; i < applicable.Count; ++i) {
+                                               var entry = applicable [i];
 
-               /// <summary>
-               ///   Add all declared and inherited methods from class `type' to the method cache.
-               /// </summary>
-               void AddMethods (Type type)
-               {
-                       AddMethods (BindingFlags.Static | BindingFlags.Public |
-                                   BindingFlags.FlattenHierarchy, type);
-                       AddMethods (BindingFlags.Static | BindingFlags.NonPublic |
-                                   BindingFlags.FlattenHierarchy, type);
-                       AddMethods (BindingFlags.Instance | BindingFlags.Public, type);
-                       AddMethods (BindingFlags.Instance | BindingFlags.NonPublic, type);
-               }
+                                               if ((entry.Modifiers & Modifiers.PRIVATE) != 0)
+                                                       continue;
 
-               void AddMethods (BindingFlags bf, Type type)
-               {
-                       MethodBase [] members = type.GetMethods (bf);
+                                               if ((entry.Modifiers & Modifiers.AccessibilityMask) == Modifiers.INTERNAL) {
+                                                       if (!TypeManager.IsThisOrFriendAssembly (member.Assembly, entry.Assembly))
+                                                               continue;
+                                               }
+
+                                               // Is the member of the correct type ?
+                                               if ((entry.Kind & mkind & MemberKind.MaskType) == 0) {
+                                                       if (member_param == null || !(entry is IParametersMember)) {
+                                                               bestCandidate = entry;
+                                                               return null;
+                                                       }
 
-                        Array.Reverse (members);
+                                                       continue;
+                                               }
 
-                       foreach (MethodBase member in members) {
-                               string name = member.Name;
+                                               if (member_param == null)
+                                                       return entry;
 
-                               // We use a name-based hash table of ArrayList's.
-                               List<CacheEntry> list;
-                               if (!method_hash.TryGetValue (name, out list)) {
-                                       list = new List<CacheEntry> (1);
-                                       method_hash.Add (name, list);
-                               }
+                                               // Check arity match
+                                               int arity = member.MemberName.Arity;
+                                               if (arity != entry.Arity)
+                                                       continue;
 
-                               MethodInfo curr = (MethodInfo) member;
-                               while (curr.IsVirtual && (curr.Attributes & MethodAttributes.NewSlot) == 0) {
-                                       MethodInfo base_method = curr.GetBaseDefinition ();
+                                               if (entry is IParametersMember) {
+                                                       if (entry.IsAccessor != member is AbstractPropertyEventMethod)
+                                                               continue;
 
-                                       if (base_method == curr)
-                                               // Not every virtual function needs to have a NewSlot flag.
-                                               break;
+                                                       var entry_param = ((IParametersMember) entry).Parameters;
+                                                       if (TypeSpecComparer.Override.IsEqual (entry_param, member_param))
+                                                               return entry;
 
-                                       overrides.Add (curr);
-                                       list.Add (new CacheEntry (null, base_method, MemberTypes.Method, bf));
-                                       curr = base_method;
-                               }
+                                                       continue;
+                                               }
+
+                                               if (bestCandidate == null)
+                                                       bestCandidate = entry;
+                                       }
 
-                               if (overrides.Count > 0) {
-                                       for (int i = 0; i < overrides.Count; ++i)
-                                               TypeManager.RegisterOverride ((MethodBase) overrides [i], curr);
-                                       overrides.Clear ();
+                                       if (member_param == null)
+                                               return null;
                                }
 
-                               // Unfortunately, the elements returned by Type.GetMethods() aren't
-                               // sorted so we need to do this check for every member.
-                               BindingFlags new_bf = bf;
-                               if (member.DeclaringType == type)
-                                       new_bf |= BindingFlags.DeclaredOnly;
+                               if (container.IsInterface)
+                                       break;
 
-                               list.Add (new CacheEntry (Container, member, MemberTypes.Method, new_bf));
-                       }
-               }
+                               container = container.BaseType;
+                       } while (container != null);
 
-               /// <summary>
-               ///   Compute and return a appropriate `EntryType' magic number for the given
-               ///   MemberTypes and BindingFlags.
-               /// </summary>
-               protected static EntryType GetEntryType (MemberTypes mt, BindingFlags bf)
-               {
-                       EntryType type = EntryType.None;
-
-                       if ((mt & MemberTypes.Constructor) != 0)
-                               type |= EntryType.Constructor;
-                       if ((mt & MemberTypes.Event) != 0)
-                               type |= EntryType.Event;
-                       if ((mt & MemberTypes.Field) != 0)
-                               type |= EntryType.Field;
-                       if ((mt & MemberTypes.Method) != 0)
-                               type |= EntryType.Method;
-                       if ((mt & MemberTypes.Property) != 0)
-                               type |= EntryType.Property;
-                       // Nested types are returned by static and instance searches.
-                       if ((mt & MemberTypes.NestedType) != 0)
-                               type |= EntryType.NestedType | EntryType.Static | EntryType.Instance;
-
-                       if ((bf & BindingFlags.Instance) != 0)
-                               type |= EntryType.Instance;
-                       if ((bf & BindingFlags.Static) != 0)
-                               type |= EntryType.Static;
-                       if ((bf & BindingFlags.Public) != 0)
-                               type |= EntryType.Public;
-                       if ((bf & BindingFlags.NonPublic) != 0)
-                               type |= EntryType.NonPublic;
-                       if ((bf & BindingFlags.DeclaredOnly) != 0)
-                               type |= EntryType.Declared;
-
-                       return type;
+                       return null;
                }
 
-               /// <summary>
-               ///   The `MemberTypes' enumeration type is a [Flags] type which means that it may
-               ///   denote multiple member types.  Returns true if the given flags value denotes a
-               ///   single member types.
-               /// </summary>
-               public static bool IsSingleMemberType (MemberTypes mt)
+               //
+               // Returns inflated version of MemberSpec, it works similarly to
+               // SRE TypeBuilder.GetMethod
+               //
+               public static T GetMember<T> (TypeSpec container, T spec) where T : MemberSpec
                {
-                       switch (mt) {
-                       case MemberTypes.Constructor:
-                       case MemberTypes.Event:
-                       case MemberTypes.Field:
-                       case MemberTypes.Method:
-                       case MemberTypes.Property:
-                       case MemberTypes.NestedType:
-                               return true;
-
-                       default:
-                               return false;
+                       IList<MemberSpec> applicable;
+                       if (container.MemberCache.member_hash.TryGetValue (GetLookupName (spec), out applicable)) {
+                               for (int i = applicable.Count - 1; i >= 0; i--) {
+                                       var entry = applicable[i];
+                                       if (entry.MemberDefinition == spec.MemberDefinition)
+                                               return (T) entry;
+                               }
                        }
-               }
 
-               /// <summary>
-               ///   We encode the MemberTypes and BindingFlags of each members in a "magic"
-               ///   number to speed up the searching process.
-               /// </summary>
-               [Flags]
-               public enum EntryType {
-                       None            = 0x000,
-
-                       Instance        = 0x001,
-                       Static          = 0x002,
-                       MaskStatic      = Instance|Static,
-
-                       Public          = 0x004,
-                       NonPublic       = 0x008,
-                       MaskProtection  = Public|NonPublic,
+                       throw new InternalErrorException ("Missing member `{0}' on inflated type `{1}'",
+                               spec.GetSignatureForError (), container.GetSignatureForError ());
+               }
 
-                       Declared        = 0x010,
+               static MemberKind GetMemberCoreKind (MemberCore member)
+               {
+                       if (member is FieldBase)
+                               return MemberKind.Field;
+                       if (member is Indexer)
+                               return MemberKind.Indexer;
+                       if (member is Class)
+                               return MemberKind.Class;
+                       if (member is Struct)
+                               return MemberKind.Struct;
+                       if (member is Destructor)
+                               return MemberKind.Destructor;
+                       if (member is Method)
+                               return MemberKind.Method;
+                       if (member is Property)
+                               return MemberKind.Property;
+                       if (member is EventField)
+                               return MemberKind.Event;
+                       if (member is Interface)
+                               return MemberKind.Interface;
+                       if (member is EventProperty)
+                               return MemberKind.Event;
+
+                       throw new NotImplementedException (member.GetType ().ToString ());
+               }
 
-                       Constructor     = 0x020,
-                       Event           = 0x040,
-                       Field           = 0x080,
-                       Method          = 0x100,
-                       Property        = 0x200,
-                       NestedType      = 0x400,
+               public static IList<MemberSpec> GetCompletitionMembers (TypeSpec container, string name)
+               {
+                       var matches = new List<MemberSpec> ();
+                       foreach (var entry in container.MemberCache.member_hash) {
+                               foreach (var name_entry in entry.Value) {
+                                       if (name_entry.IsAccessor)
+                                               continue;
 
-                       NotExtensionMethod      = 0x800,
+                                       if ((name_entry.Kind & (MemberKind.Constructor | MemberKind.FakeMethod | MemberKind.Destructor)) != 0)
+                                               continue;
 
-                       MaskType        = Constructor|Event|Field|Method|Property|NestedType
-               }
+                                       bool extra;
+                                       if (!Expression.IsMemberAccessible (InternalType.FakeInternalType, name_entry, out extra))
+                                               continue;
 
-               public class CacheEntry {
-                       public readonly IMemberContainer Container;
-                       public EntryType EntryType;
-                       public readonly MemberInfo Member;
-
-                       public CacheEntry (IMemberContainer container, MemberInfo member,
-                                          MemberTypes mt, BindingFlags bf)
-                       {
-                               this.Container = container;
-                               this.Member = member;
-                               this.EntryType = GetEntryType (mt, bf);
+                                       if (name == null || name_entry.Name.StartsWith (name)) {
+                                               matches.Add (name_entry);
+                                       }
+                               }
                        }
 
-                       public override string ToString ()
-                       {
-                               return String.Format ("CacheEntry ({0}:{1}:{2})", Container.Name,
-                                                     EntryType, Member);
-                       }
+                       return matches;
                }
 
-               /// <summary>
-               ///   This is called each time we're walking up one level in the class hierarchy
-               ///   and checks whether we can abort the search since we've already found what
-               ///   we were looking for.
-               /// </summary>
-               protected bool DoneSearching (IList<MemberInfo> list)
+               //
+               // Returns members of @iface only, base members are ignored
+               //
+               public static IList<MethodSpec> GetInterfaceMembers (TypeSpec iface)
                {
                        //
-                       // We've found exactly one member in the current class and it's not
-                       // a method or constructor.
+                       // MemberCache flatten interfaces, therefore in cases like this one
+                       // 
+                       // interface IA : IB {}
+                       // interface IB { void Foo () }
                        //
-                       if (list.Count == 1 && !(list [0] is MethodBase))
-                               return true;
-
-                       //
-                       // Multiple properties: we query those just to find out the indexer
-                       // name
+                       // we would return Foo inside IA which is not expected in this case
                        //
-                       if ((list.Count > 0) && (list [0] is PropertyInfo))
-                               return true;
+                       var methods = new List<MethodSpec> ();
+                       foreach (var entry in iface.MemberCache.member_hash.Values) {
+                               foreach (var name_entry in entry) {
+                                       if (iface == name_entry.DeclaringType) {
+                                               if (name_entry.Kind == MemberKind.Method) {
+                                                       methods.Add ((MethodSpec) name_entry);
+                                               }
+                                       }
+                               }
+                       }
 
-                       return false;
+                       return methods;
                }
 
-               /// <summary>
-               ///   Looks up members with name `name'.  If you provide an optional
-               ///   filter function, it'll only be called with members matching the
-               ///   requested member name.
-               ///
-               ///   This method will try to use the cache to do the lookup if possible.
-               ///
-               ///   Unlike other FindMembers implementations, this method will always
-               ///   check all inherited members - even when called on an interface type.
-               ///
-               ///   If you know that you're only looking for methods, you should use
-               ///   MemberTypes.Method alone since this speeds up the lookup a bit.
-               ///   When doing a method-only search, it'll try to use a special method
-               ///   cache (unless it's a dynamic type or an interface) and the returned
-               ///   MemberInfo's will have the correct ReflectedType for inherited methods.
-               ///   The lookup process will automatically restart itself in method-only
-               ///   search mode if it discovers that it's about to return methods.
-               /// </summary>
-               List<MemberInfo> global = new List<MemberInfo> ();
-               bool using_global;
-               
-               static MemberInfo [] emptyMemberInfo = new MemberInfo [0];
-               
-               public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, string name,
-                                                 MemberFilter filter, object criteria)
+               public static IList<MethodSpec> GetNotImplementedAbstractMethods (TypeSpec type)
                {
-                       if (using_global)
-                               throw new Exception ();
-
-                       bool declared_only = (bf & BindingFlags.DeclaredOnly) != 0;
-                       bool method_search = mt == MemberTypes.Method;
-                       // If we have a method cache and we aren't already doing a method-only search,
-                       // then we restart a method search if the first match is a method.
-                       bool do_method_search = !method_search && (method_hash != null);
-
-                       List<CacheEntry> applicable;
-
-                       // If this is a method-only search, we try to use the method cache if
-                       // possible; a lookup in the method cache will return a MemberInfo with
-                       // the correct ReflectedType for inherited methods.
-                       
-                       if (method_search && (method_hash != null))
-                               method_hash.TryGetValue (name, out applicable);
-                       else
-                               member_hash.TryGetValue (name, out applicable);
-
-                       if (applicable == null)
-                               return emptyMemberInfo;
+                       if (type.MemberCache.missing_abstract != null)
+                               return type.MemberCache.missing_abstract;
+                               
+                       var abstract_methods = new List<MethodSpec> ();
+                       List<TypeSpec> hierarchy = null;
 
                        //
-                       // 32  slots gives 53 rss/54 size
-                       // 2/4 slots gives 55 rss
+                       // Stage 1: top-to-bottom scan for abstract members
                        //
-                       // Strange: from 25,000 calls, only 1,800
-                       // are above 2.  Why does this impact it?
-                       //
-                       global.Clear ();
-                       using_global = true;
-
-                       Timer.StartTimer (TimerType.CachedLookup);
-
-                       EntryType type = GetEntryType (mt, bf);
-
-                       IMemberContainer current = Container;
+                       var abstract_type = type;
+                       while (true) {
+                               foreach (var entry in abstract_type.MemberCache.member_hash) {
+                                       foreach (var name_entry in entry.Value) {
+                                               if ((name_entry.Modifiers & Modifiers.ABSTRACT) == 0)
+                                                       continue;
 
-                       bool do_interface_search = current.IsInterface;
+                                               if (name_entry.Kind != MemberKind.Method)
+                                                       continue;
 
-                       // `applicable' is a list of all members with the given member name `name'
-                       // in the current class and all its base classes.  The list is sorted in
-                       // reverse order due to the way how the cache is initialy created (to speed
-                       // things up, we're doing a deep-copy of our base).
+                                               abstract_methods.Add ((MethodSpec) name_entry);
+                                       }
+                               }
 
-                       for (int i = applicable.Count-1; i >= 0; i--) {
-                               CacheEntry entry = (CacheEntry) applicable [i];
+                               var base_type = abstract_type.BaseType;
+                               if (!base_type.IsAbstract)
+                                       break;
 
-                               // This happens each time we're walking one level up in the class
-                               // hierarchy.  If we're doing a DeclaredOnly search, we must abort
-                               // the first time this happens (this may already happen in the first
-                               // iteration of this loop if there are no members with the name we're
-                               // looking for in the current class).
-                               if (entry.Container != current) {
-                                       if (declared_only)
-                                               break;
+                               if (hierarchy == null)
+                                       hierarchy = new List<TypeSpec> ();
 
-                                       if (!do_interface_search && DoneSearching (global))
-                                               break;
+                               hierarchy.Add (abstract_type);
+                               abstract_type = base_type;
+                       }
 
-                                       current = entry.Container;
-                               }
+                       int not_implemented_count = abstract_methods.Count;
+                       if (not_implemented_count == 0 || hierarchy == null) {
+                               type.MemberCache.missing_abstract = abstract_methods;
+                               return type.MemberCache.missing_abstract;
+                       }
 
-                               // Is the member of the correct type ?
-                               if ((entry.EntryType & type & EntryType.MaskType) == 0)
+                       //
+                       // Stage 2: Remove already implemented methods
+                       //
+                       foreach (var type_up in hierarchy) {
+                               var members = type_up.MemberCache.member_hash;
+                               if (members.Count == 0)
                                        continue;
 
-                               // Is the member static/non-static ?
-                               if ((entry.EntryType & type & EntryType.MaskStatic) == 0)
-                                       continue;
+                               for (int i = 0; i < abstract_methods.Count; ++i) {
+                                       var candidate = abstract_methods [i];
+                                       if (candidate == null)
+                                               continue;
 
-                               // Apply the filter to it.
-                               if (filter (entry.Member, criteria)) {
-                                       if ((entry.EntryType & EntryType.MaskType) != EntryType.Method) {
-                                               do_method_search = false;
-                                       }
-                                       
-                                       // Because interfaces support multiple inheritance we have to be sure that
-                                       // base member is from same interface, so only top level member will be returned
-                                       if (do_interface_search && global.Count > 0) {
-                                               bool member_already_exists = false;
-
-                                               foreach (MemberInfo mi in global) {
-                                                       if (mi is MethodBase)
-                                                               continue;
+                                       IList<MemberSpec> applicable;
+                                       if (!members.TryGetValue (candidate.Name, out applicable))
+                                               continue;
 
-                                                       if (IsInterfaceBaseInterface (TypeManager.GetInterfaces (mi.DeclaringType), entry.Member.DeclaringType)) {
-                                                               member_already_exists = true;
-                                                               break;
-                                                       }
-                                               }
-                                               if (member_already_exists)
+                                       var filter = new MemberFilter (candidate);
+                                       foreach (var item in applicable) {
+                                               // TODO: Need to test what should happen for OVERRIDE_UNCHECKED
+                                               if ((item.Modifiers & (Modifiers.OVERRIDE | Modifiers.OVERRIDE_UNCHECKED | Modifiers.VIRTUAL)) == 0)
                                                        continue;
-                                       }
 
-                                       global.Add (entry.Member);
+                                               if (filter.Equals (item)) {
+                                                       --not_implemented_count;
+                                                       abstract_methods [i] = null;
+                                                       break;
+                                               }
+                                       }
                                }
                        }
 
-                       Timer.StopTimer (TimerType.CachedLookup);
+                       if (not_implemented_count == abstract_methods.Count) {
+                               type.MemberCache.missing_abstract = abstract_methods;
+                               return type.MemberCache.missing_abstract;
+                       }
 
-                       // If we have a method cache and we aren't already doing a method-only
-                       // search, we restart in method-only search mode if the first match is
-                       // a method.  This ensures that we return a MemberInfo with the correct
-                       // ReflectedType for inherited methods.
-                       if (do_method_search && (global.Count > 0)){
-                               using_global = false;
+                       var not_implemented = new MethodSpec[not_implemented_count];
+                       int counter = 0;
+                       foreach (var m in abstract_methods) {
+                               if (m == null)
+                                       continue;
 
-                               return FindMembers (MemberTypes.Method, bf, name, filter, criteria);
+                               not_implemented[counter++] = m;
                        }
 
-                       using_global = false;
-                       MemberInfo [] copy = new MemberInfo [global.Count];
-                       global.CopyTo (copy);
-                       return copy;
+                       type.MemberCache.missing_abstract = not_implemented;
+                       return type.MemberCache.missing_abstract;
                }
 
-               /// <summary>
-               /// Returns true if iterface exists in any base interfaces (ifaces)
-               /// </summary>
-               static bool IsInterfaceBaseInterface (Type[] ifaces, Type ifaceToFind)
+               static string GetLookupName (MemberSpec ms)
                {
-                       foreach (Type iface in ifaces) {
-                               if (iface == ifaceToFind)
-                                       return true;
+                       if (ms.Kind == MemberKind.Indexer)
+                               return IndexerNameAlias;
 
-                               Type[] base_ifaces = TypeManager.GetInterfaces (iface);
-                               if (base_ifaces.Length > 0 && IsInterfaceBaseInterface (base_ifaces, ifaceToFind))
-                                       return true;
-                       }
-                       return false;
-               }
-               
-               // find the nested type @name in @this.
-               public Type FindNestedType (string name)
-               {
-                       List<CacheEntry> applicable;
-                       if (!member_hash.TryGetValue (name, out applicable))
-                               return null;
-                       
-                       for (int i = applicable.Count-1; i >= 0; i--) {
-                               CacheEntry entry = applicable [i];
-                               if ((entry.EntryType & EntryType.NestedType & EntryType.MaskType) != 0)
-                                       return (Type) entry.Member;
+                       if (ms.Kind == MemberKind.Constructor) {
+                               if (ms.IsStatic)
+                                       return ConstructorInfo.TypeConstructorName;
+
+                               return ConstructorInfo.ConstructorName;
                        }
-                       
-                       return null;
+
+                       return ms.Name;
                }
 
-               public MemberInfo FindBaseEvent (Type invocation_type, string name)
+               static string GetLookupName (MemberCore mc)
                {
-                       List<CacheEntry> applicable;
-                       if (!member_hash.TryGetValue (name, out applicable))
-                               return null;
+                       if (mc is Indexer)
+                               return IndexerNameAlias;
 
-                       //
-                       // Walk the chain of events, starting from the top.
-                       //
-                       for (int i = applicable.Count - 1; i >= 0; i--) 
-                       {
-                               CacheEntry entry = applicable [i];
-                               if ((entry.EntryType & EntryType.Event) == 0)
-                                       continue;
-                               
-                               EventInfo ei = (EventInfo)entry.Member;
-                               return ei.GetAddMethod (true);
-                       }
+                       if (mc is Constructor)
+                               return ConstructorInfo.ConstructorName;
 
-                       return null;
+                       return mc.MemberName.Name;
                }
 
                //
-               // Looks for extension methods with defined name and extension type
+               // Inflates all member cache nested types
                //
-               public List<MethodSpec> FindExtensionMethods (Assembly thisAssembly, Type extensionType, string name, bool publicOnly)
+               public void InflateTypes (MemberCache inflated_cache, TypeParameterInflator inflator)
                {
-                       List<CacheEntry> entries;
-                       if (method_hash != null)
-                               method_hash.TryGetValue (name, out entries);
-                       else {
-                               member_hash.TryGetValue (name, out entries);
-                       }
-
-                       if (entries == null)
-                               return null;
-
-                       EntryType entry_type = EntryType.Static | EntryType.Method | EntryType.NotExtensionMethod;
-                       EntryType found_entry_type = entry_type & ~EntryType.NotExtensionMethod;
+                       foreach (var item in member_hash) {
+                               IList<MemberSpec> inflated_members = null;
+                               for (int i = 0; i < item.Value.Count; ++i ) {
+                                       var member = item.Value[i];
 
-                       List<MethodSpec> candidates = null;
-                       foreach (CacheEntry entry in entries) {
-                               if ((entry.EntryType & entry_type) == found_entry_type) {
-                                       MethodBase mb = (MethodBase)entry.Member;
-
-                                       // Simple accessibility check
-                                       if ((entry.EntryType & EntryType.Public) == 0 && publicOnly) {
-                                               MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
-                                               if (ma != MethodAttributes.Assembly && ma != MethodAttributes.FamORAssem)
-                                                       continue;
-                                               
-                                               if (!TypeManager.IsThisOrFriendAssembly (thisAssembly, mb.DeclaringType.Assembly))
-                                                       continue;
-                                       }
+                                       // FIXME: When inflating members refering nested types before they are inflated
+                                       if (member == null)
+                                               continue;
 
-                                       IMethodData md = TypeManager.GetMethod (mb);
-                                       AParametersCollection pd = md == null ?
-                                               TypeManager.GetParameterData (mb) : md.ParameterInfo;
+                                       if ((member.Kind & MemberKind.NestedMask) != 0 &&
+                                               (member.Modifiers & Modifiers.COMPILER_GENERATED) == 0) {
+                                               if (inflated_members == null) {
+                                                       inflated_members = new MemberSpec[item.Value.Count];
+                                                       inflated_cache.member_hash.Add (item.Key, inflated_members);
+                                               }
 
-                                       Type ex_type = pd.ExtensionMethodType;
-                                       if (ex_type == null) {
-                                               entry.EntryType |= EntryType.NotExtensionMethod;
-                                               continue;
+                                               inflated_members [i] = member.InflateMember (inflator);
                                        }
-
-                                       if (candidates == null)
-                                               candidates = new List<MethodSpec> (2);
-                                       candidates.Add (Import.CreateMethod (mb));
                                }
                        }
-
-                       return candidates;
                }
-               
-               //
-               // This finds the method or property for us to override. invocation_type is the type where
-               // the override is going to be declared, name is the name of the method/property, and
-               // param_types is the parameters, if any to the method or property
+
                //
-               // Because the MemberCache holds members from this class and all the base classes,
-               // we can avoid tons of reflection stuff.
+               // Inflates all open type members, requires InflateTypes to be called before
                //
-               public MemberInfo FindMemberToOverride (Type invocation_type, string name, AParametersCollection parameters, GenericMethod generic_method, bool is_property)
+               public void InflateMembers (MemberCache cacheToInflate, TypeSpec inflatedType, TypeParameterInflator inflator)
                {
-                       List<CacheEntry> applicable;
-                       if (method_hash != null && !is_property)
-                               method_hash.TryGetValue (name, out applicable);
-                       else
-                               member_hash.TryGetValue (name, out applicable);
-                       
-                       if (applicable == null)
-                               return null;
-                       //
-                       // Walk the chain of methods, starting from the top.
-                       //
-                       for (int i = applicable.Count - 1; i >= 0; i--) {
-                               CacheEntry entry = applicable [i];
-                               
-                               if ((entry.EntryType & (is_property ? (EntryType.Property | EntryType.Field) : EntryType.Method)) == 0)
-                                       continue;
+                       var inflated_member_hash = cacheToInflate.member_hash;
+                       Dictionary<MethodSpec, MethodSpec> accessor_relation = null;
+                       List<MemberSpec> accessor_members = null;
 
-                               PropertyInfo pi = null;
-                               MethodInfo mi = null;
-                               FieldInfo fi = null;
-                               AParametersCollection cmp_attrs;
-                               
-                               if (is_property) {
-                                       if ((entry.EntryType & EntryType.Field) != 0) {
-                                               fi = (FieldInfo)entry.Member;
-                                               cmp_attrs = ParametersCompiled.EmptyReadOnlyParameters;
-                                       } else {
-                                               pi = (PropertyInfo) entry.Member;
-                                               cmp_attrs = TypeManager.GetParameterData (pi);
-                                       }
-                               } else {
-                                       mi = (MethodInfo) entry.Member;
-                                       cmp_attrs = TypeManager.GetParameterData (mi);
-                               }
+                       foreach (var item in member_hash) {
+                               var members = item.Value;
+                               IList<MemberSpec> inflated_members = null;
+                               for (int i = 0; i < members.Count; ++i ) {
+                                       var member = members[i];
+
+                                       //
+                                       // All nested types have been inflated earlier except for
+                                       // compiler types which are created later and could miss InflateTypes
+                                       //
+                                       if ((member.Kind & MemberKind.NestedMask) != 0 &&
+                                               (member.Modifiers & Modifiers.COMPILER_GENERATED) == 0) {
+                                               if (inflated_members == null)
+                                                       inflated_members = inflated_member_hash[item.Key];
 
-                               if (fi != null) {
-                                       // TODO: Almost duplicate !
-                                       // Check visibility
-                                       switch (fi.Attributes & FieldAttributes.FieldAccessMask) {
-                                       case FieldAttributes.PrivateScope:
                                                continue;
-                                       case FieldAttributes.Private:
+                                       }
+
+                                       //
+                                       // Clone the container first
+                                       //
+                                       if (inflated_members == null) {
+                                               inflated_members = new MemberSpec [item.Value.Count];
+                                               inflated_member_hash.Add (item.Key, inflated_members);
+                                       }
+
+                                       var local_inflator = inflator;
+
+                                       if (member.DeclaringType != inflatedType) {
                                                //
-                                               // A private method is Ok if we are a nested subtype.
-                                               // The spec actually is not very clear about this, see bug 52458.
+                                               // Don't inflate non generic interface members
+                                               // merged into generic interface
                                                //
-                                               if (!invocation_type.Equals (entry.Container.Type) &&
-                                                   !TypeManager.IsNestedChildOf (invocation_type, entry.Container.Type))
+                                               if (!member.DeclaringType.IsGeneric) {
+                                                       inflated_members [i] = member;
                                                        continue;
-                                               break;
-                                       case FieldAttributes.FamANDAssem:
-                                       case FieldAttributes.Assembly:
+                                               }
+
                                                //
-                                               // Check for assembly methods
+                                               // Needed when inflating flatten interfaces. It inflates
+                                               // container type only, type parameters are already done
                                                //
-                                               if (fi.DeclaringType.Assembly != CodeGen.Assembly.Builder)
-                                                       continue;
-                                               break;
+                                               // Handles cases like:
+                                               //
+                                               // interface I<T> {}
+                                               // interface I<U, V> : I<U> {}
+                                               // 
+                                               // class C: I<int, bool> {}
+                                               //
+                                               var inflated_parent = inflator.Inflate (member.DeclaringType);
+                                               if (inflated_parent != inflator.TypeInstance)
+                                                       local_inflator = new TypeParameterInflator (inflator, inflated_parent);
                                        }
-                                       return entry.Member;
-                               }
 
-                               //
-                               // Check the arguments
-                               //
-                               if (cmp_attrs.Count != parameters.Count)
-                                       continue;
-       
-                               int j;
-                               for (j = 0; j < cmp_attrs.Count; ++j) {
                                        //
-                                       // LAMESPEC: No idea why `params' modifier is ignored
+                                       // Inflate every member, its parent is now different
                                        //
-                                       if ((parameters.FixedParameters [j].ModFlags & ~Parameter.Modifier.PARAMS) != 
-                                               (cmp_attrs.FixedParameters [j].ModFlags & ~Parameter.Modifier.PARAMS))
-                                               break;
-
-                                       if (!TypeManager.IsEqual (parameters.Types [j], cmp_attrs.Types [j]))
-                                               break;
-                               }
+                                       var inflated = member.InflateMember (local_inflator);
+                                       inflated_members [i] = inflated;
 
-                               if (j < cmp_attrs.Count)
-                                       continue;
+                                       if (member is PropertySpec || member is EventSpec) {
+                                               if (accessor_members == null)
+                                                       accessor_members = new List<MemberSpec> ();
 
-                               //
-                               // check generic arguments for methods
-                               //
-                               if (mi != null) {
-                                       Type [] cmpGenArgs = TypeManager.GetGenericArguments (mi);
-                                       if (generic_method == null && cmpGenArgs != null && cmpGenArgs.Length != 0)
-                                               continue;
-                                       if (generic_method != null && cmpGenArgs != null && cmpGenArgs.Length != generic_method.TypeParameters.Length)
+                                               accessor_members.Add (inflated);
                                                continue;
-                               }
+                                       }
 
-                               //
-                               // get one of the methods because this has the visibility info.
-                               //
-                               if (is_property) {
-                                       mi = pi.GetGetMethod (true);
-                                       if (mi == null)
-                                               mi = pi.GetSetMethod (true);
+                                       if (member.IsAccessor) {
+                                               if (accessor_relation == null)
+                                                       accessor_relation = new Dictionary<MethodSpec, MethodSpec> ();
+                                               accessor_relation.Add ((MethodSpec) member, (MethodSpec) inflated);
+                                       }
                                }
-                               
-                               //
-                               // Check visibility
-                               //
-                               switch (mi.Attributes & MethodAttributes.MemberAccessMask) {
-                               case MethodAttributes.PrivateScope:
-                                       continue;
-                               case MethodAttributes.Private:
-                                       //
-                                       // A private method is Ok if we are a nested subtype.
-                                       // The spec actually is not very clear about this, see bug 52458.
-                                       //
-                                       if (!invocation_type.Equals (entry.Container.Type) &&
-                                           !TypeManager.IsNestedChildOf (invocation_type, entry.Container.Type))
-                                               continue;
-                                       break;
-                               case MethodAttributes.FamANDAssem:
-                               case MethodAttributes.Assembly:
-                                       //
-                                       // Check for assembly methods
-                                       //
-                                       if (!TypeManager.IsThisOrFriendAssembly (invocation_type.Assembly, mi.DeclaringType.Assembly))
+                       }
+
+                       if (accessor_members != null) {
+                               foreach (var member in accessor_members) {
+                                       var prop = member as PropertySpec;
+                                       if (prop != null) {
+                                               if (prop.Get != null)
+                                                       prop.Get = accessor_relation[prop.Get];
+                                               if (prop.Set != null)
+                                                       prop.Set = accessor_relation[prop.Set];
+
                                                continue;
-                                       break;
+                                       }
+
+                                       var ev = (EventSpec) member;
+                                       ev.AccessorAdd = accessor_relation[ev.AccessorAdd];
+                                       ev.AccessorRemove = accessor_relation[ev.AccessorRemove];
                                }
-                               return entry.Member;
                        }
-                       
-                       return null;
                }
 
-               /// <summary>
-               /// The method is looking for conflict with inherited symbols (errors CS0108, CS0109).
-               /// We handle two cases. The first is for types without parameters (events, field, properties).
-               /// The second are methods, indexers and this is why ignore_complex_types is here.
-               /// The latest param is temporary hack. See DoDefineMembers method for more info.
-               /// </summary>
-               public MemberInfo FindMemberWithSameName (string name, bool ignore_complex_types, MemberInfo ignore_member)
-               {
-                       List<CacheEntry> applicable = null;
-                       if (method_hash != null)
-                               method_hash.TryGetValue (name, out applicable);
-                       if (applicable != null) {
-                               for (int i = applicable.Count - 1; i >= 0; i--) {
-                                       CacheEntry entry = (CacheEntry) applicable [i];
-                                       if ((entry.EntryType & EntryType.Public) != 0)
-                                               return entry.Member;
-                               }
-                       }
-                       if (member_hash == null)
-                               return null;
-
-                       if (member_hash.TryGetValue (name, out applicable)) {
-                               for (int i = applicable.Count - 1; i >= 0; i--) {
-                                       CacheEntry entry = (CacheEntry) applicable [i];
-                                       if ((entry.EntryType & EntryType.Public) != 0 & entry.Member != ignore_member) {
-                                               if (ignore_complex_types) {
-                                                       if ((entry.EntryType & EntryType.Method) != 0)
-                                                               continue;
-                                                       // Does exist easier way how to detect indexer ?
-                                                       if ((entry.EntryType & EntryType.Property) != 0) {
-                                                               AParametersCollection arg_types = TypeManager.GetParameterData ((PropertyInfo)entry.Member);
-                                                               if (arg_types.Count > 0)
-                                                                       continue;
-                                                       }
-                                               }
-                                               return entry.Member;
-                                       }
-                               }
-                       }
-                       return null;
-               }
-
-
-               /// <summary>
-               /// Builds low-case table for CLS Compliance test
-               /// </summary>
-               public Dictionary<string, object> GetPublicMembers ()
-               {
-                       if (locase_table != null)
-                               return locase_table;
-
-                       locase_table = new Dictionary<string, object> ();
-                       foreach (var entry in member_hash) {
-                               var members = entry.Value;
-                               for (int ii = 0; ii < members.Count; ++ii) {
-                                       CacheEntry member_entry = members [ii];
-                                       if ((member_entry.EntryType & EntryType.Public) == 0)
-                                               continue;
-                                       // TODO: Does anyone know easier way how to detect that member is internal ?
-                                       switch (member_entry.EntryType & EntryType.MaskType) {
-                                       case EntryType.Constructor:
-                                               continue;
-                                               
-                                       case EntryType.Field:
-                                               if ((((FieldInfo)member_entry.Member).Attributes & (FieldAttributes.Assembly | FieldAttributes.Public)) == FieldAttributes.Assembly)
-                                                       continue;
-                                               break;
-                                               
-                                       case EntryType.Method:
-                                               if ((((MethodInfo)member_entry.Member).Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly)
+               //
+               // For imported class method do additional validation to be sure that metadata
+               // override flag was correct
+               //
+               static bool IsRealMethodOverride (MethodSpec ms)
+               {
+                       IList<MemberSpec> candidates;
+                       var dt = ms.DeclaringType;
+                       while (dt.BaseType != null) {
+                               var base_cache = dt.BaseType.MemberCache;
+                               if (base_cache.member_hash.TryGetValue (ms.Name, out candidates)) {
+                                       foreach (var candidate in candidates) {
+                                               if (candidate.Kind != ms.Kind)
                                                        continue;
-                                               break;
-                                               
-                                       case EntryType.Property:
-                                               PropertyInfo pi = (PropertyInfo)member_entry.Member;
-                                               if (pi.GetSetMethod () == null && pi.GetGetMethod () == null)
+
+                                               if (candidate.Arity != ms.Arity)
                                                        continue;
-                                               break;
-                                               
-                                       case EntryType.Event:
-                                               EventInfo ei = (EventInfo)member_entry.Member;
-                                               MethodInfo mi = ei.GetAddMethod ();
-                                               if ((mi.Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly)
+
+                                               if (!TypeSpecComparer.Override.IsEqual (((MethodSpec) candidate).Parameters, ms.Parameters))
                                                        continue;
-                                               break;
-                                       }
-                                       string lcase = ((string)entry.Key).ToLower (System.Globalization.CultureInfo.InvariantCulture);
-                                       locase_table [lcase] = member_entry.Member;
-                                       break;
-                               }
-                       }
-                       return locase_table;
-               }
-               public IDictionary<string, List<CacheEntry>> Members {
-                       get {
-                               return member_hash;
-                       }
-               }
-               /// <summary>
-               /// Cls compliance check whether methods or constructors parameters differing only in ref or out, or in array rank
-               /// </summary>
-               /// 
-               // TODO: refactor as method is always 'this'
-               public static void VerifyClsParameterConflict (IList<CacheEntry> al, MethodCore method, MemberInfo this_builder, Report Report)
-               {
-                       EntryType tested_type = (method is Constructor ? EntryType.Constructor : EntryType.Method) | EntryType.Public;
-                       for (int i = 0; i < al.Count; ++i) {
-                               var entry = al [i];
-               
-                               // skip itself
-                               if (entry.Member == this_builder)
-                                       continue;
-               
-                               if ((entry.EntryType & tested_type) != tested_type)
-                                       continue;
-               
-                               MethodBase method_to_compare = (MethodBase)entry.Member;
-                               AttributeTester.Result result = AttributeTester.AreOverloadedMethodParamsClsCompliant (
-                                       method.Parameters, TypeManager.GetParameterData (method_to_compare));
-
-                               if (result == AttributeTester.Result.Ok)
-                                       continue;
-
-                               IMethodData md = TypeManager.GetMethod (method_to_compare);
-
-                               // TODO: now we are ignoring CLSCompliance(false) on method from other assembly which is buggy.
-                               // However it is exactly what csc does.
-                               if (md != null && !md.IsClsComplianceRequired ())
-                                       continue;
-               
-                               Report.SymbolRelatedToPreviousError (entry.Member);
-                               switch (result) {
-                               case AttributeTester.Result.RefOutArrayError:
-                                       Report.Warning (3006, 1, method.Location,
-                                                       "Overloaded method `{0}' differing only in ref or out, or in array rank, is not CLS-compliant",
-                                                       method.GetSignatureForError ());
-                                       continue;
-                               case AttributeTester.Result.ArrayArrayError:
-                                       Report.Warning (3007, 1, method.Location,
-                                                       "Overloaded method `{0}' differing only by unnamed array types is not CLS-compliant",
-                                                       method.GetSignatureForError ());
-                                       continue;
+
+                                               // Everything matches except modifiers, it's not correct soverride
+                                               if ((candidate.Modifiers & Modifiers.AccessibilityMask) != (ms.Modifiers & Modifiers.AccessibilityMask))
+                                                       return false;
+
+                                               return true;
+                                       }
                                }
 
-                               throw new NotImplementedException (result.ToString ());
-                       }
-               }
+                               dt = dt.BaseType;
+                       }
 
-               public bool CheckExistingMembersOverloads (MemberCore member, string name, ParametersCompiled parameters, Report Report)
+                       return false;
+               }
+
+               //
+               // Checks all appropriate container members for CLS compliance
+               //
+               public void VerifyClsCompliance (TypeSpec container, Report report)
                {
-                       List<CacheEntry> entries;
-                       if (!member_hash.TryGetValue (name, out entries))
-                               return true;
+                       if (locase_members != null)
+                               return;
 
-                       int method_param_count = parameters.Count;
-                       for (int i = entries.Count - 1; i >= 0; --i) {
-                               CacheEntry ce = (CacheEntry) entries [i];
+                       if (container.BaseType == null) {
+                               locase_members = new Dictionary<string, MemberSpec[]> (member_hash.Count); // StringComparer.OrdinalIgnoreCase);
+                       } else {
+                               container.BaseType.MemberCache.VerifyClsCompliance (container.BaseType, report);
+                               locase_members = new Dictionary<string, MemberSpec[]> (container.BaseType.MemberCache.locase_members); //, StringComparer.OrdinalIgnoreCase);
+                       }
 
-                               if (ce.Container != member.Parent.PartialContainer)
-                                       return true;
+                       var is_imported_type = container.MemberDefinition.IsImported;
+                       foreach (var entry in container.MemberCache.member_hash) {
+                               for (int i = 0; i < entry.Value.Count; ++i ) {
+                                       var name_entry = entry.Value[i];
+                                       if ((name_entry.Modifiers & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
+                                               continue;
 
-                               Type [] p_types;
-                               AParametersCollection pd;
-                               if ((ce.EntryType & EntryType.Property) != 0) {
-                                       pd = TypeManager.GetParameterData ((PropertyInfo) ce.Member);
-                                       p_types = pd.Types;
-                               } else {
-                                       MethodBase mb = (MethodBase) ce.Member;
-               
-                                       // TODO: This is more like a hack, because we are adding generic methods
-                                       // twice with and without arity name
-                                       if (TypeManager.IsGenericMethod (mb) && !member.MemberName.IsGeneric)
+                                       if ((name_entry.Modifiers & (Modifiers.OVERRIDE | Modifiers.COMPILER_GENERATED)) != 0)
                                                continue;
 
-                                       pd = TypeManager.GetParameterData (mb);
-                                       p_types = pd.Types;
+                                       if ((name_entry.Kind & MemberKind.MaskType) == 0)
+                                               continue;
+
+                                       if (name_entry.MemberDefinition.IsNotCLSCompliant ())
+                                           continue;
+
+                                       IParametersMember p_a = name_entry as IParametersMember;
+                                       if (p_a != null && !name_entry.IsAccessor) {
+                                               if (!is_imported_type) {
+                                                       var p_a_pd = p_a.Parameters;
+                                                       for (int ii = i + 1; ii < entry.Value.Count; ++ii) {
+                                                               var checked_entry = entry.Value[ii];
+                                                               IParametersMember p_b = checked_entry as IParametersMember;
+                                                               if (p_b == null)
+                                                                       continue;
+
+                                                               if (p_a_pd.Count != p_b.Parameters.Count)
+                                                                       continue;
+
+                                                               if (checked_entry.IsAccessor)
+                                                                       continue;
+
+                                                               var res = ParametersCompiled.IsSameClsSignature (p_a.Parameters, p_b.Parameters);
+                                                               if (res != 0) {
+                                                                       var last = GetLaterDefinedMember (checked_entry, name_entry);
+                                                                       if (last == checked_entry.MemberDefinition) {
+                                                                               report.SymbolRelatedToPreviousError (name_entry);
+                                                                       } else {
+                                                                               report.SymbolRelatedToPreviousError (checked_entry);
+                                                                       }
+
+                                                                       if ((res & 1) != 0) {
+                                                                               report.Warning (3006, 1, last.Location,
+                                                                                               "Overloaded method `{0}' differing only in ref or out, or in array rank, is not CLS-compliant",
+                                                                                               name_entry.GetSignatureForError ());
+                                                                       }
+
+                                                                       if ((res & 2) != 0) {
+                                                                               report.Warning (3007, 1, last.Location,
+                                                                                       "Overloaded method `{0}' differing only by unnamed array types is not CLS-compliant",
+                                                                                       name_entry.GetSignatureForError ());
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+
+                                       if (i > 0 || name_entry.Kind == MemberKind.Constructor || name_entry.Kind == MemberKind.Indexer)
+                                               continue;
+
+                                       var name_entry_locase = name_entry.Name.ToLowerInvariant ();
+
+                                       MemberSpec[] found;
+                                       if (!locase_members.TryGetValue (name_entry_locase, out found)) {
+                                               found = new MemberSpec[] { name_entry };
+                                               locase_members.Add (name_entry_locase, found);
+                                       } else {
+                                               bool same_names_only = true;
+                                               foreach (var f in found) {
+                                                       if (f.Name == name_entry.Name)
+                                                               continue;
+
+//                                                     if (f.IsAccessor && name_entry.IsAccessor)
+//                                                             continue;
+
+                                                       same_names_only = false;
+                                                       if (!is_imported_type) {
+                                                               var last = GetLaterDefinedMember (f, name_entry);
+                                                               if (last == f.MemberDefinition) {
+                                                                       report.SymbolRelatedToPreviousError (name_entry);
+                                                               } else {
+                                                                       report.SymbolRelatedToPreviousError (f);
+                                                               }
+
+                                                               report.Warning (3005, 1, last.Location,
+                                                                       "Identifier `{0}' differing only in case is not CLS-compliant", last.GetSignatureForError ());
+                                                       }
+                                               }
+
+                                               if (!same_names_only) {
+                                                       Array.Resize (ref found, found.Length + 1);
+                                                       found[found.Length - 1] = name_entry;
+                                                       locase_members[name_entry_locase] = found;
+                                               }
+                                       }
                                }
+                       }
+               }
 
-                               if (p_types.Length != method_param_count)
+               //
+               // Local report helper to issue correctly ordered members stored in hashtable
+               //
+               static MemberCore GetLaterDefinedMember (MemberSpec a, MemberSpec b)
+               {
+                       var mc_a = a.MemberDefinition as MemberCore;
+                       var mc_b = b.MemberDefinition as MemberCore;
+                       if (mc_a == null)
+                               return mc_b;
+
+                       if (mc_b == null)
+                               return mc_a;
+
+                       if (mc_a.Location.File != mc_a.Location.File)
+                               return mc_b;
+
+                       return mc_b.Location.Row > mc_a.Location.Row ? mc_b : mc_a;
+               }
+
+               public bool CheckExistingMembersOverloads (MemberCore member, AParametersCollection parameters)
+               {
+                       var name = GetLookupName (member);
+                       var imb = member as InterfaceMemberBase;
+                       if (imb != null && imb.IsExplicitImpl) {
+                               name = imb.GetFullName (name);
+                       }
+
+                       return CheckExistingMembersOverloads (member, name, parameters);
+               }
+
+               public bool CheckExistingMembersOverloads (MemberCore member, string name, AParametersCollection parameters)
+               {
+                       IList<MemberSpec> entries;
+                       if (!member_hash.TryGetValue (name, out entries))
+                               return false;
+
+                       var Report = member.Compiler.Report;
+
+                       int method_param_count = parameters.Count;
+                       for (int i = entries.Count - 1; i >= 0; --i) {
+                               var ce = entries[i];
+                               var pm = ce as IParametersMember;
+                               var pd = pm == null ? ParametersCompiled.EmptyReadOnlyParameters : pm.Parameters;
+                               if (pd.Count != method_param_count)
+                                       continue;
+
+                               if (ce.Arity != member.MemberName.Arity)
                                        continue;
 
+                               // Ignore merged interface members
+                               if (member.Parent.PartialContainer != ce.DeclaringType.MemberDefinition)
+                                       continue;
+
+                               var p_types = pd.Types;
                                if (method_param_count > 0) {
                                        int ii = method_param_count - 1;
-                                       Type type_a, type_b;
+                                       TypeSpec type_a, type_b;
                                        do {
                                                type_a = parameters.Types [ii];
                                                type_b = p_types [ii];
 
-                                               if (TypeManager.IsGenericParameter (type_a) && type_a.DeclaringMethod != null)
-                                                       type_a = typeof (TypeParameter);
-
-                                               if (TypeManager.IsGenericParameter (type_b) && type_b.DeclaringMethod != null)
-                                                       type_b = typeof (TypeParameter);
-
                                                if ((pd.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF) !=
                                                        (parameters.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF))
                                                        break;
 
-                                       } while (TypeManager.IsEqual (type_a, type_b) && ii-- != 0);
+                                       } while (TypeSpecComparer.Override.IsEqual (type_a, type_b) && ii-- != 0);
 
                                        if (ii >= 0)
                                                continue;
@@ -1389,24 +1184,21 @@ namespace Mono.CSharp {
                                        //
                                        // Operators can differ in return type only
                                        //
-                                       if (member is Operator) {
-                                               Operator op = TypeManager.GetMethod ((MethodBase) ce.Member) as Operator;
-                                               if (op != null && op.ReturnType != ((Operator) member).ReturnType)
-                                                       continue;
-                                       }
+                                       if (member is Operator && ce.Kind == MemberKind.Operator && ((MethodSpec) ce).ReturnType != ((Operator) member).ReturnType)
+                                               continue;
 
                                        //
                                        // Report difference in parameter modifiers only
                                        //
                                        if (pd != null && member is MethodCore) {
                                                ii = method_param_count;
-                                               while (ii-- != 0 && parameters.FixedParameters [ii].ModFlags == pd.FixedParameters [ii].ModFlags &&
-                                                       parameters.ExtensionMethodType == pd.ExtensionMethodType);
+                                               while (ii-- != 0 && parameters.FixedParameters[ii].ModFlags == pd.FixedParameters[ii].ModFlags &&
+                                                       parameters.ExtensionMethodType == pd.ExtensionMethodType) ;
 
                                                if (ii >= 0) {
-                                                       MethodCore mc = TypeManager.GetMethod ((MethodBase) ce.Member) as MethodCore;
-                                                       Report.SymbolRelatedToPreviousError (ce.Member);
-                                                       if ((member.ModFlags & Modifiers.PARTIAL) != 0 && (mc.ModFlags & Modifiers.PARTIAL) != 0) {
+                                                       var mc = ce as MethodSpec;
+                                                       member.Compiler.Report.SymbolRelatedToPreviousError (ce);
+                                                       if ((member.ModFlags & Modifiers.PARTIAL) != 0 && (mc.Modifiers & Modifiers.PARTIAL) != 0) {
                                                                if (parameters.HasParams || pd.HasParams) {
                                                                        Report.Error (758, member.Location,
                                                                                "A partial method declaration and partial method implementation cannot differ on use of `params' modifier");
@@ -1414,25 +1206,23 @@ namespace Mono.CSharp {
                                                                        Report.Error (755, member.Location,
                                                                                "A partial method declaration and partial method implementation must be both an extension method or neither");
                                                                }
+                                                       } else if (member is Constructor) {
+                                                               Report.Error (851, member.Location,
+                                                                       "Overloaded contructor `{0}' cannot differ on use of parameter modifiers only",
+                                                                       member.GetSignatureForError ());
                                                        } else {
-                                                               if (member is Constructor) {
-                                                                       Report.Error (851, member.Location,
-                                                                               "Overloaded contructor `{0}' cannot differ on use of parameter modifiers only",
-                                                                               member.GetSignatureForError ());
-                                                               } else {
-                                                                       Report.Error (663, member.Location,
-                                                                               "Overloaded method `{0}' cannot differ on use of parameter modifiers only",
-                                                                               member.GetSignatureForError ());
-                                                               }
+                                                               Report.Error (663, member.Location,
+                                                                       "Overloaded method `{0}' cannot differ on use of parameter modifiers only",
+                                                                       member.GetSignatureForError ());
                                                        }
                                                        return false;
                                                }
                                        }
                                }
 
-                               if ((ce.EntryType & EntryType.Method) != 0) {
+                               if ((ce.Kind & (MemberKind.Method | MemberKind.FakeMethod)) != 0) {
                                        Method method_a = member as Method;
-                                       Method method_b = TypeManager.GetMethod ((MethodBase) ce.Member) as Method;
+                                       Method method_b = ce.MemberDefinition as Method;
                                        if (method_a != null && method_b != null && (method_a.ModFlags & method_b.ModFlags & Modifiers.PARTIAL) != 0) {
                                                const Modifiers partial_modifiers = Modifiers.STATIC | Modifiers.UNSAFE;
                                                if (method_a.IsPartialDefinition == method_b.IsPartialImplementation) {
@@ -1440,7 +1230,10 @@ namespace Mono.CSharp {
                                                                method_a.Parent.IsUnsafe && method_b.Parent.IsUnsafe) {
                                                                if (method_a.IsPartialImplementation) {
                                                                        method_a.SetPartialDefinition (method_b);
-                                                                       entries.RemoveAt (i);
+                                                                       if (entries.Count == 1)
+                                                                               member_hash.Remove (name);
+                                                                       else
+                                                                               entries.RemoveAt (i);
                                                                } else {
                                                                        method_b.SetPartialDefinition (method_a);
                                                                        method_a.caching_flags |= MemberCore.Flags.PartialDefinitionExists;
@@ -1448,52 +1241,51 @@ namespace Mono.CSharp {
                                                                continue;
                                                        }
 
-                                                       if ((method_a.ModFlags & Modifiers.STATIC) != (method_b.ModFlags & Modifiers.STATIC)) {
-                                                               Report.SymbolRelatedToPreviousError (ce.Member);
+                                                       if (method_a.IsStatic != method_b.IsStatic) {
+                                                               Report.SymbolRelatedToPreviousError (ce);
                                                                Report.Error (763, member.Location,
                                                                        "A partial method declaration and partial method implementation must be both `static' or neither");
                                                        }
 
-                                                       Report.SymbolRelatedToPreviousError (ce.Member);
+                                                       Report.SymbolRelatedToPreviousError (ce);
                                                        Report.Error (764, member.Location,
                                                                "A partial method declaration and partial method implementation must be both `unsafe' or neither");
                                                        return false;
                                                }
 
-                                               Report.SymbolRelatedToPreviousError (ce.Member);
+                                               Report.SymbolRelatedToPreviousError (ce);
                                                if (method_a.IsPartialDefinition) {
                                                        Report.Error (756, member.Location, "A partial method `{0}' declaration is already defined",
                                                                member.GetSignatureForError ());
-                                               } else {
-                                                       Report.Error (757, member.Location, "A partial method `{0}' implementation is already defined",
-                                                               member.GetSignatureForError ());
                                                }
 
+                                               Report.Error (757, member.Location, "A partial method `{0}' implementation is already defined",
+                                                       member.GetSignatureForError ());
                                                return false;
                                        }
 
-                                       Report.SymbolRelatedToPreviousError (ce.Member);
-                                       IMethodData duplicate_member = TypeManager.GetMethod ((MethodBase) ce.Member);
-                                       if (member is Operator && duplicate_member is Operator) {
-                                               Report.Error (557, member.Location, "Duplicate user-defined conversion in type `{0}'",
-                                                       member.Parent.GetSignatureForError ());
-                                               return false;
-                                       }
+                                       Report.SymbolRelatedToPreviousError (ce);
 
                                        bool is_reserved_a = member is AbstractPropertyEventMethod || member is Operator;
-                                       bool is_reserved_b = duplicate_member is AbstractPropertyEventMethod || duplicate_member is Operator;
+                                       bool is_reserved_b = ((MethodSpec) ce).IsReservedMethod;
 
                                        if (is_reserved_a || is_reserved_b) {
                                                Report.Error (82, member.Location, "A member `{0}' is already reserved",
                                                        is_reserved_a ?
-                                                       TypeManager.GetFullNameSignature (ce.Member) :
+                                                       ce.GetSignatureForError () :
                                                        member.GetSignatureForError ());
                                                return false;
                                        }
                                } else {
-                                       Report.SymbolRelatedToPreviousError (ce.Member);
+                                       Report.SymbolRelatedToPreviousError (ce);
                                }
-                               
+
+                               if (member is Operator && ce.Kind == MemberKind.Operator) {
+                                       Report.Error (557, member.Location, "Duplicate user-defined conversion in type `{0}'",
+                                               member.Parent.GetSignatureForError ());
+                                       return false;
+                               }
+
                                Report.Error (111, member.Location,
                                        "A member `{0}' is already defined. Rename this member or use different parameter types",
                                        member.GetSignatureForError ());
index 9ffac154ab7172aa734709ed80545a46f38abdcb..2932ae27837bc9a3c08adf772539b8eb3e1ba96f 100644 (file)
@@ -20,6 +20,7 @@ using System.Runtime.InteropServices;
 using System.Security;
 using System.Security.Permissions;
 using System.Text;
+using System.Linq;
 
 #if NET_2_1
 using XmlElement = System.Object;
@@ -31,9 +32,9 @@ using Mono.CompilerServices.SymbolWriter;
 
 namespace Mono.CSharp {
 
-       public abstract class MethodCore : InterfaceMemberBase
+       public abstract class MethodCore : InterfaceMemberBase, IParametersMember
        {
-               public readonly ParametersCompiled Parameters;
+               protected ParametersCompiled parameters;
                protected ToplevelBlock block;
                protected MethodSpec spec;
 
@@ -42,23 +43,27 @@ namespace Mono.CSharp {
                        MemberName name, Attributes attrs, ParametersCompiled parameters)
                        : base (parent, generic, type, mod, allowed_mod, name, attrs)
                {
-                       Parameters = parameters;
+                       this.parameters = parameters;
                }
 
                //
                //  Returns the System.Type array for the parameters of this method
                //
-               public Type [] ParameterTypes {
+               public TypeSpec [] ParameterTypes {
                        get {
-                               return Parameters.Types;
+                               return parameters.Types;
                        }
                }
 
                public ParametersCompiled ParameterInfo {
                        get {
-                               return Parameters;
+                               return parameters;
                        }
                }
+
+               AParametersCollection IParametersMember.Parameters {
+                       get { return parameters; }
+               }
                
                public ToplevelBlock Block {
                        get {
@@ -72,7 +77,7 @@ namespace Mono.CSharp {
 
                public CallingConventions CallingConventions {
                        get {
-                               CallingConventions cc = Parameters.CallingConvention;
+                               CallingConventions cc = parameters.CallingConvention;
                                if (!IsInterface)
                                        if ((ModFlags & Modifiers.STATIC) == 0)
                                                cc |= CallingConventions.HasThis;
@@ -83,10 +88,25 @@ namespace Mono.CSharp {
                        }
                }
 
+               protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
+               {
+                       bool res = base.CheckOverrideAgainstBase (base_member);
+
+                       //
+                       // Check that the permissions are not being changed
+                       //
+                       if (!CheckAccessModifiers (this, base_member)) {
+                               Error_CannotChangeAccessModifiers (this, base_member);
+                               res = false;
+                       }
+
+                       return res;
+               }
+
                protected override bool CheckBase ()
                {
                        // Check whether arguments were correct.
-                       if (!DefineParameters (Parameters))
+                       if (!DefineParameters (parameters))
                                return false;
 
                        return base.CheckBase ();
@@ -98,7 +118,7 @@ namespace Mono.CSharp {
                //
                public override string GetDocCommentName (DeclSpace ds)
                {
-                       return DocUtil.GetMethodDocCommentName (this, Parameters, ds);
+                       return DocUtil.GetMethodDocCommentName (this, parameters, ds);
                }
 
                //
@@ -140,74 +160,84 @@ namespace Mono.CSharp {
                        if (!base.VerifyClsCompliance ())
                                return false;
 
-                       if (Parameters.HasArglist) {
+                       if (parameters.HasArglist) {
                                Report.Warning (3000, 1, Location, "Methods with variable arguments are not CLS-compliant");
                        }
 
-                       if (!AttributeTester.IsClsCompliant (MemberType)) {
+                       if (member_type != null && !member_type.IsCLSCompliant ()) {
                                Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
                                        GetSignatureForError ());
                        }
 
-                       Parameters.VerifyClsCompliance (this);
+                       parameters.VerifyClsCompliance (this);
                        return true;
                }
        }
 
-       interface IGenericMethodDefinition : IMemberDefinition
+       public interface IGenericMethodDefinition : IMemberDefinition
        {
-               MethodInfo MakeGenericMethod (Type[] targs);
+               TypeParameterSpec[] TypeParameters { get; }
+               int TypeParametersCount { get; }
+
+//             MethodInfo MakeGenericMethod (TypeSpec[] targs);
        }
 
-       public class MethodSpec : MemberSpec
+       public class MethodSpec : MemberSpec, IParametersMember
        {
                MethodBase metaInfo;
-               readonly AParametersCollection parameters;
+               AParametersCollection parameters;
+               TypeSpec returnType;
+
+               TypeSpec[] targs;
+               TypeParameterSpec[] constraints;
 
-               public MethodSpec (MemberKind kind, IMemberDefinition details, MethodBase info, AParametersCollection parameters, Modifiers modifiers)
-                       : base (kind, details, info.Name, modifiers)
+               public MethodSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition details, TypeSpec returnType,
+                       MethodBase info, AParametersCollection parameters, Modifiers modifiers)
+                       : base (kind, declaringType, details, modifiers)
                {
-                       this.MetaInfo = info;
+                       this.metaInfo = info;
                        this.parameters = parameters;
+                       this.returnType = returnType;
                }
 
-               public override Type DeclaringType {
+               #region Properties
+
+               public override int Arity {
                        get {
-                               return MetaInfo.DeclaringType;
+                               return IsGeneric ? GenericDefinition.TypeParametersCount : 0;
                        }
                }
 
-               public Type[] GetGenericArguments ()
-               {
-                       return MetaInfo.GetGenericArguments ();
-               }
-
-               public MethodSpec Inflate (Type[] targs)
-               {
-                       // TODO: Only create MethodSpec and inflate parameters, defer the call for later
-                       var mb = ((IGenericMethodDefinition) definition).MakeGenericMethod (targs);
+               public TypeParameterSpec[] Constraints {
+                       get {
+                               if (constraints == null && IsGeneric)
+                                       constraints = GenericDefinition.TypeParameters;
 
-                       // TODO: Does not work on .NET
-                       var par = TypeManager.GetParameterData (mb);
+                               return constraints;
+                       }
+               }
 
-                       return new MethodSpec (Kind, definition, mb, par, Modifiers);
+               public bool IsConstructor {
+                       get {
+                               return Kind == MemberKind.Constructor;
+                       }
                }
 
-               public bool IsAbstract {
+               public IGenericMethodDefinition GenericDefinition {
                        get {
-                               return (Modifiers & Modifiers.ABSTRACT) != 0;
+                               return (IGenericMethodDefinition) definition;
                        }
                }
 
-               public bool IsConstructor {
+               public bool IsExtensionMethod {
                        get {
-                               return MetaInfo.IsConstructor;
+                               return IsStatic && parameters.HasExtensionMethodType;
                        }
                }
 
-               public bool IsGenericMethod {
+               public bool IsSealed {
                        get {
-                               return MetaInfo.IsGenericMethod;
+                               return (Modifiers & Modifiers.SEALED) != 0;
                        }
                }
 
@@ -218,24 +248,185 @@ namespace Mono.CSharp {
                        }
                }
 
-               public MethodBase MetaInfo {
+               public bool IsReservedMethod {
                        get {
-                               return metaInfo;
+                               return Kind == MemberKind.Operator || IsAccessor;
                        }
-                       set {
-                               metaInfo = value;
+               }
+
+               TypeSpec IInterfaceMemberSpec.MemberType {
+                       get {
+                               return returnType;
                        }
                }
 
                public AParametersCollection Parameters {
-                       get { return parameters; }
+                       get { 
+                               return parameters;
+                       }
                }
 
-               public Type ReturnType {
+               public TypeSpec ReturnType {
                        get {
-                               return IsConstructor ?
-                                       TypeManager.void_type : ((MethodInfo) MetaInfo).ReturnType;
+                               return returnType;
+                       }
+               }
+
+               public TypeSpec[] TypeArguments {
+                       get {
+                               return targs;
+                       }
+               }
+
+               #endregion
+
+               public MethodSpec GetGenericMethodDefinition ()
+               {
+                       if (!IsGeneric && !DeclaringType.IsGeneric)
+                               return this;
+
+                       return MemberCache.GetMember (declaringType, this);
+               }
+
+               public MethodBase GetMetaInfo ()
+               {
+                       if ((state & StateFlags.PendingMetaInflate) != 0) {
+                               if (DeclaringType.IsTypeBuilder) {
+                                       if (IsConstructor)
+                                               metaInfo = TypeBuilder.GetConstructor (DeclaringType.GetMetaInfo (), (ConstructorInfo) metaInfo);
+                                       else
+                                               metaInfo = TypeBuilder.GetMethod (DeclaringType.GetMetaInfo (), (MethodInfo) metaInfo);
+                               } else {
+                                       metaInfo = MethodInfo.GetMethodFromHandle (metaInfo.MethodHandle, DeclaringType.GetMetaInfo ().TypeHandle);
+                               }
+
+                               state &= ~StateFlags.PendingMetaInflate;
+                       }
+
+                       if ((state & StateFlags.PendingMakeMethod) != 0) {
+                               metaInfo = ((MethodInfo) metaInfo).MakeGenericMethod (targs.Select (l => l.GetMetaInfo ()).ToArray ());
+                               state &= ~StateFlags.PendingMakeMethod;
                        }
+
+                       if (Kind == MemberKind.FakeMethod)
+                               throw new InternalErrorException ("Emitting fake method");
+
+                       return metaInfo;
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       string name;
+                       if (IsConstructor) {
+                               name = DeclaringType.GetSignatureForError () + "." + DeclaringType.Name;
+                       } else if (Kind == MemberKind.Operator) {
+                               var op = Operator.GetType (Name).Value;
+                               if (op == Operator.OpType.Implicit || op == Operator.OpType.Explicit) {
+                                       name = DeclaringType.GetSignatureForError () + "." + Operator.GetName (op) + " operator " + returnType.GetSignatureForError ();
+                               } else {
+                                       name = DeclaringType.GetSignatureForError () + ".operator " + Operator.GetName (op);
+                               }
+                       } else if (IsAccessor) {
+                               int split = Name.IndexOf ('_');
+                               name = Name.Substring (split + 1);
+                               var postfix = Name.Substring (0, split);
+                               if (split == 3) {
+                                       var pc = parameters.Count;
+                                       if (pc > 0 && postfix == "get") {
+                                               name = "this" + parameters.GetSignatureForError ("[", "]", pc);
+                                       } else if (pc > 1 && postfix == "set") {
+                                               name = "this" + parameters.GetSignatureForError ("[", "]", pc - 1);
+                                       }
+                               }
+
+                               return DeclaringType.GetSignatureForError () + "." + name + "." + postfix;
+                       } else {
+                               name = base.GetSignatureForError ();
+                               if (targs != null)
+                                       name += "<" + TypeManager.CSharpName (targs) + ">";
+                               else if (IsGeneric)
+                                       name += "<" + TypeManager.CSharpName (GenericDefinition.TypeParameters) + ">";
+                       }
+
+                       return name + parameters.GetSignatureForError ();
+               }
+
+               public override MemberSpec InflateMember (TypeParameterInflator inflator)
+               {
+                       var ms = (MethodSpec) base.InflateMember (inflator);
+                       ms.returnType = inflator.Inflate (returnType);
+                       ms.parameters = parameters.Inflate (inflator);
+                       if (IsGeneric)
+                               ms.constraints = TypeParameterSpec.InflateConstraints (inflator, GenericDefinition.TypeParameters);
+
+                       return ms;
+               }
+
+               public MethodSpec MakeGenericMethod (params TypeSpec[] targs)
+               {
+                       if (targs == null)
+                               throw new ArgumentNullException ();
+// TODO MemberCache
+//                     if (generic_intances != null && generic_intances.TryGetValue (targs, out ginstance))
+//                             return ginstance;
+
+                       //if (generic_intances == null)
+                       //    generic_intances = new Dictionary<TypeSpec[], Method> (TypeSpecArrayComparer.Default);
+
+                       var inflator = new TypeParameterInflator (DeclaringType, GenericDefinition.TypeParameters, targs);
+
+                       var inflated = (MethodSpec) MemberwiseClone ();
+                       inflated.declaringType = inflator.TypeInstance;
+                       inflated.returnType = inflator.Inflate (returnType);
+                       inflated.parameters = parameters.Inflate (inflator);
+                       inflated.targs = targs;
+                       inflated.constraints = TypeParameterSpec.InflateConstraints (inflator, constraints ?? GenericDefinition.TypeParameters);
+                       inflated.state |= StateFlags.PendingMakeMethod;
+
+                       //                      if (inflated.parent == null)
+                       //                              inflated.parent = parent;
+
+                       //generic_intances.Add (targs, inflated);
+                       return inflated;
+               }
+
+               public MethodSpec Mutate (TypeParameterMutator mutator)
+               {
+                       var targs = TypeArguments;
+                       if (targs != null)
+                               targs = mutator.Mutate (targs);
+
+                       var decl = DeclaringType;
+                       if (DeclaringType.IsGenericOrParentIsGeneric) {
+                               decl = mutator.Mutate (decl);
+                       }
+
+                       if (targs == TypeArguments && decl == DeclaringType)
+                               return this;
+
+                       var ms = (MethodSpec) MemberwiseClone ();
+                       if (decl != DeclaringType) {
+                               // Gets back MethodInfo in case of metaInfo was inflated
+                               ms.metaInfo = MemberCache.GetMember (DeclaringType.GetDefinition (), this).metaInfo;
+
+                               ms.declaringType = decl;
+                               ms.state |= StateFlags.PendingMetaInflate;
+                       }
+
+                       if (targs != null) {
+                               ms.targs = targs;
+                               ms.state |= StateFlags.PendingMakeMethod;
+                       }
+
+                       return ms;
+               }
+
+               public void SetMetaInfo (MethodInfo info)
+               {
+                       if (this.metaInfo != null)
+                               throw new InternalErrorException ("MetaInfo reset");
+
+                       this.metaInfo = info;
                }
        }
 
@@ -256,7 +447,7 @@ namespace Mono.CSharp {
                {
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Target == AttributeTargets.ReturnValue) {
                                if (return_attributes == null)
@@ -286,7 +477,7 @@ namespace Mono.CSharp {
                        }
 
                        if (MethodBuilder != null)
-                               MethodBuilder.SetCustomAttribute (ctor, cdata);
+                               MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
                public override AttributeTargets AttributeTargets {
@@ -297,28 +488,12 @@ namespace Mono.CSharp {
 
                protected override bool CheckForDuplications ()
                {
-                       string name = GetFullName (MemberName);
-                       if (MemberName.IsGeneric)
-                               name = MemberName.MakeName (name, MemberName.TypeArguments);
-
-                       return Parent.MemberCache.CheckExistingMembersOverloads (this, name, Parameters, Report);
+                       return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
                }
 
                public virtual EmitContext CreateEmitContext (ILGenerator ig)
                {
-                       return new EmitContext (
-                               this, ig, MemberType);
-               }
-
-               protected override bool ResolveMemberType ()
-               {
-                       if (GenericMethod != null) {
-                               MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
-                               if (!GenericMethod.Define (this))
-                                       return false;
-                       }
-
-                       return base.ResolveMemberType ();
+                       return new EmitContext (this, ig, MemberType);
                }
 
                public override bool Define ()
@@ -329,15 +504,6 @@ namespace Mono.CSharp {
                        if (!CheckBase ())
                                return false;
 
-                       if (block != null && block.IsIterator && !(Parent is IteratorStorey)) {
-                               //
-                               // Current method is turned into automatically generated
-                               // wrapper which creates an instance of iterator
-                               //
-                               Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
-                               ModFlags |= Modifiers.DEBUGGER_HIDDEN;
-                       }
-
                        MemberKind kind;
                        if (this is Operator)
                                kind = MemberKind.Operator;
@@ -352,11 +518,10 @@ namespace Mono.CSharp {
 
                                // Add to member cache only when a partial method implementation has not been found yet
                                if ((caching_flags & Flags.PartialDefinitionExists) == 0) {
-                                       MethodBase mb = new PartialMethodDefinitionInfo (this);
+//                                     MethodBase mb = new PartialMethodDefinitionInfo (this);
 
-                                       spec = new MethodSpec (kind, this, mb, Parameters, ModFlags);
-                                       Parent.MemberCache.AddMember (mb, spec);
-                                       TypeManager.AddMethod (mb, this);
+                                       spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags);
+                                       Parent.MemberCache.AddMember (spec);
                                }
 
                                return true;
@@ -370,12 +535,11 @@ namespace Mono.CSharp {
                                        
                        MethodBuilder = MethodData.MethodBuilder;
 
-                       spec = new MethodSpec (kind, this, MethodBuilder, Parameters, ModFlags);
-
-                       if (TypeManager.IsGenericMethod (MethodBuilder))
-                               Parent.MemberCache.AddGenericMember (MethodBuilder, this);
+                       spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags);
+                       if (MemberName.Arity > 0)
+                               spec.IsGeneric = true;
                        
-                       Parent.MemberCache.AddMember (MethodBuilder, spec);
+                       Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec);
 
                        return true;
                }
@@ -387,8 +551,8 @@ namespace Mono.CSharp {
                        CheckAbstractAndExtern (block != null);
 
                        if ((ModFlags & Modifiers.PARTIAL) != 0) {
-                               for (int i = 0; i < Parameters.Count; ++i) {
-                                       IParameterData p = Parameters.FixedParameters [i];
+                               for (int i = 0; i < parameters.Count; ++i) {
+                                       IParameterData p = parameters.FixedParameters [i];
                                        if (p.ModFlags == Parameter.Modifier.OUT) {
                                                Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
                                                        GetSignatureForError ());
@@ -404,10 +568,8 @@ namespace Mono.CSharp {
                {
                        base.DoMemberTypeDependentChecks ();
 
-                       if (!TypeManager.IsGenericParameter (MemberType)) {
-                               if (MemberType.IsAbstract && MemberType.IsSealed) {
-                                       Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
-                               }
+                       if (MemberType.IsStatic) {
+                               Error_StaticReturnType ();
                        }
                }
 
@@ -418,14 +580,14 @@ namespace Mono.CSharp {
                        if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
                                PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (MethodBuilder);
 
-                       if (TypeManager.IsDynamicType (ReturnType)) {
+                       if (ReturnType == InternalType.Dynamic) {
                                return_attributes = new ReturnParameter (this, MethodBuilder, Location);
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
                        } else {
                                var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType);
                                if (trans_flags != null) {
                                        var pa = PredefinedAttributes.Get.DynamicTransform;
-                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
                                                return_attributes = new ReturnParameter (this, MethodBuilder, Location);
                                                return_attributes.Builder.SetCustomAttribute (
                                                        new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
@@ -478,7 +640,7 @@ namespace Mono.CSharp {
 
                #region IMethodData Members
 
-               public Type ReturnType {
+               public TypeSpec ReturnType {
                        get {
                                return MemberType;
                        }
@@ -493,48 +655,36 @@ namespace Mono.CSharp {
                /// <summary>
                /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
                /// </summary>
-               public bool IsExcluded () {
-                       if ((caching_flags & Flags.Excluded_Undetected) == 0)
-                               return (caching_flags & Flags.Excluded) != 0;
+               public override string[] ConditionalConditions ()
+               {
+                       if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
+                               return null;
+
+                       if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.Excluded) != 0)
+                               return new string [0];
 
                        caching_flags &= ~Flags.Excluded_Undetected;
+                       string[] conditions;
 
                        if (base_method == null) {
                                if (OptAttributes == null)
-                                       return false;
+                                       return null;
 
                                Attribute[] attrs = OptAttributes.SearchMulti (PredefinedAttributes.Get.Conditional);
-
                                if (attrs == null)
-                                       return false;
-
-                               foreach (Attribute a in attrs) {
-                                       string condition = a.GetConditionalAttributeValue ();
-                                       if (condition == null)
-                                               return false;
-
-                                       if (Location.CompilationUnit.IsConditionalDefined (condition))
-                                               return false;
-                               }
-
-                               caching_flags |= Flags.Excluded;
-                               return true;
-                       }
+                                       return null;
 
-                       IMethodData md = TypeManager.GetMethod (TypeManager.DropGenericMethodArguments (base_method));
-                       if (md == null) {
-                               if (AttributeTester.IsConditionalMethodExcluded (base_method, Location)) {
-                                       caching_flags |= Flags.Excluded;
-                                       return true;
-                               }
-                               return false;
+                               conditions = new string[attrs.Length];
+                               for (int i = 0; i < conditions.Length; ++i)
+                                       conditions[i] = attrs[i].GetConditionalAttributeValue ();
+                       } else {
+                               conditions = base_method.MemberDefinition.ConditionalConditions();
                        }
 
-                       if (md.IsExcluded ()) {
+                       if (conditions != null)
                                caching_flags |= Flags.Excluded;
-                               return true;
-                       }
-                       return false;
+
+                       return conditions;
                }
 
                GenericMethod IMethodData.GenericMethod {
@@ -645,10 +795,52 @@ namespace Mono.CSharp {
                        : base (parent, null, return_type, mod, amod, name, attrs, parameters)
                {
                }
-               
+
+#region Properties
+
+               public override TypeParameter[] CurrentTypeParameters {
+                       get {
+                               if (GenericMethod != null)
+                                       return GenericMethod.CurrentTypeParameters;
+
+                               return null;
+                       }
+               }
+
+               public override bool HasUnresolvedConstraints {
+                       get {
+                               if (CurrentTypeParameters == null)
+                                       return false;
+
+                               // When overriding base method constraints are fetched from
+                               // base method but to find it we have to resolve parameters
+                               // to find exact base method match
+                               if (IsExplicitImpl || (ModFlags & Modifiers.OVERRIDE) != 0)
+                                       return base_method == null;
+
+                               // Even for non-override generic method constraints check has to be
+                               // delayed after all constraints are resolved
+                               return true;
+                       }
+               }
+
+               public TypeParameterSpec[] TypeParameters {
+                       get {
+                               return CurrentTypeParameters.Select (l => l.Type).ToArray ();
+                       }
+               }
+
+               public int TypeParametersCount {
+                       get {
+                               return CurrentTypeParameters == null ? 0 : CurrentTypeParameters.Length;
+                       }
+               }
+
+#endregion
+
                public override string GetSignatureForError()
                {
-                       return base.GetSignatureForError () + Parameters.GetSignatureForError ();
+                       return base.GetSignatureForError () + parameters.GetSignatureForError ();
                }
 
                void Error_DuplicateEntryPoint (Method b)
@@ -664,31 +856,32 @@ namespace Mono.CSharp {
                                ReturnType != TypeManager.int32_type)
                                return false;
 
-                       if (Parameters.Count == 0)
+                       if (parameters.IsEmpty)
                                return true;
 
-                       if (Parameters.Count > 1)
+                       if (parameters.Count > 1)
                                return false;
 
-                       Type t = Parameters.Types [0];
-                       return t.IsArray && t.GetArrayRank () == 1 &&
-                                       TypeManager.GetElementType (t) == TypeManager.string_type &&
-                                       (Parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
+                       var ac = parameters.Types [0] as ArrayContainer;
+                       return ac != null && ac.Rank == 1 && ac.Element == TypeManager.string_type &&
+                                       (parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
                }
 
-               public override FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               public override FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
                {
-                       TypeParameter[] tp = CurrentTypeParameters;
-                       if (tp != null) {
-                               TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
-                               if (t != null)
-                                       return new TypeParameterExpr (t, loc);
+                       if (arity == 0) {
+                               TypeParameter[] tp = CurrentTypeParameters;
+                               if (tp != null) {
+                                       TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
+                                       if (t != null)
+                                               return new TypeParameterExpr (t, loc);
+                               }
                        }
 
-                       return base.LookupNamespaceOrType (name, loc, ignore_cs0104);
+                       return base.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.Conditional) {
                                if (IsExplicitImpl) {
@@ -718,8 +911,8 @@ namespace Mono.CSharp {
                                        return;
                                }
 
-                               for (int i = 0; i < Parameters.Count; ++i) {
-                                       if (Parameters.FixedParameters [i].ModFlags == Parameter.Modifier.OUT) {
+                               for (int i = 0; i < parameters.Count; ++i) {
+                                       if (parameters.FixedParameters [i].ModFlags == Parameter.Modifier.OUT) {
                                                Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
                                                return;
                                        }
@@ -760,25 +953,44 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               protected override bool CheckBase ()
+               protected virtual void DefineTypeParameters ()
                {
-                       if (!base.CheckBase ())
-                               return false;
+                       var tparams = CurrentTypeParameters;
 
-                       if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == Destructor.MetadataName) {
-                               Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
-                                       TypeManager.CSharpSignature (base_method));
+                       TypeParameterSpec[] base_tparams = null;
+                       if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
+                               if (base_method != null)
+                                       base_tparams = base_method.GenericDefinition.TypeParameters;
+                               else if (MethodData.implementing != null)
+                                       base_tparams = MethodData.implementing.GenericDefinition.TypeParameters;
                        }
 
-                       return true;
-               }
+                       for (int i = 0; i < tparams.Length; ++i) {
+                               var tp = tparams[i];
 
-               public override TypeParameter[] CurrentTypeParameters {
-                       get {
-                               if (GenericMethod != null)
-                                       return GenericMethod.CurrentTypeParameters;
+                               if (!tp.ResolveConstraints (this))
+                                       continue;
 
-                               return null;
+                               //
+                               // Copy base constraints for override/explicit methods
+                               //
+                               if (base_tparams != null) {
+                                       var base_tparam = base_tparams[i];
+                                       tp.Type.SpecialConstraint = base_tparam.SpecialConstraint;
+                                       tp.Type.TypeArguments = base_tparam.TypeArguments;
+
+                                       // TODO MemberCache: Inflate with different MVAR ?
+                                       tp.Type.Interfaces = base_tparam.Interfaces;
+                                       tp.Type.BaseType = base_tparam.BaseType;
+                               } else if (MethodData.implementing != null) {
+                                       var base_tp = MethodData.implementing.Constraints[i];
+                                       if (!tp.Type.HasSameConstraintsImplementation (base_tp)) {
+                                               Report.SymbolRelatedToPreviousError (MethodData.implementing);
+                                               Report.Error (425, Location,
+                                                       "The constraints for type parameter `{0}' of method `{1}' must match the constraints for type parameter `{2}' of interface method `{3}'. Consider using an explicit interface implementation instead",
+                                                       tp.GetSignatureForError (), GetSignatureForError (), base_tp.GetSignatureForError (), MethodData.implementing.GetSignatureForError ());
+                                       }
+                               }
                        }
                }
 
@@ -787,7 +999,7 @@ namespace Mono.CSharp {
                //
                public override bool Define ()
                {
-                       if (type_name == TypeManager.system_void_expr && Parameters.IsEmpty && Name == Destructor.MetadataName) {
+                       if (type_expr == TypeManager.system_void_expr && parameters.IsEmpty && Name == Destructor.MetadataName) {
                                Report.Warning (465, 1, Location, "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
                        }
 
@@ -802,18 +1014,32 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       if (base_method != null && (ModFlags & Modifiers.NEW) == 0) {
-                               if (Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type && Name == "Equals")
-                                       Parent.PartialContainer.Mark_HasEquals ();
-                               else if (Parameters.IsEmpty && Name == "GetHashCode")
-                                       Parent.PartialContainer.Mark_HasGetHashCode ();
+                       if (CurrentTypeParameters == null) {
+                               if (base_method != null) {
+                                       if (parameters.Count == 1 && ParameterTypes[0] == TypeManager.object_type && Name == "Equals")
+                                               Parent.PartialContainer.Mark_HasEquals ();
+                                       else if (parameters.IsEmpty && Name == "GetHashCode")
+                                               Parent.PartialContainer.Mark_HasGetHashCode ();
+                               }
+                                       
+                       } else {
+                               DefineTypeParameters ();
+                       }
+
+                       if (block != null && block.IsIterator && !(Parent is IteratorStorey)) {
+                               //
+                               // Current method is turned into automatically generated
+                               // wrapper which creates an instance of iterator
+                               //
+                               Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
+                               ModFlags |= Modifiers.DEBUGGER_HIDDEN;
                        }
 
                        if ((ModFlags & Modifiers.STATIC) == 0)
                                return true;
 
-                       if (Parameters.HasExtensionMethodType) {
-                               if (Parent.PartialContainer.IsStaticClass && !Parent.IsGeneric) {
+                       if (parameters.HasExtensionMethodType) {
+                               if (Parent.PartialContainer.IsStatic && !Parent.IsGeneric) {
                                        if (!Parent.IsTopLevel)
                                                Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
                                                        GetSignatureForError ());
@@ -827,6 +1053,7 @@ namespace Mono.CSharp {
 
                                        ModFlags |= Modifiers.METHOD_EXTENSION;
                                        Parent.PartialContainer.ModFlags |= Modifiers.METHOD_EXTENSION;
+                                       Spec.DeclaringType.SetExtensionMethodContainer ();
                                        CodeGen.Assembly.HasExtensionMethods = true;
                                } else {
                                        Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
@@ -884,6 +1111,24 @@ namespace Mono.CSharp {
                                                GetSignatureForError ());
                                }
 
+                               if (CurrentTypeParameters != null) {
+                                       var ge = type_expr as GenericTypeExpr;
+                                       if (ge != null)
+                                               ge.CheckConstraints (this);
+
+                                       foreach (Parameter p in parameters.FixedParameters) {
+                                               ge = p.TypeExpression as GenericTypeExpr;
+                                               if (ge != null)
+                                                       ge.CheckConstraints (this);
+                                       }
+
+                                       for (int i = 0; i < CurrentTypeParameters.Length; ++i) {
+                                               var tp = CurrentTypeParameters [i];
+                                               tp.CheckGenericConstraints ();
+                                               tp.Emit ();
+                                       }
+                               }
+
                                base.Emit ();
                                
                                if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
@@ -907,29 +1152,20 @@ namespace Mono.CSharp {
                        return base.EnableOverloadChecks (overload);
                }
 
-               public static void Error1599 (Location loc, Type t, Report Report)
+               public static void Error1599 (Location loc, TypeSpec t, Report Report)
                {
                        Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
                }
 
-               protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
+               protected override bool ResolveMemberType ()
                {
-                       MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindMemberToOverride (
-                               Parent.TypeBuilder, Name, Parameters, GenericMethod, false);
-
-                       if (mi == null)
-                               return null;
-
-                       if (mi.IsSpecialName)
-                               return null;
-
-                       base_ret_type = TypeManager.TypeToCoreType (mi.ReturnType);
-                       return mi;
-               }
+                       if (GenericMethod != null) {
+                               MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
+                               if (!GenericMethod.Define (this))
+                                       return false;
+                       }
 
-               public MethodInfo MakeGenericMethod (Type[] targs)
-               {
-                       return MethodBuilder.MakeGenericMethod (targs);
+                       return base.ResolveMemberType ();
                }
 
                public void SetPartialDefinition (Method methodDefinition)
@@ -938,9 +1174,9 @@ namespace Mono.CSharp {
                        methodDefinition.partialMethodImplementation = this;
 
                        // Ensure we are always using method declaration parameters
-                       for (int i = 0; i < methodDefinition.Parameters.Count; ++i ) {
-                               Parameters [i].Name = methodDefinition.Parameters [i].Name;
-                               Parameters [i].DefaultValue = methodDefinition.Parameters [i].DefaultValue;
+                       for (int i = 0; i < methodDefinition.parameters.Count; ++i ) {
+                               parameters [i].Name = methodDefinition.parameters [i].Name;
+                               parameters [i].DefaultValue = methodDefinition.parameters [i].DefaultValue;
                        }
 
                        if (methodDefinition.attributes == null)
@@ -952,20 +1188,6 @@ namespace Mono.CSharp {
                                attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
                        }
                }
-
-               protected override bool VerifyClsCompliance ()
-               {
-                       if (!base.VerifyClsCompliance ())
-                               return false;
-
-                       if (!Parameters.IsEmpty) {
-                               var al = Parent.PartialContainer.MemberCache.Members [Name];
-                               if (al.Count > 1)
-                                       MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder, Report);
-                       }
-
-                       return true;
-               }
        }
 
        public abstract class ConstructorInitializer : ExpressionStatement
@@ -994,8 +1216,8 @@ namespace Mono.CSharp {
                {
                        eclass = ExprClass.Value;
 
-                       // TODO: ec.GetSignatureForError ()
-                       ConstructorBuilder caller_builder = ((Constructor) ec.MemberContext).ConstructorBuilder;
+                       // FIXME: Hack
+                       var caller_builder = (Constructor) ec.MemberContext;
 
                        if (argument_list != null) {
                                bool dynamic;
@@ -1021,9 +1243,9 @@ namespace Mono.CSharp {
                                        return this;
 
                                type = ec.CurrentType.BaseType;
-                               if (TypeManager.IsStruct (ec.CurrentType)) {
+                               if (ec.CurrentType.IsStruct) {
                                        ec.Report.Error (522, loc,
-                                               "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
+                                               "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ());
                                        return this;
                                }
                        } else {
@@ -1038,8 +1260,8 @@ namespace Mono.CSharp {
                        }
 
                        base_constructor_group = MemberLookupFinal (
-                               ec, null, type, ConstructorBuilder.ConstructorName, MemberTypes.Constructor,
-                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               ec, null, type, ConstructorBuilder.ConstructorName, 0, MemberKind.Constructor,
+                               BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly,
                                loc) as MethodGroupExpr;
                        
                        if (base_constructor_group == null)
@@ -1056,8 +1278,10 @@ namespace Mono.CSharp {
                        
                        var base_ctor = base_constructor_group.BestCandidate;
 
-                       if (base_ctor.MetaInfo == caller_builder){
-                               ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
+                       // TODO MemberCache: Does it work for inflated types ?
+                       if (base_ctor == caller_builder.Spec){
+                               ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
+                                       caller_builder.GetSignatureForError ());
                        }
                                                
                        return this;
@@ -1147,14 +1371,14 @@ namespace Mono.CSharp {
                public bool IsDefault ()
                {
                        if ((ModFlags & Modifiers.STATIC) != 0)
-                               return Parameters.IsEmpty;
-                       
-                       return Parameters.IsEmpty &&
+                               return parameters.IsEmpty;
+
+                       return parameters.IsEmpty &&
                                        (Initializer is ConstructorBaseInitializer) &&
                                        (Initializer.Arguments == null);
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.IsValidSecurityAttribute ()) {
                                if (declarative_security == null) {
@@ -1168,13 +1392,13 @@ namespace Mono.CSharp {
                                is_external_implementation = true;
                        }
 
-                       ConstructorBuilder.SetCustomAttribute (ctor, cdata);
+                       ConstructorBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
                protected override bool CheckBase ()
                {
                        if ((ModFlags & Modifiers.STATIC) != 0) {
-                               if (!Parameters.IsEmpty) {
+                               if (!parameters.IsEmpty) {
                                        Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
                                                GetSignatureForError ());
                                        return false;
@@ -1185,19 +1409,16 @@ namespace Mono.CSharp {
                        }
 
                        // Check whether arguments were correct.
-                       if (!DefineParameters (Parameters))
+                       if (!DefineParameters (parameters))
                                return false;
 
                        if ((caching_flags & Flags.MethodOverloadsExist) != 0)
-                               Parent.MemberCache.CheckExistingMembersOverloads (this, ConstructorInfo.ConstructorName,
-                                       Parameters, Report);
+                               Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
 
-                       if (Parent.PartialContainer.Kind == MemberKind.Struct) {
-                               if (Parameters.Count == 0) {
-                                       Report.Error (568, Location, 
-                                               "Structs cannot contain explicit parameterless constructors");
-                                       return false;
-                               }
+                       if (Parent.PartialContainer.Kind == MemberKind.Struct && parameters.IsEmpty) {
+                               Report.Error (568, Location, 
+                                       "Structs cannot contain explicit parameterless constructors");
+                               return false;
                        }
 
                        CheckProtectedModifier ();
@@ -1213,25 +1434,12 @@ namespace Mono.CSharp {
                        if (ConstructorBuilder != null)
                                return true;
 
-                       MethodAttributes ca = (MethodAttributes.RTSpecialName |
-                                              MethodAttributes.SpecialName);
+                       var ca = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
                        
                        if ((ModFlags & Modifiers.STATIC) != 0) {
                                ca |= MethodAttributes.Static | MethodAttributes.Private;
                        } else {
-                               ca |= MethodAttributes.HideBySig;
-
-                               if ((ModFlags & Modifiers.PUBLIC) != 0)
-                                       ca |= MethodAttributes.Public;
-                               else if ((ModFlags & Modifiers.PROTECTED) != 0){
-                                       if ((ModFlags & Modifiers.INTERNAL) != 0)
-                                               ca |= MethodAttributes.FamORAssem;
-                                       else 
-                                               ca |= MethodAttributes.Family;
-                               } else if ((ModFlags & Modifiers.INTERNAL) != 0)
-                                       ca |= MethodAttributes.Assembly;
-                               else
-                                       ca |= MethodAttributes.Private;
+                               ca |= ModifiersExtensions.MethodAttr (ModFlags);
                        }
 
                        if (!CheckAbstractAndExtern (block != null))
@@ -1243,20 +1451,11 @@ namespace Mono.CSharp {
 
                        ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
                                ca, CallingConventions,
-                               Parameters.GetEmitTypes ());
+                               parameters.GetMetaInfo ());
 
-                       spec = new MethodSpec (MemberKind.Constructor, this, ConstructorBuilder, Parameters, ModFlags);
-
-                       if (Parent.PartialContainer.IsComImport) {
-                               if (!IsDefault ()) {
-                                       Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
-                                               Parent.GetSignatureForError ());
-                               }
-                               ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
-                       }
+                       spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, TypeManager.void_type, ConstructorBuilder, parameters, ModFlags);
                        
-                       Parent.MemberCache.AddMember (ConstructorBuilder, spec);
-                       TypeManager.AddMethod (ConstructorBuilder, this);
+                       Parent.MemberCache.AddMember (spec);
                        
                        // It's here only to report an error
                        if (block != null && block.IsIterator) {
@@ -1272,6 +1471,14 @@ namespace Mono.CSharp {
                //
                public override void Emit ()
                {
+                       if (Parent.PartialContainer.IsComImport) {
+                               if (!IsDefault ()) {
+                                       Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
+                                               Parent.GetSignatureForError ());
+                               }
+                               ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
+                       }
+
                        if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
                                PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (ConstructorBuilder);
 
@@ -1310,12 +1517,12 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       Parameters.ApplyAttributes (ConstructorBuilder);
+                       parameters.ApplyAttributes (ConstructorBuilder);
 
                        SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder, block);
 
                        if (block != null) {
-                               if (block.Resolve (null, bc, Parameters, this)) {
+                               if (block.Resolve (null, bc, parameters, this)) {
                                        EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType);
                                        ec.With (EmitContext.Options.ConstructorScope, true);
 
@@ -1340,15 +1547,16 @@ namespace Mono.CSharp {
                        block = null;
                }
 
-               // Is never override
-               protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
+               protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate)
                {
+                       // Is never override
+                       bestCandidate = null;
                        return null;
                }
 
                public override string GetSignatureForError()
                {
-                       return base.GetSignatureForError () + Parameters.GetSignatureForError ();
+                       return base.GetSignatureForError () + parameters.GetSignatureForError ();
                }
 
                public override string[] ValidAttributeTargets {
@@ -1362,20 +1570,15 @@ namespace Mono.CSharp {
                        if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
                                return false;
                        }
-                       
-                       if (!Parameters.IsEmpty) {
-                               var al = Parent.MemberCache.Members [ConstructorInfo.ConstructorName];
-                               if (al.Count > 2)
-                                       MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder, Report);
-                               if (TypeManager.IsSubclassOf (Parent.TypeBuilder, TypeManager.attribute_type)) {
-                                       foreach (Type param in Parameters.Types) {
-                                               if (param.IsArray) {
-                                                       return true;
-                                               }
+
+                       if (!parameters.IsEmpty && Parent.Definition.IsAttribute) {
+                               foreach (TypeSpec param in parameters.Types) {
+                                       if (param.IsArray) {
+                                               return true;
                                        }
                                }
                        }
+
                        has_compliant_args = true;
                        return true;
                }
@@ -1388,7 +1591,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public Type ReturnType {
+               public TypeSpec ReturnType {
                        get {
                                return MemberType;
                        }
@@ -1424,19 +1627,16 @@ namespace Mono.CSharp {
                CallingConventions CallingConventions { get; }
                Location Location { get; }
                MemberName MethodName { get; }
-               Type ReturnType { get; }
+               TypeSpec ReturnType { get; }
                GenericMethod GenericMethod { get; }
                ParametersCompiled ParameterInfo { get; }
+               MethodSpec Spec { get; }
 
                Attributes OptAttributes { get; }
                ToplevelBlock Block { get; set; }
 
                EmitContext CreateEmitContext (ILGenerator ig);
-               ObsoleteAttribute GetObsoleteAttribute ();
                string GetSignatureForError ();
-               bool IsExcluded ();
-               bool IsClsComplianceRequired ();
-               void SetIsUsed ();
                void EmitExtraSymbolInfo (SourceMethod source);
        }
 
@@ -1452,7 +1652,7 @@ namespace Mono.CSharp {
                //
                // Are we implementing an interface ?
                //
-               public MethodInfo implementing;
+               public MethodSpec implementing;
 
                //
                // Protected data.
@@ -1460,17 +1660,17 @@ namespace Mono.CSharp {
                protected InterfaceMemberBase member;
                protected Modifiers modifiers;
                protected MethodAttributes flags;
-               protected Type declaring_type;
-               protected MethodInfo parent_method;
+               protected TypeSpec declaring_type;
+               protected MethodSpec parent_method;
 
-               MethodBuilder builder = null;
+               MethodBuilder builder;
                public MethodBuilder MethodBuilder {
                        get {
                                return builder;
                        }
                }
 
-               public Type DeclaringType {
+               public TypeSpec DeclaringType {
                        get {
                                return declaring_type;
                        }
@@ -1489,7 +1689,7 @@ namespace Mono.CSharp {
                public MethodData (InterfaceMemberBase member,
                                   Modifiers modifiers, MethodAttributes flags, 
                                   IMethodData method, MethodBuilder builder,
-                                  GenericMethod generic, MethodInfo parent_method)
+                                  GenericMethod generic, MethodSpec parent_method)
                        : this (member, modifiers, flags, method)
                {
                        this.builder = builder;
@@ -1499,13 +1699,11 @@ namespace Mono.CSharp {
 
                public bool Define (DeclSpace parent, string method_full_name, Report Report)
                {
-                       string name = method.MethodName.Basename;
-
                        TypeContainer container = parent.PartialContainer;
 
                        PendingImplementation pending = container.PendingImplementations;
                        if (pending != null){
-                               implementing = pending.IsInterfaceMethod (name, member.InterfaceType, this);
+                               implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this);
 
                                if (member.InterfaceType != null){
                                        if (implementing == null){
@@ -1521,7 +1719,7 @@ namespace Mono.CSharp {
                                                }
                                                return false;
                                        }
-                                       if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
+                                       if (implementing.IsAccessor && !(method is AbstractPropertyEventMethod)) {
                                                Report.SymbolRelatedToPreviousError (implementing);
                                                Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
                                                        member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
@@ -1531,14 +1729,13 @@ namespace Mono.CSharp {
                                        if (implementing != null) {
                                                AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
                                                if (prop_method == null) {
-                                                       if (TypeManager.IsSpecialMethod (implementing)) {
+                                                       if (implementing.IsAccessor) {
                                                                Report.SymbolRelatedToPreviousError (implementing);
-                                                               Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
-                                                                       method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
-                                                                       implementing.Name.StartsWith ("get_") ? "get" : "set");
+                                                               Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}'",
+                                                                       method.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
                                                        }
                                                } else if (implementing.DeclaringType.IsInterface) {
-                                                       if (!implementing.IsSpecialName) {
+                                                       if (!implementing.IsAccessor) {
                                                                Report.SymbolRelatedToPreviousError (implementing);
                                                                Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
                                                                        method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
@@ -1548,7 +1745,7 @@ namespace Mono.CSharp {
                                                        if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
                                                                Report.SymbolRelatedToPreviousError (implementing);
                                                                Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
-                                                                       method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
+                                                                       method.GetSignatureForError (), implementing.GetSignatureForError ());
                                                                return false;
                                                        }
                                                }
@@ -1569,7 +1766,7 @@ namespace Mono.CSharp {
                                // but it wont get cleared
                                //
                                if (member.IsExplicitImpl){
-                                       if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
+                                       if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) {
                                                Report.SymbolRelatedToPreviousError (implementing);
                                                Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
                                                        method.GetSignatureForError ());
@@ -1631,26 +1828,13 @@ namespace Mono.CSharp {
                        if (builder == null)
                                return false;
 
-                       if (container.CurrentType != null)
-                               declaring_type = container.CurrentType;
-                       else
-                               declaring_type = container.TypeBuilder;
+//                     if (container.CurrentType != null)
+//                             declaring_type = container.CurrentType;
+//                     else
+                               declaring_type = container.Definition;
 
                        if (implementing != null && member.IsExplicitImpl) {
-                                       container.TypeBuilder.DefineMethodOverride (builder, implementing);
-                       }
-
-                       TypeManager.AddMethod (builder, method);
-
-                       if (GenericMethod != null) {
-                               bool is_override = member.IsExplicitImpl |
-                                       ((modifiers & Modifiers.OVERRIDE) != 0);
-
-                               if (implementing != null)
-                                       parent_method = implementing;
-
-                               if (!GenericMethod.DefineType (GenericMethod, builder, parent_method, is_override))
-                                       return false;
+                               container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
                        }
 
                        return true;
@@ -1662,11 +1846,13 @@ namespace Mono.CSharp {
                /// </summary>
                void DefineMethodBuilder (TypeContainer container, string method_name, ParametersCompiled param)
                {
+                       var return_type = method.ReturnType.GetMetaInfo ();
+                       var p_types = param.GetMetaInfo ();
+
                        if (builder == null) {
                                builder = container.TypeBuilder.DefineMethod (
                                        method_name, flags, method.CallingConventions,
-                                       method.ReturnType,
-                                       param.GetEmitTypes ());
+                                       return_type, p_types);
                                return;
                        }
 
@@ -1674,8 +1860,8 @@ namespace Mono.CSharp {
                        // Generic method has been already defined to resolve method parameters
                        // correctly when they use type parameters
                        //
-                       builder.SetParameters (param.GetEmitTypes ());
-                       builder.SetReturnType (method.ReturnType);
+                       builder.SetParameters (p_types);
+                       builder.SetReturnType (return_type);
                        if (builder.Attributes != flags) {
                                try {
                                        if (methodbuilder_attrs_field == null)
@@ -1692,16 +1878,16 @@ namespace Mono.CSharp {
                // 
                public void Emit (DeclSpace parent)
                {
-                       method.ParameterInfo.ApplyAttributes (MethodBuilder);
-
                        if (GenericMethod != null)
                                GenericMethod.EmitAttributes ();
 
+                       method.ParameterInfo.ApplyAttributes (MethodBuilder);
+
                        //
                        // clear the pending implementation flag
                        //
                        if (implementing != null)
-                               parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName.Basename,
+                               parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName,
                                        member.InterfaceType, this, member.IsExplicitImpl);
 
                        SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
@@ -1745,7 +1931,7 @@ namespace Mono.CSharp {
                        ModFlags |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.Conditional) {
                                Error_ConditionalAttributeIsNotValid ();
@@ -1760,17 +1946,17 @@ namespace Mono.CSharp {
                        if (!base.CheckBase ())
                                return false;
 
-                       if (Parent.PartialContainer.BaseCache == null)
+                       var base_type = Parent.PartialContainer.BaseType;
+                       if (base_type == null)
                                return true;
 
-                       Type base_type = Parent.PartialContainer.BaseCache.Container.Type;
-                       if (base_type != null && Block != null) {
-                               MethodGroupExpr method_expr = Expression.MethodLookup (Parent.Module.Compiler, Parent.TypeBuilder, base_type, MetadataName, Location);
+                       if (Block != null) {
+                               MethodGroupExpr method_expr = Expression.MethodLookup (Parent.Module.Compiler, Parent.Definition, base_type, MemberKind.Destructor, MetadataName, 0, Location);
                                if (method_expr == null)
                                        throw new NotImplementedException ();
 
                                method_expr.IsBase = true;
-                               method_expr.InstanceExpression = new CompilerGeneratedThis (Parent.TypeBuilder, Location);
+                               method_expr.InstanceExpression = new CompilerGeneratedThis (Parent.Definition, Location);
 
                                ToplevelBlock new_block = new ToplevelBlock (Compiler, Block.StartLocation);
                                new_block.EndLocation = Block.EndLocation;
@@ -1797,11 +1983,6 @@ namespace Mono.CSharp {
                        return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
                }
 
-               protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
-               {
-                       return null;
-               }
-
                public override string[] ValidAttributeTargets {
                        get {
                                return attribute_targets;
@@ -1891,18 +2072,18 @@ namespace Mono.CSharp {
                        }
                }
 
-               public Type[] ParameterTypes { 
+               public TypeSpec[] ParameterTypes { 
                        get {
                                return ParameterInfo.Types;
                        }
                }
 
                public abstract ParametersCompiled ParameterInfo { get ; }
-               public abstract Type ReturnType { get; }
+               public abstract TypeSpec ReturnType { get; }
 
                #endregion
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
                                Report.Error (1667, a.Location,
@@ -1919,7 +2100,7 @@ namespace Mono.CSharp {
                        }
 
                        if (a.Target == AttributeTargets.Method) {
-                               method_data.MethodBuilder.SetCustomAttribute (ctor, cdata);
+                               method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                                return;
                        }
 
@@ -1934,7 +2115,7 @@ namespace Mono.CSharp {
                        ApplyToExtraTarget (a, ctor, cdata, pa);
                }
 
-               protected virtual void ApplyToExtraTarget (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               protected virtual void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        throw new NotSupportedException ("You forgot to define special attribute target handling");
                }
@@ -1954,14 +2135,14 @@ namespace Mono.CSharp {
                        if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
                                PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
 
-                       if (TypeManager.IsDynamicType (ReturnType)) {
+                       if (ReturnType == InternalType.Dynamic) {
                                return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder);
                        } else {
                                var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType);
                                if (trans_flags != null) {
                                        var pa = PredefinedAttributes.Get.DynamicTransform;
-                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
                                                return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
                                                return_attributes.Builder.SetCustomAttribute (
                                                        new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
@@ -2005,7 +2186,7 @@ namespace Mono.CSharp {
                        if (!MemberName.Equals (method.MemberName))
                                return false;
 
-                       Type[] param_types = method.ParameterTypes;
+                       TypeSpec[] param_types = method.ParameterTypes;
 
                        if (param_types == null || param_types.Length != ParameterTypes.Length)
                                return false;
@@ -2136,7 +2317,7 @@ namespace Mono.CSharp {
                        Block = block;
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.Conditional) {
                                Error_ConditionalAttributeIsNotValid ();
@@ -2156,25 +2337,34 @@ namespace Mono.CSharp {
                        if (!base.Define ())
                                return false;
 
+                       if (block != null && block.IsIterator && !(Parent is IteratorStorey)) {
+                               //
+                               // Current method is turned into automatically generated
+                               // wrapper which creates an instance of iterator
+                               //
+                               Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
+                               ModFlags |= Modifiers.DEBUGGER_HIDDEN;
+                       }
+
                        // imlicit and explicit operator of same types are not allowed
                        if (OperatorType == OpType.Explicit)
-                               Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), Parameters, Report);
+                               Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);
                        else if (OperatorType == OpType.Implicit)
-                               Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), Parameters, Report);
+                               Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);
 
-                       Type declaring_type = MethodData.DeclaringType;
-                       Type return_type = MemberType;
-                       Type first_arg_type = ParameterTypes [0];
+                       TypeSpec declaring_type = Parent.CurrentType;
+                       TypeSpec return_type = MemberType;
+                       TypeSpec first_arg_type = ParameterTypes [0];
                        
-                       Type first_arg_type_unwrap = first_arg_type;
+                       TypeSpec first_arg_type_unwrap = first_arg_type;
                        if (TypeManager.IsNullableType (first_arg_type))
-                               first_arg_type_unwrap = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (first_arg_type) [0]);
+                               first_arg_type_unwrap = TypeManager.GetTypeArguments (first_arg_type) [0];
                        
-                       Type return_type_unwrap = return_type;
+                       TypeSpec return_type_unwrap = return_type;
                        if (TypeManager.IsNullableType (return_type))
-                               return_type_unwrap = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (return_type) [0]);
+                               return_type_unwrap = TypeManager.GetTypeArguments (return_type) [0];
 
-                       if (TypeManager.IsDynamicType (return_type) || TypeManager.IsDynamicType (first_arg_type)) {
+                       if (return_type == InternalType.Dynamic || first_arg_type == InternalType.Dynamic) {
                                Report.Error (1964, Location,
                                        "User-defined operator `{0}' cannot convert to or from the dynamic type",
                                        GetSignatureForError ());
@@ -2192,7 +2382,7 @@ namespace Mono.CSharp {
                                        return false;
                                }
                                
-                               Type conv_type;
+                               TypeSpec conv_type;
                                if (TypeManager.IsEqual (declaring_type, return_type) || declaring_type == return_type_unwrap) {
                                        conv_type = first_arg_type;
                                } else if (TypeManager.IsEqual (declaring_type, first_arg_type) || declaring_type == first_arg_type_unwrap) {
@@ -2228,11 +2418,11 @@ namespace Mono.CSharp {
                                        }
                                }
                        } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
-                               if (first_arg_type != declaring_type || Parameters.Types [1] != TypeManager.int32_type) {
+                               if (first_arg_type != declaring_type || parameters.Types[1] != TypeManager.int32_type) {
                                        Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
                                        return false;
                                }
-                       } else if (Parameters.Count == 1) {
+                       } else if (parameters.Count == 1) {
                                // Checks for Unary operators
 
                                if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
@@ -2269,7 +2459,7 @@ namespace Mono.CSharp {
 
                                var second_arg_type = ParameterTypes [1];
                                if (TypeManager.IsNullableType (second_arg_type))
-                                       second_arg_type = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (second_arg_type) [0]);
+                                       second_arg_type = TypeManager.GetTypeArguments (second_arg_type) [0];
 
                                if (!TypeManager.IsEqual (second_arg_type, declaring_type)) {
                                        Report.Error (563, Location,
@@ -2290,9 +2480,10 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               // Operator cannot be override
-               protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
+               protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate)
                {
+                       // Operator cannot be override
+                       bestCandidate = null;
                        return null;
                }
 
@@ -2363,136 +2554,15 @@ namespace Mono.CSharp {
                        StringBuilder sb = new StringBuilder ();
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
                                sb.AppendFormat ("{0}.{1} operator {2}",
-                                       Parent.GetSignatureForError (), GetName (OperatorType), type_name.GetSignatureForError ());
+                                       Parent.GetSignatureForError (), GetName (OperatorType), type_expr.GetSignatureForError ());
                        }
                        else {
                                sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
                        }
 
-                       sb.Append (Parameters.GetSignatureForError ());
+                       sb.Append (parameters.GetSignatureForError ());
                        return sb.ToString ();
                }
        }
-
-       //
-       // This is used to compare method signatures
-       //
-       struct MethodSignature {
-               public string Name;
-               public Type RetType;
-               public Type [] Parameters;
-               
-               /// <summary>
-               ///    This delegate is used to extract methods which have the
-               ///    same signature as the argument
-               /// </summary>
-               public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
-               
-               public MethodSignature (string name, Type ret_type, Type [] parameters)
-               {
-                       Name = name;
-                       RetType = ret_type;
-
-                       if (parameters == null)
-                               Parameters = Type.EmptyTypes;
-                       else
-                               Parameters = parameters;
-               }
-
-               public override string ToString ()
-               {
-                       string pars = "";
-                       if (Parameters.Length != 0){
-                               System.Text.StringBuilder sb = new System.Text.StringBuilder ();
-                               for (int i = 0; i < Parameters.Length; i++){
-                                       sb.Append (Parameters [i]);
-                                       if (i+1 < Parameters.Length)
-                                               sb.Append (", ");
-                               }
-                               pars = sb.ToString ();
-                       }
-
-                       return String.Format ("{0} {1} ({2})", RetType, Name, pars);
-               }
-               
-               public override int GetHashCode ()
-               {
-                       return Name.GetHashCode ();
-               }
-
-               public override bool Equals (Object o)
-               {
-                       MethodSignature other = (MethodSignature) o;
-
-                       if (other.Name != Name)
-                               return false;
-
-                       if (other.RetType != RetType)
-                               return false;
-                       
-                       if (Parameters == null){
-                               if (other.Parameters == null)
-                                       return true;
-                               return false;
-                       }
-
-                       if (other.Parameters == null)
-                               return false;
-                       
-                       int c = Parameters.Length;
-                       if (other.Parameters.Length != c)
-                               return false;
-
-                       for (int i = 0; i < c; i++)
-                               if (other.Parameters [i] != Parameters [i])
-                                       return false;
-
-                       return true;
-               }
-
-               static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
-               {
-                       MethodSignature sig = (MethodSignature) filter_criteria;
-
-                       if (m.Name != sig.Name)
-                               return false;
-
-                       Type ReturnType;
-                       MethodInfo mi = m as MethodInfo;
-                       PropertyInfo pi = m as PropertyInfo;
-
-                       if (mi != null)
-                               ReturnType = mi.ReturnType;
-                       else if (pi != null)
-                               ReturnType = pi.PropertyType;
-                       else
-                               return false;
-
-                       //
-                       // we use sig.RetType == null to mean `do not check the
-                       // method return value.  
-                       //
-                       if (sig.RetType != null) {
-                               if (!TypeManager.IsEqual (ReturnType, sig.RetType))
-                                       return false;
-                       }
-
-                       Type [] args;
-                       if (mi != null)
-                               args = TypeManager.GetParameterData (mi).Types;
-                       else
-                               args = TypeManager.GetParameterData (pi).Types;
-                       Type [] sigp = sig.Parameters;
-
-                       if (args.Length != sigp.Length)
-                               return false;
-
-                       for (int i = args.Length - 1; i >= 0; i--)
-                               if (!TypeManager.IsEqual (args [i], sigp [i]))
-                                       return false;
-
-                       return true;
-               }
-       }
 }
 
index bf1e540f0b41cc189182e962ed144a8d6823c0a0..788c1f891e001036adb75aead377ccb82673af5e 100644 (file)
@@ -33,6 +33,7 @@ namespace Mono.CSharp
                // Compiler specific flags
                //
                PROPERTY_CUSTOM                 = 0x4000,
+               OVERRIDE_UNCHECKED              = 0x8000,
                PARTIAL                                 = 0x20000,
                DEFAULT_ACCESS_MODIFER  = 0x40000,
                METHOD_EXTENSION                = 0x80000,
@@ -46,6 +47,24 @@ namespace Mono.CSharp
 
        static class ModifiersExtensions
        {
+               public static string AccessibilityName (Modifiers mod)
+               {
+                       switch (mod & Modifiers.AccessibilityMask) {
+                       case Modifiers.PUBLIC:
+                               return "public";
+                       case Modifiers.PROTECTED:
+                               return "protected";
+                       case Modifiers.PROTECTED | Modifiers.INTERNAL:
+                               return "protected internal";
+                       case Modifiers.INTERNAL:
+                               return "internal";
+                       case Modifiers.PRIVATE:
+                               return "private";
+                       default:
+                               throw new NotImplementedException (mod.ToString ());
+                       }
+               }
+
                static public string Name (Modifiers i)
                {
                        string s = "";
@@ -84,26 +103,24 @@ namespace Mono.CSharp
                        return s;
                }
 
-               public static string GetDescription (MethodAttributes ma)
+               //
+               // Used by custom property accessors to check whether @modA is more restrictive than @modB
+               //
+               public static bool IsRestrictedModifier (Modifiers modA, Modifiers modB)
                {
-                       ma &= MethodAttributes.MemberAccessMask;
+                       Modifiers flags = 0;
 
-                       if (ma == MethodAttributes.Assembly)
-                               return "internal";
+                       if ((modB & Modifiers.PUBLIC) != 0) {
+                               flags = Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
+                       } else if ((modB & Modifiers.PROTECTED) != 0) {
+                               if ((modB & Modifiers.INTERNAL) != 0)
+                                       flags = Modifiers.PROTECTED | Modifiers.INTERNAL;
 
-                       if (ma == MethodAttributes.Family)
-                               return "protected";
+                               flags |= Modifiers.PRIVATE;
+                       } else if ((modB & Modifiers.INTERNAL) != 0)
+                               flags = Modifiers.PRIVATE;
 
-                       if (ma == MethodAttributes.Public)
-                               return "public";
-
-                       if (ma == MethodAttributes.FamORAssem)
-                               return "protected internal";
-
-                       if (ma == MethodAttributes.Private)
-                               return "private";
-
-                       throw new NotImplementedException (ma.ToString ());
+                       return modB != modA && (modA & (~flags)) == 0;
                }
 
                public static TypeAttributes TypeAttr (Modifiers mod_flags, bool is_toplevel)
@@ -166,18 +183,24 @@ namespace Mono.CSharp
                {
                        MethodAttributes ma = MethodAttributes.HideBySig;
 
-                       if ((mod_flags & Modifiers.PUBLIC) != 0)
+                       switch (mod_flags & Modifiers.AccessibilityMask) {
+                       case Modifiers.PUBLIC:
                                ma |= MethodAttributes.Public;
-                       else if ((mod_flags & Modifiers.PRIVATE) != 0)
+                               break;
+                       case Modifiers.PRIVATE:
                                ma |= MethodAttributes.Private;
-                       else if ((mod_flags & Modifiers.PROTECTED) != 0) {
-                               if ((mod_flags & Modifiers.INTERNAL) != 0)
-                                       ma |= MethodAttributes.FamORAssem;
-                               else 
-                                       ma |= MethodAttributes.Family;
-                       } else {
-                               if ((mod_flags & Modifiers.INTERNAL) != 0)
-                                       ma |= MethodAttributes.Assembly;
+                               break;
+                       case Modifiers.PROTECTED | Modifiers.INTERNAL:
+                               ma |= MethodAttributes.FamORAssem;
+                               break;
+                       case Modifiers.PROTECTED:
+                               ma |= MethodAttributes.Family;
+                               break;
+                       case Modifiers.INTERNAL:
+                               ma |= MethodAttributes.Assembly;
+                               break;
+                       default:
+                               throw new NotImplementedException (mod_flags.ToString ());
                        }
 
                        if ((mod_flags & Modifiers.STATIC) != 0)
@@ -191,9 +214,9 @@ namespace Mono.CSharp
                        if ((mod_flags & Modifiers.VIRTUAL) != 0)
                                ma |= MethodAttributes.Virtual;
 
-                       if ((mod_flags & Modifiers.OVERRIDE) != 0)
+                       if ((mod_flags & Modifiers.OVERRIDE) != 0) {
                                ma |= MethodAttributes.Virtual;
-                       else {
+                       else {
                                if ((ma & MethodAttributes.Virtual) != 0)
                                        ma |= MethodAttributes.NewSlot;
                        }
@@ -240,7 +263,7 @@ namespace Mono.CSharp
                                a = ((a & 2) >> 1) + (a & 5);
                                a = ((a & 4) >> 2) + (a & 3);
                                if (a > 1)
-                                       Report.Error (107, l, "More than one protection modifier specified", Report);
+                                       Report.Error (107, l, "More than one protection modifier specified");
                                
                                return mod;
                        }
@@ -257,7 +280,7 @@ namespace Mono.CSharp
 
                public static void Error_InvalidModifier (Location l, string name, Report Report)
                {
-                       Report.Error (106, l, "The modifier `" + name + "' is not valid for this item", Report);
+                       Report.Error (106, l, "The modifier `{0}' is not valid for this item", name);
                }
        }
 }
index f40d3ba2837ad0fcef427a52bf770427e0608da9..3e9140e9649e3927b8d9a298f22a787f0c927cbd 100644 (file)
 using System;
 using System.Collections.Generic;
 using System.Reflection;
+using System.Linq;
 
 namespace Mono.CSharp {
 
        public class RootNamespace : Namespace {
-               //
-               // Points to Mono's GetNamespaces method, an
-               // optimization when running on Mono to fetch all the
-               // namespaces in an assembly
-               //
-               static MethodInfo get_namespaces_method;
 
                protected readonly string alias_name;
                protected Assembly [] referenced_assemblies;
 
                Dictionary<string, Namespace> all_namespaces;
 
-               static RootNamespace ()
-               {
-                       get_namespaces_method = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance | BindingFlags.NonPublic);
-               }
-
                public RootNamespace (string alias_name)
                        : base (null, String.Empty)
                {
@@ -56,11 +46,11 @@ namespace Mono.CSharp {
                        referenced_assemblies = n;
                }
 
-               public void ComputeNamespace (CompilerContext ctx, Type extensionType)
+               public void ImportTypes (CompilerContext ctx)
                {
                        foreach (Assembly a in referenced_assemblies) {
                                try {
-                                       ComputeNamespaces (a, extensionType);
+                                       ImportAssembly (a);
                                } catch (TypeLoadException e) {
                                        ctx.Report.Error (11, Location.Null, e.Message);
                                } catch (System.IO.FileNotFoundException) {
@@ -70,77 +60,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public virtual Type LookupTypeReflection (CompilerContext ctx, string name, Location loc, bool must_be_unique)
-               {
-                       // FIXME: Breaks dynamic
-                       Assembly invocation_assembly = CodeGen.Assembly.Builder;
-
-                       Type found_type = null;
-                       foreach (Assembly a in referenced_assemblies) {
-                               Type t = GetTypeInAssembly (invocation_assembly, a, name);
-                               if (t == null)
-                                       continue;
-
-                               if (!must_be_unique)
-                                       return t;
-
-                               if (found_type == null) {
-                                       found_type = t;
-                                       continue;
-                               }
-
-                               // When type is forwarded
-                               if (t.Assembly == found_type.Assembly)
-                                       continue;                                       
-
-                               ctx.Report.SymbolRelatedToPreviousError (found_type);
-                               ctx.Report.SymbolRelatedToPreviousError (t);
-                               if (loc.IsNull) {
-                                       Error_AmbiguousPredefinedType (ctx, loc, name, found_type);
-                               } else {
-                                       ctx.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", name);
-                               }
-
-                               return found_type;
-                       }
-
-                       return found_type;
-               }
-
-               //
-               // Returns the types starting with the given prefix
-               //
-               public ICollection<string> CompletionGetTypesStartingWith (string prefix)
-               {
-                       Dictionary<string, string> result = null;
-
-                       foreach (Assembly a in referenced_assemblies){
-                               Type [] mtypes = a.GetTypes ();
-
-                               foreach (Type t in mtypes){
-                                       if (t.IsNotPublic)
-                                               continue;
-                                       
-                                       string f = t.FullName;
-
-                                       if (f.StartsWith (prefix) && (result == null || !result.ContainsKey (f))){
-                                               if (result == null)
-                                                       result = new Dictionary<string, string> ();
-
-                                               result [f] = f;
-                                       }
-                               }
-                       }
-                       return result == null ? null : result.Keys;
-               }
-               
-               protected static void Error_AmbiguousPredefinedType (CompilerContext ctx, Location loc, string name, Type type)
-               {
-                       ctx.Report.Warning (1685, 1, loc,
-                               "The predefined type `{0}' is ambiguous. Using definition from `{1}'",
-                               name, type.Assembly.FullName);
-               }
-
                public void RegisterNamespace (Namespace child)
                {
                        if (child != this)
@@ -158,74 +77,43 @@ namespace Mono.CSharp {
                                GetNamespace (dotted_name, true);
                }
 
-               void RegisterExtensionMethodClass (Type t)
-               {
-                       string n = t.Namespace;
-                       Namespace ns = null;
-                       if (n == null)
-                               ns = GlobalRootNamespace.Instance;
-                       else
-                               all_namespaces.TryGetValue (n, out ns);
-
-                       if (ns == null)
-                               ns = GetNamespace (n, true);
-                       ns.RegisterExternalExtensionMethodClass (t);
-               }
-
-               void ComputeNamespaces (Assembly assembly, Type extensionType)
+               public void ImportAssembly (Assembly assembly)
                {
-                       bool contains_extension_methods = extensionType != null && assembly.IsDefined (extensionType, false);
-                       if (get_namespaces_method != null) {
-                               string [] namespaces = (string []) get_namespaces_method.Invoke (assembly, null);
-                               foreach (string ns in namespaces)
-                                       RegisterNamespace (ns);
-
-                               if (!contains_extension_methods)
-                                       return;
-                       }
-
-                       foreach (Type t in assembly.GetTypes ()) {
-                               if ((t.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
-                                       contains_extension_methods && t.IsDefined (extensionType, false))
-                                       RegisterExtensionMethodClass (t);
-
-                               if (get_namespaces_method == null)
-                                       RegisterNamespace (t.Namespace);
-                       }
-               }
+                       Type extension_type = null;
+                       var all_attributes = CustomAttributeData.GetCustomAttributes (assembly);
+                       foreach (var attr in all_attributes) {
+                               var dt = attr.Constructor.DeclaringType;
+                               if (dt.Name == "ExtensionAttribute" && dt.Namespace == "System.Runtime.CompilerServices") {
+                                       extension_type = dt;
+                                       break;
+                               }
+                       }
 
-               protected static Type GetTypeInAssembly (Assembly invocation, Assembly assembly, string name)
-               {
-                       if (assembly == null)
-                               throw new ArgumentNullException ("assembly");
-                       if (name == null)
-                               throw new ArgumentNullException ("name");
-                       Type t = assembly.GetType (name);
-                       if (t == null)
-                               return null;
+                       Namespace ns = this;
+                       string prev_namespace = null;
+                       foreach (var t in assembly.GetTypes ()) {
+                               if (t.IsNested)
+                                       continue;
 
-                       if (t.IsPointer)
-                               throw new InternalErrorException ("Use GetPointerType() to get a pointer");
+                               if (t.Name[0] == '<')
+                                       continue;
 
-                       TypeAttributes ta = t.Attributes & TypeAttributes.VisibilityMask;
-                       if (ta == TypeAttributes.NestedPrivate)
-                               return null;
+                               var it = Import.CreateType (t);
+                               if (it == null)
+                                       continue;
 
-                       if ((ta == TypeAttributes.NotPublic ||
-                            ta == TypeAttributes.NestedAssembly ||
-                            ta == TypeAttributes.NestedFamANDAssem) &&
-                           !TypeManager.IsThisOrFriendAssembly (invocation, t.Assembly))
-                               return null;
+                               if (prev_namespace != t.Namespace) {
+                                       ns = t.Namespace == null ? this : GetNamespace (t.Namespace, true);
+                                       prev_namespace = t.Namespace;
+                               }
 
-                       return t;
-               }
+                               ns.AddType (it);
 
-               public override string ToString ()
-               {
-                       return String.Format ("RootNamespace ({0}::)", alias_name);
-               }
+                               if (it.IsStatic && extension_type != null && t.IsDefined (extension_type, false)) {
+                                       it.SetExtensionMethodContainer ();
+                               }
+                       }
+               }
 
                public override string GetSignatureForError ()
                {
@@ -271,20 +159,14 @@ namespace Mono.CSharp {
                        if (m == RootContext.ToplevelTypes.Builder)
                                return;
 
-                       foreach (Type t in m.GetTypes ())
+                       foreach (var t in m.GetTypes ())
                                RegisterNamespace (t.Namespace);
                }
 
                public void ComputeNamespaces (CompilerContext ctx)
                {
-                       //
-                       // Do very early lookup because type is required when we cache
-                       // imported extension types in ComputeNamespaces
-                       //
-                       Type extension_attribute_type = TypeManager.CoreLookupType (ctx, "System.Runtime.CompilerServices", "ExtensionAttribute", MemberKind.Class, false);
-
                        foreach (RootNamespace rn in root_namespaces.Values) {
-                               rn.ComputeNamespace (ctx, extension_attribute_type);
+                               rn.ImportTypes (ctx);
                        }
                }
 
@@ -304,7 +186,7 @@ namespace Mono.CSharp {
                        retval.AddAssemblyReference (assembly);
                }
 
-               public override void Error_NamespaceDoesNotExist (Location loc, string name, IMemberContext ctx)
+               public override void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
                {
                        ctx.Compiler.Report.Error (400, loc,
                                "The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
@@ -319,37 +201,6 @@ namespace Mono.CSharp {
 
                        return rn;
                }
-
-               public override Type LookupTypeReflection (CompilerContext ctx, string name, Location loc, bool must_be_unique)
-               {
-                       Type found_type = base.LookupTypeReflection (ctx, name, loc, must_be_unique);
-
-                       if (modules != null) {
-                               foreach (Module module in modules) {
-                                       Type t = module.GetType (name);
-                                       if (t == null)
-                                               continue;
-
-                                       if (found_type == null) {
-                                               found_type = t;
-                                               continue;
-                                       }
-
-                                       ctx.Report.SymbolRelatedToPreviousError (found_type);
-                                       if (loc.IsNull) {
-                                               DeclSpace ds = TypeManager.LookupDeclSpace (t);
-                                               Error_AmbiguousPredefinedType (ctx, ds.Location, name, found_type);
-                                               return found_type;
-                                       }
-                                       ctx.Report.SymbolRelatedToPreviousError (t);
-                                       ctx.Report.Warning (436, 2, loc, "The type `{0}' conflicts with the imported type `{1}'. Ignoring the imported type definition",
-                                               TypeManager.CSharpName (t), TypeManager.CSharpName (found_type));
-                                       return t;
-                               }
-                       }
-
-                       return found_type;
-               }
        }
 
        /// <summary>
@@ -362,11 +213,11 @@ namespace Mono.CSharp {
                
                Namespace parent;
                string fullname;
-               Dictionary<string, Namespace> namespaces;
-               Dictionary<string, DeclSpace> declspaces;
+               protected Dictionary<string, Namespace> namespaces;
+               protected Dictionary<string, IList<TypeSpec>> types;
                Dictionary<string, TypeExpr> cached_types;
                RootNamespace root;
-               List<Type> external_exmethod_classes;
+               bool cls_checked;
 
                public readonly MemberName MemberName;
 
@@ -379,7 +230,7 @@ namespace Mono.CSharp {
                {
                        // Expression members.
                        this.eclass = ExprClass.Namespace;
-                       this.Type = typeof (Namespace);
+                       this.Type = InternalType.FakeInternalType;
                        this.loc = Location.Null;
 
                        this.parent = parent;
@@ -415,25 +266,42 @@ namespace Mono.CSharp {
                        root.RegisterNamespace (this);
                }
 
+               #region Properties
+
+               /// <summary>
+               ///   The qualified name of the current namespace
+               /// </summary>
+               public string Name {
+                       get { return fullname; }
+               }
+
+               /// <summary>
+               ///   The parent of this namespace, used by the parser to "Pop"
+               ///   the current namespace declaration
+               /// </summary>
+               public Namespace Parent {
+                       get { return parent; }
+               }
+
+               #endregion
+
                protected override Expression DoResolve (ResolveContext ec)
                {
                        return this;
                }
 
-               public virtual void Error_NamespaceDoesNotExist (Location loc, string name, IMemberContext ctx)
+               public virtual void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
                {
-                       if (name.IndexOf ('`') > 0) {
-                               FullNamedExpression retval = Lookup (ctx.Compiler, SimpleName.RemoveGenericArity (name), loc);
-                               if (retval != null) {
-                                       retval.Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc);
-                                       return;
-                               }
-                       } else {
-                               Type t = LookForAnyGenericType (name);
-                               if (t != null) {
-                                       Error_InvalidNumberOfTypeArguments (ctx.Compiler.Report, t, loc);
-                                       return;
-                               }
+                       FullNamedExpression retval = Lookup (ctx.Compiler, name, -System.Math.Max (1, arity), loc);
+                       if (retval != null) {
+                               Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, retval.Type, arity);
+                               return;
+                       }
+
+                       Namespace ns;
+                       if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
+                               ns.Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, null, arity);
+                               return;
                        }
 
                        ctx.Compiler.Report.Error (234, loc,
@@ -441,13 +309,6 @@ namespace Mono.CSharp {
                                name, GetSignatureForError ());
                }
 
-               public static void Error_InvalidNumberOfTypeArguments (Report report, Type t, Location loc)
-               {
-                       report.SymbolRelatedToPreviousError (t);
-                       report.Error (305, loc, "Using the generic type `{0}' requires `{1}' type argument(s)",
-                               TypeManager.CSharpName(t), TypeManager.GetNumberOfTypeArguments(t).ToString());
-               }
-
                public override string GetSignatureForError ()
                {
                        return fullname;
@@ -478,204 +339,318 @@ namespace Mono.CSharp {
                        return ns;
                }
 
-               public bool HasDefinition (string name)
+               TypeExpr LookupType (CompilerContext ctx, string name, int arity, Location loc)
                {
-                       return declspaces != null && declspaces.ContainsKey (name);
-               }
+                       if (types == null)
+                               return null;
 
-               TypeExpr LookupType (CompilerContext ctx, string name, Location loc)
-               {
                        TypeExpr te;
-                       if (cached_types.TryGetValue (name, out te))
+                       if (arity == 0 && cached_types.TryGetValue (name, out te))
                                return te;
 
-                       Type t = null;
-                       if (declspaces != null) {
-                               DeclSpace tdecl;
-                               if (declspaces.TryGetValue (name, out tdecl)) {
-                                       //
-                                       // Note that this is not:
-                                       //
-                                       //   t = tdecl.DefineType ()
-                                       //
-                                       // This is to make it somewhat more useful when a DefineType
-                                       // fails due to problems in nested types (more useful in the sense
-                                       // of fewer misleading error messages)
-                                       //
-                                       tdecl.DefineType ();
-                                       t = tdecl.TypeBuilder;
-
-                                       if (RootContext.EvalMode){
-                                               // Replace the TypeBuilder with a System.Type, as
-                                               // Reflection.Emit fails otherwise (we end up pretty
-                                               // much with Random type definitions later on).
-                                               Type tt = t.Assembly.GetType (t.Name);
-                                               if (tt != null)
-                                                       t = tt;
+                       IList<TypeSpec> found;
+                       if (!types.TryGetValue (name, out found))
+                               return null;
+
+                       TypeSpec best = null;
+                       foreach (var ts in found) {
+                               if (ts.Arity == arity) {
+                                       if (best == null) {
+                                               best = ts;
+                                               continue;
+                                       }
+
+                                       if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
+                                               ctx.Report.SymbolRelatedToPreviousError (best);
+                                               ctx.Report.SymbolRelatedToPreviousError (ts);
+                                               ctx.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
+                                               break;
+                                       }
+
+                                       var pts = best as PredefinedTypeSpec;
+                                       if (pts == null)
+                                               pts = ts as PredefinedTypeSpec;
+
+                                       if (pts != null) {
+                                               ctx.Report.SymbolRelatedToPreviousError (best);
+                                               ctx.Report.SymbolRelatedToPreviousError (ts);
+                                               ctx.Report.Warning (1685, 1, loc,
+                                                       "The predefined type `{0}.{1}' is redefined in the source code. Ignoring the local type definition",
+                                                       pts.Namespace, pts.Name);
+                                               best = pts;
+                                               continue;
+                                       }
+
+                                       if (best.MemberDefinition.IsImported)
+                                               best = ts;
+
+                                       if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, best.MemberDefinition.Assembly))
+                                               continue;
+
+                                       if (ts.MemberDefinition.IsImported)
+                                               ctx.Report.SymbolRelatedToPreviousError (ts);
+
+                                       ctx.Report.Warning (436, 2, loc,
+                                               "The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",
+                                               best.GetSignatureForError ());
+                               }
+
+                               //
+                               // Lookup for the best candidate with closest arity match
+                               //
+                               if (arity < 0) {
+                                       if (best == null) {
+                                               best = ts;
+                                       } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
+                                               best = ts;
                                        }
                                }
                        }
-                       string lookup = t != null ? t.FullName : (fullname.Length == 0 ? name : fullname + "." + name);
-                       Type rt = root.LookupTypeReflection (ctx, lookup, loc, t == null);
 
-                       // HACK: loc.IsNull when the type is core type
-                       if (t == null || (rt != null && loc.IsNull))
-                               t = rt;
+                       if (best == null)
+                               return null;
+
+                       te = new TypeExpression (best, Location.Null);
+
+                       // TODO MemberCache: Cache more
+                       if (arity == 0)
+                               cached_types.Add (name, te);
 
-                       te = t == null ? null : new TypeExpression (t, Location.Null);
-                       cached_types [name] = te;
                        return te;
                }
 
-               ///
-               /// Used for better error reporting only
-               /// 
-               public Type LookForAnyGenericType (string typeName)
+               TypeSpec LookupType (string name, int arity)
                {
-                       if (declspaces == null)
+                       if (types == null)
                                return null;
 
-                       typeName = SimpleName.RemoveGenericArity (typeName);
+                       IList<TypeSpec> found;
+                       if (types.TryGetValue (name, out found)) {
+                               TypeSpec best = null;
+
+                               foreach (var ts in found) {
+                                       if (ts.Arity == arity)
+                                               return ts;
 
-                       foreach (var de in declspaces) {
-                               string type_item = de.Key;
-                               int pos = type_item.LastIndexOf ('`');
-                               if (pos == typeName.Length && String.Compare (typeName, 0, type_item, 0, pos) == 0)
-                                       return de.Value.TypeBuilder;
+                                       //
+                                       // Lookup for the best candidate with closest arity match
+                                       //
+                                       if (arity < 0) {
+                                               if (best == null) {
+                                                       best = ts;
+                                               } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best.Arity + arity)) {
+                                                       best = ts;
+                                               }
+                                       }
+                               }
+                               
+                               return best;
                        }
+
                        return null;
                }
 
-               public FullNamedExpression Lookup (CompilerContext ctx, string name, Location loc)
+               public FullNamedExpression Lookup (CompilerContext ctx, string name, int arity, Location loc)
                {
-                       if (namespaces.ContainsKey (name))
+                       if (arity == 0 && namespaces.ContainsKey (name))
                                return namespaces [name];
 
-                       return LookupType (ctx, name, loc);
+                       return LookupType (ctx, name, arity, loc);
                }
 
                //
-               // Completes types with the given `prefix' and stores the results in `result'
+               // Completes types with the given `prefix'
                //
-               public void CompletionGetTypesStartingWith (string prefix, Dictionary<string, string> result)
+               public IEnumerable<string> CompletionGetTypesStartingWith (string prefix)
                {
-                       int l = fullname.Length + 1;
-                       var res = root.CompletionGetTypesStartingWith (fullname + "." + prefix);
-
-                       if (res == null)
-                               return;
-                       
-                       foreach (string match in res){
-                               string x = match.Substring (l);
+                       if (types == null)
+                               return Enumerable.Empty<string> ();
 
-                               // Turn reflection nested classes foo+bar into foo.bar
-                               x = x.Replace ('+', '.');
+                       var res = from item in types
+                                         where item.Key.StartsWith (prefix) && item.Value.Any (l => (l.Modifiers & Modifiers.PUBLIC) != 0)
+                                         select item.Key;
 
-                               // Only get the first name element, no point in adding anything beyond the first dot.
-                               int p = x.IndexOf ('.');
-                               if (p != -1)
-                                       x = x.Substring (0, p);
+                       if (namespaces != null)
+                               res = res.Concat (from item in namespaces where item.Key.StartsWith (prefix) select item.Key);
 
-                               // Turn Foo`N into Foo<
-                               p = x.IndexOf ('`');
-                               if (p != -1)
-                                       x = x.Substring (0, p) + "<";
-
-                               if (!result.ContainsKey (x))
-                                       result [x] = x;
-                       }
-               }
-
-               public void RegisterExternalExtensionMethodClass (Type type)
-               {
-                       // Ignore, extension methods cannot be nested
-                       if (type.DeclaringType != null)
-                               return;
-
-                       // TODO: CodeGen.Assembly.Builder is global
-                       if (type.IsNotPublic && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, type.Assembly))
-                               return;
-
-                       if (external_exmethod_classes == null)
-                               external_exmethod_classes = new List<Type> ();
-
-                       external_exmethod_classes.Add (type);
+                       return res;
                }
 
                /// 
                /// Looks for extension method in this namespace
                /// 
-               public List<MethodSpec> LookupExtensionMethod (Type extensionType, ClassOrStruct currentClass, string name)
+               public List<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, ClassOrStruct currentClass, string name, int arity)
                {
+                       if (types == null)
+                               return null;
+
                        List<MethodSpec> found = null;
 
-                       // TODO: problematic
-                       var invocation_assembly = CodeGen.Assembly.Builder;
+                       var invocation_type = currentClass == null ? InternalType.FakeInternalType : currentClass.CurrentType;
 
-                       if (declspaces != null) {
-                               var e = declspaces.Values.GetEnumerator ();
-                               while (e.MoveNext ()) {
-                                       Class c = e.Current as Class;
-                                       if (c == null)
-                                               continue;
+                       // TODO: Add per namespace flag when at least 1 type has extension
 
-                                       if ((c.ModFlags & Modifiers.METHOD_EXTENSION) == 0)
+                       foreach (var tgroup in types.Values) {
+                               foreach (var ts in tgroup) {
+                                       if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0)
                                                continue;
 
-                                       var res = c.MemberCache.FindExtensionMethods (invocation_assembly, extensionType, name, c != currentClass);
+                                       var res = ts.MemberCache.FindExtensionMethods (invocation_type, extensionType, name, arity);
                                        if (res == null)
                                                continue;
 
-                                       if (found == null)
+                                       if (found == null) {
                                                found = res;
-                                       else
+                                       } else {
                                                found.AddRange (res);
+                                       }
                                }
                        }
 
-                       if (external_exmethod_classes == null)
-                               return found;
-
-                       foreach (Type t in external_exmethod_classes) {
-                               MemberCache m = TypeHandle.GetMemberCache (t);
-                               var res = m.FindExtensionMethods (invocation_assembly, extensionType, name, true);
-                               if (res == null)
-                                       continue;
+                       return found;
+               }
 
-                               if (found == null)
-                                       found = res;
-                               else
-                                       found.AddRange (res);
+               public void AddType (TypeSpec ts)
+               {
+                       if (types == null) {
+                               types = new Dictionary<string, IList<TypeSpec>> (64);
                        }
 
-                       return found;
+                       var name = ts.Name;
+                       IList<TypeSpec> existing;
+                       if (types.TryGetValue (name, out existing)) {
+                               TypeSpec better_type;
+                               TypeSpec found;
+                               if (existing.Count == 1) {
+                                       found = existing[0];
+                                       if (ts.Arity == found.Arity) {
+                                               better_type = IsImportedTypeOverride (ts, found);
+                                               if (better_type == found)
+                                                       return;
+
+                                               if (better_type != null) {
+                                                       existing [0] = better_type;
+                                                       return;
+                                               }
+                                       }
+
+                                       existing = new List<TypeSpec> ();
+                                       existing.Add (found);
+                                       types[name] = existing;
+                               } else {
+                                       for (int i = 0; i < existing.Count; ++i) {
+                                               found = existing[i];
+                                               if (ts.Arity != found.Arity)
+                                                       continue;
+
+                                               better_type = IsImportedTypeOverride (ts, found);
+                                               if (better_type == found)
+                                                       return;
+
+                                               if (better_type != null) {
+                                                       existing.RemoveAt (i);
+                                                       --i;
+                                                       continue;
+                                               }
+                                       }
+                               }
+
+                               existing.Add (ts);
+                       } else {
+                               types.Add (name, new TypeSpec[] { ts });
+                       }
                }
 
-               public void AddDeclSpace (string name, DeclSpace ds)
+               //
+               // We import any types but in the situation there are same types
+               // but one has better visibility (either public or internal with friend)
+               // the less visible type is removed from the namespace cache
+               //
+               public static TypeSpec IsImportedTypeOverride (TypeSpec ts, TypeSpec found)
                {
-                       if (declspaces == null)
-                               declspaces = new Dictionary<string, DeclSpace> ();
-                       declspaces.Add (name, ds);
+                       var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, ts.MemberDefinition.Assembly);
+                       var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, found.MemberDefinition.Assembly);
+
+                       if (ts_accessible && !found_accessible)
+                               return ts;
+
+                       // found is better always better for accessible or inaccessible ts
+                       if (!ts_accessible)
+                               return found;
+
+                       return null;
                }
 
                public void RemoveDeclSpace (string name)
                {
-                       declspaces.Remove (name);
+                       types.Remove (name);
                }
-               
-               /// <summary>
-               ///   The qualified name of the current namespace
-               /// </summary>
-               public string Name {
-                       get { return fullname; }
+
+               public void ReplaceTypeWithPredefined (TypeSpec ts, PredefinedTypeSpec pts)
+               {
+                       var found = types [ts.Name];
+                       cached_types.Remove (ts.Name);
+                       if (found.Count == 1) {
+                               types[ts.Name][0] = pts;
+                       } else {
+                               throw new NotImplementedException ();
+                       }
                }
 
-               /// <summary>
-               ///   The parent of this namespace, used by the parser to "Pop"
-               ///   the current namespace declaration
-               /// </summary>
-               public Namespace Parent {
-                       get { return parent; }
+               public void VerifyClsCompliance ()
+               {
+                       if (types == null || cls_checked)
+                               return;
+
+                       cls_checked = true;
+
+                       // TODO: This is quite ugly way to check for CLS compliance at namespace level
+
+                       var locase_types = new Dictionary<string, List<TypeSpec>> (StringComparer.OrdinalIgnoreCase);
+                       foreach (var tgroup in types.Values) {
+                               foreach (var tm in tgroup) {
+                                       if ((tm.Modifiers & Modifiers.PUBLIC) == 0 || !tm.IsCLSCompliant ())
+                                               continue;
+
+                                       List<TypeSpec> found;
+                                       if (!locase_types.TryGetValue (tm.Name, out found)) {
+                                               found = new List<TypeSpec> ();
+                                               locase_types.Add (tm.Name, found);
+                                       }
+
+                                       found.Add (tm);
+                               }
+                       }
+
+                       foreach (var locase in locase_types.Values) {
+                               if (locase.Count < 2)
+                                       continue;
+
+                               bool all_same = true;
+                               foreach (var notcompliant in locase) {
+                                       all_same = notcompliant.Name == locase[0].Name;
+                                       if (!all_same)
+                                               break;
+                               }
+
+                               if (all_same)
+                                       continue;
+
+                               TypeContainer compiled = null;
+                               foreach (var notcompliant in locase) {
+                                       if (!notcompliant.MemberDefinition.IsImported) {
+                                               if (compiled != null)
+                                                       compiled.Compiler.Report.SymbolRelatedToPreviousError (compiled);
+
+                                               compiled = notcompliant.MemberDefinition as TypeContainer;
+                                       } else {
+                                               compiled.Compiler.Report.SymbolRelatedToPreviousError (notcompliant);
+                                       }
+                               }
+
+                               compiled.Compiler.Report.Warning (3005, 1, compiled.Location,
+                                       "Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ());
+                       }
                }
        }
 
@@ -789,7 +764,7 @@ namespace Mono.CSharp {
                                }
 
                                if (resolved is TypeExpr)
-                                       resolved = resolved.ResolveAsBaseTerminal (rc, false);
+                                       resolved = resolved.ResolveAsTypeTerminal (rc, false);
 
                                return resolved;
                        }
@@ -1034,11 +1009,11 @@ namespace Mono.CSharp {
                /// Does extension methods look up to find a method which matches name and extensionType.
                /// Search starts from this namespace and continues hierarchically up to top level.
                ///
-               public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
+               public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
                {
                        List<MethodSpec> candidates = null;
                        foreach (Namespace n in GetUsingTable ()) {
-                               var a = n.LookupExtensionMethod (extensionType, null, name);
+                               var a = n.LookupExtensionMethod (extensionType, null, name, arity);
                                if (a == null)
                                        continue;
 
@@ -1059,7 +1034,7 @@ namespace Mono.CSharp {
                        //
                        Namespace parent_ns = ns.Parent;
                        do {
-                               candidates = parent_ns.LookupExtensionMethod (extensionType, null, name);
+                               candidates = parent_ns.LookupExtensionMethod (extensionType, null, name, arity);
                                if (candidates != null)
                                        return new ExtensionMethodGroupExpr (candidates, parent, extensionType, loc);
 
@@ -1069,23 +1044,24 @@ namespace Mono.CSharp {
                        //
                        // Continue in parent scope
                        //
-                       return parent.LookupExtensionMethod (extensionType, name, loc);
+                       return parent.LookupExtensionMethod (extensionType, name, arity, loc);
                }
 
-               public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
+               public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
                {
                        // Precondition: Only simple names (no dots) will be looked up with this function.
                        FullNamedExpression resolved = null;
                        for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
-                               if ((resolved = curr_ns.Lookup (name, loc, ignore_cs0104)) != null)
+                               if ((resolved = curr_ns.Lookup (name, arity, loc, ignore_cs0104)) != null)
                                        break;
                        }
+
                        return resolved;
                }
 
-               public ICollection<string> CompletionGetTypesStartingWith (string prefix)
+               public IList<string> CompletionGetTypesStartingWith (string prefix)
                {
-                       var result = new Dictionary<string, string> ();
+                       IEnumerable<string> all = Enumerable.Empty<string> ();
                        
                        for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent){
                                foreach (Namespace using_ns in GetUsingTable ()){
@@ -1094,24 +1070,16 @@ namespace Mono.CSharp {
                                                if (ld != -1){
                                                        string rest = prefix.Substring (ld+1);
 
-                                                       using_ns.CompletionGetTypesStartingWith (rest, result);
+                                                       all = all.Concat (using_ns.CompletionGetTypesStartingWith (rest));
                                                }
                                        }
-                                       using_ns.CompletionGetTypesStartingWith (prefix, result);
+                                       all = all.Concat (using_ns.CompletionGetTypesStartingWith (prefix));
                                }
                        }
 
-                       return result.Keys;
+                       return all.Distinct ().ToList ();
                }
                
-               void Error_AmbiguousTypeReference (Location loc, string name, FullNamedExpression t1, FullNamedExpression t2)
-               {
-                       Compiler.Report.SymbolRelatedToPreviousError (t1.Type);
-                       Compiler.Report.SymbolRelatedToPreviousError (t2.Type);
-                       Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
-                               name, t1.GetSignatureForError (), t2.GetSignatureForError ());
-               }
-
                // Looks-up a alias named @name in this and surrounding namespace declarations
                public FullNamedExpression LookupNamespaceAlias (string name)
                {
@@ -1128,17 +1096,17 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               private FullNamedExpression Lookup (string name, Location loc, bool ignore_cs0104)
+               private FullNamedExpression Lookup (string name, int arity, Location loc, bool ignore_cs0104)
                {
                        //
                        // Check whether it's in the namespace.
                        //
-                       FullNamedExpression fne = ns.Lookup (Compiler, name, loc);
+                       FullNamedExpression fne = ns.Lookup (Compiler, name, arity, loc);
 
                        //
                        // Check aliases. 
                        //
-                       if (using_aliases != null) {
+                       if (using_aliases != null && arity == 0) {
                                foreach (UsingAliasEntry ue in using_aliases) {
                                        if (ue.Alias == name) {
                                                if (fne != null) {
@@ -1159,8 +1127,10 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (fne != null)
-                               return fne;
+                       if (fne != null) {
+                               if (!((fne.Type.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, fne.Type.Assembly)))
+                                       return fne;
+                       }
 
                        if (IsImplicit)
                                return null;
@@ -1170,18 +1140,43 @@ namespace Mono.CSharp {
                        //
                        FullNamedExpression match = null;
                        foreach (Namespace using_ns in GetUsingTable ()) {
-                               match = using_ns.Lookup (Compiler, name, loc);
-                               if (match == null || !(match is TypeExpr))
+                               fne = using_ns.Lookup (Compiler, name, arity, loc);
+                               if (fne == null)
+                                       continue;
+
+                               if (match == null) {
+                                       match = fne;
                                        continue;
-                               if (fne != null) {
-                                       if (!ignore_cs0104)
-                                               Error_AmbiguousTypeReference (loc, name, fne, match);
-                                       return null;
                                }
-                               fne = match;
+
+                               // Prefer types over namespaces
+                               var texpr_fne = fne as TypeExpr;
+                               var texpr_match = match as TypeExpr;
+                               if (texpr_fne != null && texpr_match == null) {
+                                       match = fne;
+                                       continue;
+                               } else if (texpr_fne == null && texpr_match != null) {
+                                       continue;
+                               }
+
+                               if (ignore_cs0104)
+                                       return match;
+
+                               // It can be top level accessibility only
+                               var better = Namespace.IsImportedTypeOverride (texpr_match.Type, texpr_fne.Type);
+                               if (better == null) {
+                                       Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
+                                       Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
+                                       Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
+                                               name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
+                                       return match;
+                               }
+
+                               if (better == texpr_fne.Type)
+                                       match = texpr_fne;
                        }
 
-                       return fne;
+                       return match;
                }
 
                Namespace [] GetUsingTable ()
@@ -1314,18 +1309,22 @@ namespace Mono.CSharp {
                        get { return RootContext.ToplevelTypes.Compiler; }
                }
 
-               public Type CurrentType {
+               public TypeSpec CurrentType {
                        get { return SlaveDeclSpace.CurrentType; }
                }
 
-               public TypeContainer CurrentTypeDefinition {
-                       get { return SlaveDeclSpace.CurrentTypeDefinition; }
+               public MemberCore CurrentMemberDefinition {
+                       get { return SlaveDeclSpace.CurrentMemberDefinition; }
                }
 
                public TypeParameter[] CurrentTypeParameters {
                        get { return SlaveDeclSpace.CurrentTypeParameters; }
                }
 
+               public bool HasUnresolvedConstraints {
+                       get { return false; }
+               }
+
                public bool IsObsolete {
                        get { return SlaveDeclSpace.IsObsolete; }
                }
index 9b1e3222301579ba5195170bdea079e847b574ec..8e2dc682bbc0fbbfc2403f8ed3842c0c87c11dd4 100644 (file)
@@ -29,7 +29,7 @@ namespace Mono.CSharp.Nullable
                        eclass = ExprClass.Type;
                }
 
-               public NullableType (Type type, Location loc)
+               public NullableType (TypeSpec type, Location loc)
                        : this (new TypeExpression (type, loc), loc)
                { }
 
@@ -37,68 +37,54 @@ namespace Mono.CSharp.Nullable
                {
                        if (TypeManager.generic_nullable_type == null) {
                                TypeManager.generic_nullable_type = TypeManager.CoreLookupType (ec.Compiler,
-                                       "System", "Nullable`1", MemberKind.Struct, true);
+                                       "System", "Nullable", 1, MemberKind.Struct, true);
                        }
 
                        TypeArguments args = new TypeArguments (underlying);
                        GenericTypeExpr ctype = new GenericTypeExpr (TypeManager.generic_nullable_type, args, loc);
                        return ctype.ResolveAsTypeTerminal (ec, false);
                }
-
-               public override TypeExpr ResolveAsTypeTerminal (IMemberContext ec, bool silent)
-               {
-                       return ResolveAsBaseTerminal (ec, silent);
-               }               
        }
 
-       public sealed class NullableInfo
+       static class NullableInfo
        {
-               public readonly Type Type;
-               public readonly Type UnderlyingType;
-               public MethodSpec HasValue;
-               public MethodSpec Value;
-               public MethodSpec GetValueOrDefault;
-               public MethodSpec Constructor;
-
-               public NullableInfo (Type type)
+               public static MethodSpec GetConstructor (TypeSpec nullableType)
                {
-                       Type = type;
-                       UnderlyingType = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (type) [0]);
-
-                       var has_value_pi = TypeManager.GetPredefinedProperty (type, "HasValue", Location.Null, Type.EmptyTypes);
-                       var value_pi = TypeManager.GetPredefinedProperty (type, "Value", Location.Null, Type.EmptyTypes);
-                       GetValueOrDefault = TypeManager.GetPredefinedMethod (type, "GetValueOrDefault", Location.Null, Type.EmptyTypes);
+                       return TypeManager.GetPredefinedConstructor (nullableType, Location.Null, GetUnderlyingType (nullableType));
+               }
 
-                       HasValue = Import.CreateMethod (has_value_pi.MetaInfo.GetGetMethod (false));
-                       Value = Import.CreateMethod (value_pi.MetaInfo.GetGetMethod (false));
+               public static MethodSpec GetHasValue (TypeSpec nullableType)
+               {
+                       return (MethodSpec) MemberCache.FindMember (nullableType,
+                               MemberFilter.Method ("get_HasValue", 0, ParametersCompiled.EmptyReadOnlyParameters, null), BindingRestriction.None);
+               }
 
-                       // When compiling corlib
-                       if (TypeManager.IsBeingCompiled (type)) {
-                               TypeContainer tc = TypeManager.LookupGenericTypeContainer (type);
-                               
-                               // TODO: check for correct overload
-                               Constructor c = ((Constructor) tc.InstanceConstructors [0]);
+               public static MethodSpec GetGetValueOrDefault (TypeSpec nullableType)
+               {
+                       return (MethodSpec) MemberCache.FindMember (nullableType,
+                               MemberFilter.Method ("GetValueOrDefault", 0, ParametersCompiled.EmptyReadOnlyParameters, null), BindingRestriction.None);
+               }
 
-                               Constructor = Import.CreateMethod (TypeBuilder.GetConstructor (type, c.ConstructorBuilder));
-                               return;
-                       }
+               public static MethodSpec GetValue (TypeSpec nullableType)
+               {
+                       return (MethodSpec) MemberCache.FindMember (nullableType,
+                               MemberFilter.Method ("get_Value", 0, ParametersCompiled.EmptyReadOnlyParameters, null), BindingRestriction.None);
+               }
 
-#if MS_COMPATIBLE
-//                     if (TypeManager.IsBeingCompiled (UnderlyingType)) {
-//                             ConstructorInfo cinfo = TypeManager.DropGenericTypeArguments (type).GetConstructors ()[0];
-//                             Constructor = TypeBuilder.GetConstructor (type, cinfo);
-//                             return;
-//                     }
-#endif
+               public static TypeSpec GetUnderlyingType (TypeSpec nullableType)
+               {
+                       return ((InflatedTypeSpec) nullableType).TypeArguments[0];
+               }
 
-                       Constructor = Import.CreateMethod (type.GetConstructor (new Type[] { UnderlyingType }));
+               public static bool IsNullableType (TypeSpec type)
+               {
+                       throw new NotImplementedException ("net");
                }
        }
 
        public class Unwrap : Expression, IMemoryLocation, IAssignMethod
        {
                Expression expr;
-               NullableInfo info;
 
                LocalTemporary temp;
                readonly bool useDefaultValue;
@@ -109,8 +95,7 @@ namespace Mono.CSharp.Nullable
                        this.loc = expr.Location;
                        this.useDefaultValue = useDefaultValue;
 
-                       info = new NullableInfo (expr.Type);
-                       type = info.UnderlyingType;
+                       type = NullableInfo.GetUnderlyingType (expr.Type);
                        eclass = expr.eclass;
                }
 
@@ -150,15 +135,15 @@ namespace Mono.CSharp.Nullable
                {
                        Store (ec);
                        if (useDefaultValue)
-                               Invocation.EmitCall (ec, false, this, info.GetValueOrDefault, null, loc);
+                               Invocation.EmitCall (ec, false, this, NullableInfo.GetGetValueOrDefault (expr.Type), null, loc);
                        else
-                               Invocation.EmitCall (ec, false, this, info.Value, null, loc);
+                               Invocation.EmitCall (ec, false, this, NullableInfo.GetValue (expr.Type), null, loc);
                }
 
                public void EmitCheck (EmitContext ec)
                {
                        Store (ec);
-                       Invocation.EmitCall (ec, false, this, info.HasValue, null, loc);
+                       Invocation.EmitCall (ec, false, this, NullableInfo.GetHasValue (expr.Type), null, loc);
                }
 
                public override bool Equals (object obj)
@@ -209,15 +194,6 @@ namespace Mono.CSharp.Nullable
                        return expr.MakeExpression (ctx);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       type = storey.MutateType (type);
-                       storey.MutateConstructor (info.Constructor);
-                       storey.MutateGenericMethod (info.HasValue);
-                       storey.MutateGenericMethod (info.GetValueOrDefault);
-                       storey.MutateGenericMethod (info.Value);
-               }
-
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        IMemoryLocation ml = expr as VariableReference;
@@ -233,7 +209,7 @@ namespace Mono.CSharp.Nullable
                LocalTemporary LocalVariable {
                        get {
                                if (temp == null)
-                                       temp = new LocalTemporary (info.Type);
+                                       temp = new LocalTemporary (expr.Type);
                                return temp;
                        }
                }
@@ -249,22 +225,20 @@ namespace Mono.CSharp.Nullable
                public void EmitAssign (EmitContext ec, Expression source,
                                        bool leave_copy, bool prepare_for_load)
                {
-                       InternalWrap wrap = new InternalWrap (source, info, loc);
+                       InternalWrap wrap = new InternalWrap (source, expr.Type, loc);
                        ((IAssignMethod) expr).EmitAssign (ec, wrap, leave_copy, false);
                }
 
-               protected class InternalWrap : Expression
+               class InternalWrap : Expression
                {
                        public Expression expr;
-                       public NullableInfo info;
 
-                       public InternalWrap (Expression expr, NullableInfo info, Location loc)
+                       public InternalWrap (Expression expr, TypeSpec type, Location loc)
                        {
                                this.expr = expr;
-                               this.info = info;
                                this.loc = loc;
+                               this.type = type;
 
-                               type = info.Type;
                                eclass = ExprClass.Value;
                        }
 
@@ -281,19 +255,16 @@ namespace Mono.CSharp.Nullable
                        public override void Emit (EmitContext ec)
                        {
                                expr.Emit (ec);
-                               ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) info.Constructor.MetaInfo);
+                               ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type));
                        }
                }
        }
 
        public class Wrap : TypeCast
        {
-               readonly NullableInfo info;
-
-               protected Wrap (Expression expr, Type type)
+               private Wrap (Expression expr, TypeSpec type)
                        : base (expr, type)
                {
-                       info = new NullableInfo (type);
                        eclass = ExprClass.Value;
                }
 
@@ -308,13 +279,13 @@ namespace Mono.CSharp.Nullable
                        return base.CreateExpressionTree (ec);
                }
 
-               public static Expression Create (Expression expr, Type type)
+               public static Expression Create (Expression expr, TypeSpec type)
                {
                        //
                        // Avoid unwraping and wraping of the same type
                        //
                        Unwrap unwrap = expr as Unwrap;
-                       if (unwrap != null && TypeManager.IsEqual (expr.Type, TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (type) [0])))
+                       if (unwrap != null && TypeManager.IsEqual (expr.Type, NullableInfo.GetUnderlyingType (type)))
                                return unwrap.Original;
                
                        return new Wrap (expr, type);
@@ -323,7 +294,7 @@ namespace Mono.CSharp.Nullable
                public override void Emit (EmitContext ec)
                {
                        child.Emit (ec);
-                       ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) info.Constructor.MetaInfo);
+                       ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type));
                }
        }
 
@@ -332,13 +303,13 @@ namespace Mono.CSharp.Nullable
        //
        public class LiftedNull : NullConstant, IMemoryLocation
        {
-               private LiftedNull (Type nullable_type, Location loc)
+               private LiftedNull (TypeSpec nullable_type, Location loc)
                        : base (nullable_type, loc)
                {
                        eclass = ExprClass.Value;
                }
 
-               public static Constant Create (Type nullable, Location loc)
+               public static Constant Create (TypeSpec nullable, Location loc)
                {
                        return new LiftedNull (nullable, loc);
                }
@@ -357,7 +328,7 @@ namespace Mono.CSharp.Nullable
                        LocalTemporary value_target = new LocalTemporary (type);
 
                        value_target.AddressOf (ec, AddressOp.Store);
-                       ec.ig.Emit (OpCodes.Initobj, type);
+                       ec.Emit (OpCodes.Initobj, type);
                        value_target.Emit (ec);
                }
 
@@ -366,7 +337,7 @@ namespace Mono.CSharp.Nullable
                        LocalTemporary value_target = new LocalTemporary (type);
                                
                        value_target.AddressOf (ec, AddressOp.Store);
-                       ec.ig.Emit (OpCodes.Initobj, type);
+                       ec.Emit (OpCodes.Initobj, type);
                        ((IMemoryLocation) value_target).AddressOf (ec, Mode);
                }
        }
@@ -379,7 +350,7 @@ namespace Mono.CSharp.Nullable
                Expression expr, null_value;
                Unwrap unwrap;
 
-               public Lifted (Expression expr, Unwrap unwrap, Type type)
+               public Lifted (Expression expr, Unwrap unwrap, TypeSpec type)
                {
                        this.expr = expr;
                        this.unwrap = unwrap;
@@ -387,7 +358,7 @@ namespace Mono.CSharp.Nullable
                        this.type = type;
                }
 
-               public Lifted (Expression expr, Expression unwrap, Type type)
+               public Lifted (Expression expr, Expression unwrap, TypeSpec type)
                        : this (expr, unwrap as Unwrap, type)
                {
                }
@@ -428,20 +399,19 @@ namespace Mono.CSharp.Nullable
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label is_null_label = ig.DefineLabel ();
-                       Label end_label = ig.DefineLabel ();
+                       Label is_null_label = ec.DefineLabel ();
+                       Label end_label = ec.DefineLabel ();
 
                        unwrap.EmitCheck (ec);
-                       ig.Emit (OpCodes.Brfalse, is_null_label);
+                       ec.Emit (OpCodes.Brfalse, is_null_label);
 
                        expr.Emit (ec);
 
-                       ig.Emit (OpCodes.Br, end_label);
-                       ig.MarkLabel (is_null_label);
+                       ec.Emit (OpCodes.Br, end_label);
+                       ec.MarkLabel (is_null_label);
 
                        null_value.Emit (ec);
-                       ig.MarkLabel (end_label);
+                       ec.MarkLabel (end_label);
                }
 
                public void AddressOf (EmitContext ec, AddressOp mode)
@@ -500,28 +470,25 @@ namespace Mono.CSharp.Nullable
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label is_null_label = ig.DefineLabel ();
-                       Label end_label = ig.DefineLabel ();
+                       Label is_null_label = ec.DefineLabel ();
+                       Label end_label = ec.DefineLabel ();
 
                        unwrap.EmitCheck (ec);
-                       ig.Emit (OpCodes.Brfalse, is_null_label);
-
-                       NullableInfo ni = new NullableInfo (type);
+                       ec.Emit (OpCodes.Brfalse, is_null_label);
 
                        if (user_operator != null) {
                                user_operator.Emit (ec);
                        } else {
-                               EmitOperator (ec, ni.UnderlyingType);
+                               EmitOperator (ec, NullableInfo.GetUnderlyingType (type));
                        }
 
-                       ig.Emit (OpCodes.Newobj, (ConstructorInfo) ni.Constructor.MetaInfo);
-                       ig.Emit (OpCodes.Br_S, end_label);
+                       ec.Emit (OpCodes.Newobj, NullableInfo.GetConstructor (type));
+                       ec.Emit (OpCodes.Br_S, end_label);
 
-                       ig.MarkLabel (is_null_label);
+                       ec.MarkLabel (is_null_label);
                        LiftedNull.Create (type, loc).Emit (ec);
 
-                       ig.MarkLabel (end_label);
+                       ec.MarkLabel (end_label);
                }
 
                Expression LiftExpression (ResolveContext ec, Expression expr)
@@ -650,23 +617,21 @@ namespace Mono.CSharp.Nullable
 
                void EmitBitwiseBoolean (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
-                       Label load_left = ig.DefineLabel ();
-                       Label load_right = ig.DefineLabel ();
-                       Label end_label = ig.DefineLabel ();
+                       Label load_left = ec.DefineLabel ();
+                       Label load_right = ec.DefineLabel ();
+                       Label end_label = ec.DefineLabel ();
 
                        left_unwrap.Emit (ec);
-                       ig.Emit (OpCodes.Brtrue_S, load_right);
+                       ec.Emit (OpCodes.Brtrue_S, load_right);
 
                        right_unwrap.Emit (ec);
-                       ig.Emit (OpCodes.Brtrue_S, load_left);
+                       ec.Emit (OpCodes.Brtrue_S, load_left);
 
                        left_unwrap.EmitCheck (ec);
-                       ig.Emit (OpCodes.Brfalse_S, load_right);
+                       ec.Emit (OpCodes.Brfalse_S, load_right);
 
                        // load left
-                       ig.MarkLabel (load_left);
+                       ec.MarkLabel (load_left);
 
                        if (Oper == Operator.BitwiseAnd) {
                                left_unwrap.Load (ec);
@@ -674,13 +639,13 @@ namespace Mono.CSharp.Nullable
                                right_unwrap.Load (ec);
                                right_unwrap = left_unwrap;
                        }
-                       ig.Emit (OpCodes.Br_S, end_label);
+                       ec.Emit (OpCodes.Br_S, end_label);
 
                        // load right
-                       ig.MarkLabel (load_right);
+                       ec.MarkLabel (load_right);
                        right_unwrap.Load (ec);
 
-                       ig.MarkLabel (end_label);
+                       ec.MarkLabel (end_label);
                }
 
                //
@@ -688,16 +653,14 @@ namespace Mono.CSharp.Nullable
                //
                void EmitEquality (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        //
                        // Either left or right is null
                        //
                        if (left_unwrap != null && (right_null_lifted || right.IsNull)) {
                                left_unwrap.EmitCheck (ec);
                                if (Oper == Binary.Operator.Equality) {
-                                       ig.Emit (OpCodes.Ldc_I4_0);
-                                       ig.Emit (OpCodes.Ceq);
+                                       ec.Emit (OpCodes.Ldc_I4_0);
+                                       ec.Emit (OpCodes.Ceq);
                                }
                                return;
                        }
@@ -705,23 +668,23 @@ namespace Mono.CSharp.Nullable
                        if (right_unwrap != null && (left_null_lifted || left.IsNull)) {
                                right_unwrap.EmitCheck (ec);
                                if (Oper == Binary.Operator.Equality) {
-                                       ig.Emit (OpCodes.Ldc_I4_0);
-                                       ig.Emit (OpCodes.Ceq);
+                                       ec.Emit (OpCodes.Ldc_I4_0);
+                                       ec.Emit (OpCodes.Ceq);
                                }
                                return;
                        }
 
-                       Label dissimilar_label = ig.DefineLabel ();
-                       Label end_label = ig.DefineLabel ();
+                       Label dissimilar_label = ec.DefineLabel ();
+                       Label end_label = ec.DefineLabel ();
 
                        if (user_operator != null) {
                                user_operator.Emit (ec);
-                               ig.Emit (Oper == Operator.Equality ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, dissimilar_label);
+                               ec.Emit (Oper == Operator.Equality ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, dissimilar_label);
                        } else {
                                left.Emit (ec);
                                right.Emit (ec);
 
-                               ig.Emit (OpCodes.Bne_Un_S, dissimilar_label);
+                               ec.Emit (OpCodes.Bne_Un_S, dissimilar_label);
                        }
 
                        if (left_unwrap != null)
@@ -732,31 +695,31 @@ namespace Mono.CSharp.Nullable
 
                        if (left_unwrap != null && right_unwrap != null) {
                                if (Oper == Operator.Inequality)
-                                       ig.Emit (OpCodes.Xor);
+                                       ec.Emit (OpCodes.Xor);
                                else
-                                       ig.Emit (OpCodes.Ceq);
+                                       ec.Emit (OpCodes.Ceq);
                        } else {
                                if (Oper == Operator.Inequality) {
-                                       ig.Emit (OpCodes.Ldc_I4_0);
-                                       ig.Emit (OpCodes.Ceq);
+                                       ec.Emit (OpCodes.Ldc_I4_0);
+                                       ec.Emit (OpCodes.Ceq);
                                }
                        }
 
-                       ig.Emit (OpCodes.Br_S, end_label);
+                       ec.Emit (OpCodes.Br_S, end_label);
 
-                       ig.MarkLabel (dissimilar_label);
+                       ec.MarkLabel (dissimilar_label);
                        if (Oper == Operator.Inequality)
-                               ig.Emit (OpCodes.Ldc_I4_1);
+                               ec.Emit (OpCodes.Ldc_I4_1);
                        else
-                               ig.Emit (OpCodes.Ldc_I4_0);
+                               ec.Emit (OpCodes.Ldc_I4_0);
 
-                       ig.MarkLabel (end_label);
+                       ec.MarkLabel (end_label);
                }
                
                public override void EmitBranchable (EmitContext ec, Label target, bool onTrue)
                {
                        Emit (ec);
-                       ec.ig.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+                       ec.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);
                }                       
 
                public override void Emit (EmitContext ec)
@@ -777,14 +740,12 @@ namespace Mono.CSharp.Nullable
                                return;
                        }
 
-                       ILGenerator ig = ec.ig;
-
-                       Label is_null_label = ig.DefineLabel ();
-                       Label end_label = ig.DefineLabel ();
+                       Label is_null_label = ec.DefineLabel ();
+                       Label end_label = ec.DefineLabel ();
 
                        if (left_unwrap != null) {
                                left_unwrap.EmitCheck (ec);
-                               ig.Emit (OpCodes.Brfalse, is_null_label);
+                               ec.Emit (OpCodes.Brfalse, is_null_label);
                        }
 
                        //
@@ -792,27 +753,27 @@ namespace Mono.CSharp.Nullable
                        //
                        if (right_unwrap != null && !left.Equals (right)) {
                                right_unwrap.EmitCheck (ec);
-                               ig.Emit (OpCodes.Brfalse, is_null_label);
+                               ec.Emit (OpCodes.Brfalse, is_null_label);
                        }
 
                        EmitOperator (ec, left.Type);
 
                        if (wrap_ctor != null)
-                               ig.Emit (OpCodes.Newobj, (ConstructorInfo) wrap_ctor.MetaInfo);
+                               ec.Emit (OpCodes.Newobj, wrap_ctor);
 
-                       ig.Emit (OpCodes.Br_S, end_label);
-                       ig.MarkLabel (is_null_label);
+                       ec.Emit (OpCodes.Br_S, end_label);
+                       ec.MarkLabel (is_null_label);
 
                        if ((Oper & Operator.ComparisonMask) != 0) {
-                               ig.Emit (OpCodes.Ldc_I4_0);
+                               ec.Emit (OpCodes.Ldc_I4_0);
                        } else {
                                LiftedNull.Create (type, loc).Emit (ec);
                        }
 
-                       ig.MarkLabel (end_label);
+                       ec.MarkLabel (end_label);
                }
 
-               protected override void EmitOperator (EmitContext ec, Type l)
+               protected override void EmitOperator (EmitContext ec, TypeSpec l)
                {
                        if (user_operator != null) {
                                user_operator.Emit (ec);
@@ -820,7 +781,7 @@ namespace Mono.CSharp.Nullable
                        }
 
                        if (TypeManager.IsNullableType (l))
-                               l = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (l) [0]);
+                               l = TypeManager.GetTypeArguments (l) [0];
 
                        base.EmitOperator (ec, l);
                }
@@ -869,7 +830,7 @@ namespace Mono.CSharp.Nullable
                                if (lifted_type == null)
                                        return null;
 
-                               wrap_ctor = new NullableInfo (lifted_type.Type).Constructor;
+                               wrap_ctor = NullableInfo.GetConstructor (lifted_type.Type);
                                type = res_expr.Type = lifted_type.Type;
                        }
 
@@ -902,7 +863,7 @@ namespace Mono.CSharp.Nullable
                        return res_expr;
                }
 
-               protected override Expression ResolveOperatorPredefined (ResolveContext ec, Binary.PredefinedOperator [] operators, bool primitives_only, Type enum_type)
+               protected override Expression ResolveOperatorPredefined (ResolveContext ec, Binary.PredefinedOperator [] operators, bool primitives_only, TypeSpec enum_type)
                {
                        Expression e = base.ResolveOperatorPredefined (ec, operators, primitives_only, enum_type);
 
@@ -924,7 +885,7 @@ namespace Mono.CSharp.Nullable
                        return e;
                }
 
-               protected override Expression ResolveUserOperator (ResolveContext ec, Type l, Type r)
+               protected override Expression ResolveUserOperator (ResolveContext ec, TypeSpec l, TypeSpec r)
                {
                        Expression expr = base.ResolveUserOperator (ec, l, r);
                        if (expr == null)
@@ -983,7 +944,7 @@ namespace Mono.CSharp.Nullable
                        if (left.eclass == ExprClass.MethodGroup)
                                return null;
 
-                       Type ltype = left.Type;
+                       TypeSpec ltype = left.Type;
 
                        //
                        // If left is a nullable type and an implicit conversion exists from right to underlying type of left,
@@ -1023,7 +984,7 @@ namespace Mono.CSharp.Nullable
                                return null;
                        }
 
-                       Type rtype = right.Type;
+                       TypeSpec rtype = right.Type;
                        if (!Convert.ImplicitConversionExists (ec, unwrap != null ? unwrap : left, rtype) || right.eclass == ExprClass.MethodGroup)
                                return null;
 
@@ -1059,42 +1020,33 @@ namespace Mono.CSharp.Nullable
 
                public override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
-                       Label end_label = ig.DefineLabel ();
+                       Label end_label = ec.DefineLabel ();
 
                        if (unwrap != null) {
-                               Label is_null_label = ig.DefineLabel ();
+                               Label is_null_label = ec.DefineLabel ();
 
                                unwrap.EmitCheck (ec);
-                               ig.Emit (OpCodes.Brfalse, is_null_label);
+                               ec.Emit (OpCodes.Brfalse, is_null_label);
 
                                left.Emit (ec);
-                               ig.Emit (OpCodes.Br, end_label);
+                               ec.Emit (OpCodes.Br, end_label);
 
-                               ig.MarkLabel (is_null_label);
+                               ec.MarkLabel (is_null_label);
                                right.Emit (ec);
 
-                               ig.MarkLabel (end_label);
+                               ec.MarkLabel (end_label);
                                return;
                        }
 
                        left.Emit (ec);
 
-                       ig.Emit (OpCodes.Dup);
-                       ig.Emit (OpCodes.Brtrue, end_label);
+                       ec.Emit (OpCodes.Dup);
+                       ec.Emit (OpCodes.Brtrue, end_label);
 
-                       ig.Emit (OpCodes.Pop);
+                       ec.Emit (OpCodes.Pop);
                        right.Emit (ec);
 
-                       ig.MarkLabel (end_label);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       left.MutateHoistedGenericType (storey);
-                       right.MutateHoistedGenericType (storey);
-                       type = storey.MutateType (type);
+                       ec.MarkLabel (end_label);
                }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -1147,25 +1099,24 @@ namespace Mono.CSharp.Nullable
 
                void DoEmit (EmitContext ec, bool is_expr)
                {
-                       ILGenerator ig = ec.ig;
-                       Label is_null_label = ig.DefineLabel ();
-                       Label end_label = ig.DefineLabel ();
+                       Label is_null_label = ec.DefineLabel ();
+                       Label end_label = ec.DefineLabel ();
 
                        unwrap.EmitCheck (ec);
-                       ig.Emit (OpCodes.Brfalse, is_null_label);
+                       ec.Emit (OpCodes.Brfalse, is_null_label);
 
                        if (is_expr) {
                                underlying.Emit (ec);
-                               ig.Emit (OpCodes.Br_S, end_label);
+                               ec.Emit (OpCodes.Br_S, end_label);
                        } else {
                                underlying.EmitStatement (ec);
                        }
 
-                       ig.MarkLabel (is_null_label);
+                       ec.MarkLabel (is_null_label);
                        if (is_expr)
                                LiftedNull.Create (type, loc).Emit (ec);
 
-                       ig.MarkLabel (end_label);
+                       ec.MarkLabel (end_label);
                }
 
                public override void Emit (EmitContext ec)
index 9e3d7fddd6a35a284f63a988a389641528b8f429..b25bae9cae2c7fc74194537c282d522ea96ff5fc 100644 (file)
@@ -14,6 +14,7 @@ using System;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Text;
+using System.Linq;
 
 namespace Mono.CSharp {
 
@@ -24,7 +25,7 @@ namespace Mono.CSharp {
        {
                protected ParameterBuilder builder;
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
 #if false
                        if (a.Type == pa.MarshalAs) {
@@ -45,7 +46,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       builder.SetCustomAttribute (ctor, cdata);
+                       builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
                public ParameterBuilder Builder {
@@ -79,7 +80,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.CLSCompliant) {
                                method.Compiler.Report.Warning (3023, 1, a.Location,
@@ -144,16 +145,17 @@ namespace Mono.CSharp {
                {
                }
 
-               public override Type Resolve (IMemberContext ec)
+               public override TypeSpec Resolve (IMemberContext ec, int index)
                {
                        if (parameter_type == null)
                                throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
                                        Name);
 
+                       base.idx = index;
                        return parameter_type;
                }
 
-               public Type Type {
+               public TypeSpec Type {
                        set { parameter_type = value; }
                }
        }
@@ -164,12 +166,13 @@ namespace Mono.CSharp {
                {
                }
 
-               public override Type Resolve (IMemberContext ec)
+               public override TypeSpec Resolve (IMemberContext ec, int index)
                {
-                       if (base.Resolve (ec) == null)
+                       if (base.Resolve (ec, index) == null)
                                return null;
 
-                       if (!parameter_type.IsArray || parameter_type.GetArrayRank () != 1) {
+                       var ac = parameter_type as ArrayContainer;
+                       if (ac == null || ac.Rank != 1) {
                                ec.Compiler.Report.Error (225, Location, "The params parameter must be a single dimensional array");
                                return null;
                        }
@@ -189,6 +192,7 @@ namespace Mono.CSharp {
                public ArglistParameter (Location loc) :
                        base (null, String.Empty, Parameter.Modifier.NONE, null, loc)
                {
+                       parameter_type = InternalType.Arglist;
                }
 
                public override void  ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
@@ -201,14 +205,9 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public override Type Resolve (IMemberContext ec)
+               public override TypeSpec Resolve (IMemberContext ec, int index)
                {
-                       return InternalType.Arglist;
-               }
-
-               public override string GetSignatureForError ()
-               {
-                       return "__arglist";
+                       return parameter_type;
                }
        }
 
@@ -240,13 +239,13 @@ namespace Mono.CSharp {
 
                static string[] attribute_targets = new string [] { "param" };
 
-               protected FullNamedExpression TypeName;
+               FullNamedExpression texpr;
                readonly Modifier modFlags;
                string name;
                Expression default_expr;
-               protected Type parameter_type;
+               protected TypeSpec parameter_type;
                public readonly Location Location;
-               int idx;
+               protected int idx;
                public bool HasAddressTaken;
 
                Expression expr_tree_variable;
@@ -259,13 +258,21 @@ namespace Mono.CSharp {
                        this.name = name;
                        modFlags = mod;
                        Location = loc;
-                       TypeName = type;
+                       texpr = type;
 
                        // Only assign, attributes will be attached during resolve
                        base.attributes = attrs;
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+#region Properties
+               public FullNamedExpression TypeExpression  {
+                       get {
+                               return texpr;
+                       }
+               }
+#endregion
+
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.In && ModFlags == Modifier.OUT) {
                                a.Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
@@ -296,15 +303,15 @@ namespace Mono.CSharp {
                        }
 
                        if (a.Type == pa.DefaultParameterValue) {
-                               Type arg_type;
+                               TypeSpec arg_type;
                                var c = a.GetParameterDefaultValue (out arg_type);
                                if (c == null) {
                                        if (parameter_type == TypeManager.object_type) {
                                                a.Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
-                                                       TypeManager.CSharpName (arg_type));
+                                                       arg_type.GetSignatureForError ());
                                        } else {
                                                a.Report.Error (1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
-                                                       TypeManager.CSharpName (parameter_type)); ;
+                                                       parameter_type.GetSignatureForError ()); ;
                                        }
 
                                        return;
@@ -330,10 +337,15 @@ namespace Mono.CSharp {
                        return member.IsAccessibleAs (parameter_type);
                }
 
+               public static void Reset ()
+               {
+                       parameter_expr_tree_type = null;
+               }
+
                // <summary>
                //   Resolve is used in method definitions
                // </summary>
-               public virtual Type Resolve (IMemberContext rc)
+               public virtual TypeSpec Resolve (IMemberContext rc, int index)
                {
                        if (parameter_type != null)
                                return parameter_type;
@@ -341,20 +353,19 @@ namespace Mono.CSharp {
                        if (attributes != null)
                                attributes.AttachTo (this, rc);
 
-                       TypeExpr texpr = TypeName.ResolveAsTypeTerminal (rc, false);
-                       if (texpr == null)
+                       var expr = texpr.ResolveAsTypeTerminal (rc, false);
+                       if (expr == null)
                                return null;
 
+                       this.idx = index;
+                       texpr = expr;
                        parameter_type = texpr.Type;
 
                        // Ignore all checks for dummy members
                        AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod;
                        if (pem != null && pem.IsDummy)
                                return parameter_type;
-
-                       if (default_expr != null)
-                               default_expr = ResolveDefaultValue (new ResolveContext (rc));
-
+                       
                        if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
                                TypeManager.IsSpecialType (parameter_type)) {
                                rc.Compiler.Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
@@ -366,16 +377,13 @@ namespace Mono.CSharp {
                                (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
                                rc);
 
-                       if (TypeManager.IsGenericParameter (parameter_type))
-                               return parameter_type;
-
-                       if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+                       if (parameter_type.IsStatic) {
                                rc.Compiler.Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
                                        texpr.GetSignatureForError ());
                                return parameter_type;
                        }
 
-                       if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || TypeManager.IsDynamicType (parameter_type))) {
+                       if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || parameter_type == InternalType.Dynamic)) {
                                rc.Compiler.Report.Error (1103, Location, "The extension method cannot be of type `{0}'",
                                        TypeManager.CSharpName (parameter_type));
                        }
@@ -383,7 +391,13 @@ namespace Mono.CSharp {
                        return parameter_type;
                }
 
-               Expression ResolveDefaultValue (ResolveContext rc)
+               public void ResolveDefaultValue (ResolveContext rc)
+               {
+                       if (default_expr != null)
+                               default_expr = ResolveDefaultExpression (rc);
+               }
+
+               Expression ResolveDefaultExpression (ResolveContext rc)
                {
                        default_expr = default_expr.Resolve (rc);
                        if (default_expr == null)
@@ -431,11 +445,6 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public void ResolveVariable (int idx)
-               {
-                       this.idx = idx;
-               }
-
                public bool HasDefaultValue {
                        get { return default_expr != null; }
                }
@@ -482,7 +491,7 @@ namespace Mono.CSharp {
                        if (parameter_type != null)
                                type_name = TypeManager.CSharpName (parameter_type);
                        else
-                               type_name = TypeName.GetSignatureForError ();
+                               type_name = texpr.GetSignatureForError ();
 
                        string mod = GetModifierSignature (modFlags);
                        if (mod.Length > 0)
@@ -509,7 +518,7 @@ namespace Mono.CSharp {
 
                public void IsClsCompliant (IMemberContext ctx)
                {
-                       if (AttributeTester.IsClsCompliant (parameter_type))
+                       if (parameter_type.IsCLSCompliant ())
                                return;
 
                        ctx.Compiler.Report.Warning (3001, 1, Location,
@@ -541,13 +550,13 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (TypeManager.IsDynamicType (parameter_type)) {
+                       if (parameter_type == InternalType.Dynamic) {
                                PredefinedAttributes.Get.Dynamic.EmitAttribute (builder);
                        } else {
                                var trans_flags = TypeManager.HasDynamicTypeUsed (parameter_type);
                                if (trans_flags != null) {
                                        var pa = PredefinedAttributes.Get.DynamicTransform;
-                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
                                                builder.SetCustomAttribute (
                                                        new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
                                        }
@@ -597,7 +606,7 @@ namespace Mono.CSharp {
                        if (!ec.IsStatic)
                                arg_idx++;
 
-                       ParameterReference.EmitLdArg (ec.ig, arg_idx);
+                       ParameterReference.EmitLdArg (ec, arg_idx);
                }
 
                public void EmitAssign (EmitContext ec)
@@ -607,9 +616,9 @@ namespace Mono.CSharp {
                                arg_idx++;
 
                        if (arg_idx <= 255)
-                               ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
+                               ec.Emit (OpCodes.Starg_S, (byte) arg_idx);
                        else
-                               ec.ig.Emit (OpCodes.Starg, arg_idx);
+                               ec.Emit (OpCodes.Starg, arg_idx);
                }
 
                public void EmitAddressOf (EmitContext ec)
@@ -621,12 +630,12 @@ namespace Mono.CSharp {
 
                        bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
                        if (is_ref) {
-                               ParameterReference.EmitLdArg (ec.ig, arg_idx);
+                               ParameterReference.EmitLdArg (ec, arg_idx);
                        } else {
                                if (arg_idx <= 255)
-                                       ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
+                                       ec.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
                                else
-                                       ec.ig.Emit (OpCodes.Ldarga, arg_idx);
+                                       ec.Emit (OpCodes.Ldarga, arg_idx);
                        }
                }
 
@@ -643,7 +652,7 @@ namespace Mono.CSharp {
                        if (parameter_expr_tree_type != null)
                                return parameter_expr_tree_type;
 
-                       Type p_type = TypeManager.parameter_expression_type;
+                       TypeSpec p_type = TypeManager.parameter_expression_type;
                        if (p_type == null) {
                                p_type = TypeManager.CoreLookupType (ec.Compiler, "System.Linq.Expressions", "ParameterExpression", MemberKind.Class, true);
                                TypeManager.parameter_expression_type = p_type;
@@ -716,11 +725,7 @@ namespace Mono.CSharp {
 
                // Null object pattern
                protected IParameterData [] parameters;
-               protected Type [] types;
-
-               public ParametersCompiled AsCompiled {
-                       get { return (ParametersCompiled) this; }
-               }
+               protected TypeSpec [] types;
 
                public CallingConventions CallingConvention {
                        get {
@@ -734,7 +739,7 @@ namespace Mono.CSharp {
                        get { return parameters.Length; }
                }
 
-               public Type ExtensionMethodType {
+               public TypeSpec ExtensionMethodType {
                        get {
                                if (Count == 0)
                                        return null;
@@ -756,30 +761,32 @@ namespace Mono.CSharp {
                                ParameterAttributes.Out : ParameterAttributes.None;
                }
 
-               public Type [] GetEmitTypes ()
+               // Very expensive operation
+               public Type[] GetMetaInfo ()
                {
-                       Type [] types = null;
+                       Type[] types;
                        if (has_arglist) {
                                if (Count == 1)
                                        return Type.EmptyTypes;
 
                                types = new Type [Count - 1];
-                               Array.Copy (Types, types, types.Length);
+                       } else {
+                               if (Count == 0)
+                                       return Type.EmptyTypes;
+
+                               types = new Type [Count];
                        }
 
-                       for (int i = 0; i < Count; ++i) {
+                       for (int i = 0; i < types.Length; ++i) {
+                               types[i] = Types[i].GetMetaInfo ();
+
                                if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
                                        continue;
 
-                               if (types == null)
-                                       types = (Type []) Types.Clone ();
-
-                               types [i] = TypeManager.GetReferenceType (types [i]);
+                               // TODO MemberCache: Should go to MetaInfo getter
+                               types [i] = types [i].MakeByRefType ();
                        }
 
-                       if (types == null)
-                               types = Types;
-
                        return types;
                }
 
@@ -798,13 +805,18 @@ namespace Mono.CSharp {
 
                public string GetSignatureForError ()
                {
-                       StringBuilder sb = new StringBuilder ("(");
-                       for (int i = 0; i < Count; ++i) {
+                       return GetSignatureForError ("(", ")", Count);
+               }
+
+               public string GetSignatureForError (string start, string end, int count)
+               {
+                       StringBuilder sb = new StringBuilder (start);
+                       for (int i = 0; i < count; ++i) {
                                if (i != 0)
                                        sb.Append (", ");
                                sb.Append (ParameterDesc (i));
                        }
-                       sb.Append (')');
+                       sb.Append (end);
                        return sb.ToString ();
                }
 
@@ -829,6 +841,43 @@ namespace Mono.CSharp {
                        get { return parameters.Length == 0; }
                }
 
+               public AParametersCollection Inflate (TypeParameterInflator inflator)
+               {
+                       TypeSpec[] inflated_types = null;
+                       bool default_value = false;
+
+                       for (int i = 0; i < Count; ++i) {
+                               var inflated_param = inflator.Inflate (types[i]);
+                               if (inflated_types == null) {
+                                       if (inflated_param == types[i])
+                                               continue;
+
+                                       default_value |= FixedParameters[i] is DefaultValueExpression;
+                                       inflated_types = new TypeSpec[types.Length];
+                                       Array.Copy (types, inflated_types, types.Length);       
+                               }
+
+                               inflated_types[i] = inflated_param;
+                       }
+
+                       if (inflated_types == null)
+                               return this;
+
+                       var clone = (AParametersCollection) MemberwiseClone ();
+                       clone.types = inflated_types;
+                       if (default_value) {
+                               for (int i = 0; i < Count; ++i) {
+                                       var dve = clone.FixedParameters[i] as DefaultValueExpression;
+                                       if (dve != null) {
+                                               throw new NotImplementedException ("net");
+                                               //      clone.FixedParameters [i].DefaultValue = new DefaultValueExpression ();
+                                       }
+                               }
+                       }
+
+                       return clone;
+               }
+
                public string ParameterDesc (int pos)
                {
                        if (types == null || types [pos] == null)
@@ -845,42 +894,10 @@ namespace Mono.CSharp {
                        return Parameter.GetModifierSignature (mod) + " " + type;
                }
 
-               public Type[] Types {
+               public TypeSpec[] Types {
                        get { return types; }
                        set { types = value; }
                }
-
-#if MS_COMPATIBLE
-               public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes)
-               {
-                       AParametersCollection p = (AParametersCollection) MemberwiseClone (); // Clone ();
-
-                       for (int i = 0; i < Count; ++i) {
-                               if (types[i].IsGenericType) {
-                                       Type[] gen_arguments_open = new Type[types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
-                                       Type[] gen_arguments = types[i].GetGenericArguments ();
-                                       for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
-                                               if (gen_arguments[ii].IsGenericParameter) {
-                                                       Type t = argTypes[gen_arguments[ii].GenericParameterPosition];
-                                                       gen_arguments_open[ii] = t;
-                                               } else
-                                                       gen_arguments_open[ii] = gen_arguments[ii];
-                                       }
-
-                                       p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
-                                       continue;
-                               }
-
-                               if (types[i].IsGenericParameter) {
-                                       Type gen_argument = argTypes[types[i].GenericParameterPosition];
-                                       p.types[i] = gen_argument;
-                                       continue;
-                               }
-                       }
-
-                       return p;
-               }
-#endif
        }
 
        //
@@ -888,7 +905,7 @@ namespace Mono.CSharp {
        //
        public class ParametersImported : AParametersCollection
        {
-               ParametersImported (AParametersCollection param, Type[] types)
+               ParametersImported (AParametersCollection param, TypeSpec[] types)
                {
                        this.parameters = param.FixedParameters;
                        this.types = types;
@@ -896,7 +913,7 @@ namespace Mono.CSharp {
                        has_params = param.HasParams;
                }
 
-               ParametersImported (IParameterData [] parameters, Type [] types, bool hasArglist, bool hasParams)
+               ParametersImported (IParameterData [] parameters, TypeSpec [] types, bool hasArglist, bool hasParams)
                {
                        this.parameters = parameters;
                        this.types = types;
@@ -904,60 +921,36 @@ namespace Mono.CSharp {
                        this.has_params = hasParams;
                }
 
-               public ParametersImported (IParameterData [] param, Type[] types)
+               public ParametersImported (IParameterData [] param, TypeSpec[] types)
                {
                        this.parameters = param;
                        this.types = types;
                }
 
-               public static AParametersCollection Create (MethodBase method)
+               public static AParametersCollection Create (TypeSpec parent, MethodBase method)
                {
-                       return Create (method.GetParameters (), method);
-               }
-
-               //
-               // Generic method parameters importer, param is shared between all instances
-               //
-               public static AParametersCollection Create (AParametersCollection param, MethodBase method)
-               {
-                       if (param.IsEmpty)
-                               return param;
-
-                       ParameterInfo [] pi = method.GetParameters ();
-                       Type [] types = new Type [pi.Length];
-                       for (int i = 0; i < types.Length; i++) {
-                               Type t = pi [i].ParameterType;
-                               if (t.IsByRef)
-                                       t = TypeManager.GetElementType (t);
-
-                               types [i] = TypeManager.TypeToCoreType (t);
-                       }
-
-                       return new ParametersImported (param, types);
+                       return Create (parent, method.GetParameters (), method);
                }
 
                //
                // Imports SRE parameters
                //
-               public static AParametersCollection Create (ParameterInfo [] pi, MethodBase method)
+               public static AParametersCollection Create (TypeSpec parent, ParameterInfo [] pi, MethodBase method)
                {
                        int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0;
 
                        if (pi.Length == 0 && varargs == 0)
                                return ParametersCompiled.EmptyReadOnlyParameters;
 
-                       Type [] types = new Type [pi.Length + varargs];
+                       TypeSpec [] types = new TypeSpec [pi.Length + varargs];
                        IParameterData [] par = new IParameterData [pi.Length + varargs];
                        bool is_params = false;
                        PredefinedAttribute extension_attr = PredefinedAttributes.Get.Extension;
-                       PredefinedAttribute param_attr = PredefinedAttributes.Get.ParamArray;
                        for (int i = 0; i < pi.Length; i++) {
-                               types [i] = TypeManager.TypeToCoreType (pi [i].ParameterType);
-
                                ParameterInfo p = pi [i];
                                Parameter.Modifier mod = 0;
                                Expression default_value = null;
-                               if (types [i].IsByRef) {
+                               if (p.ParameterType.IsByRef) {
                                        if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
                                                mod = Parameter.Modifier.OUT;
                                        else
@@ -966,14 +959,17 @@ namespace Mono.CSharp {
                                        //
                                        // Strip reference wrapping
                                        //
-                                       types [i] = TypeManager.GetElementType (types [i]);
-                               } else if (i == 0 && extension_attr.IsDefined && method != null && method.IsStatic &&
-                               (method.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
-                                       method.IsDefined (extension_attr.Type, false)) {
+                                       types [i] = Import.ImportType (p.ParameterType.GetElementType ());
+                               } else if (i == 0 && method.IsStatic && parent.IsStatic &&
+                                       extension_attr.IsDefined && extension_attr.IsDefined && method.IsDefined (extension_attr.Type.GetMetaInfo (), false)) {
                                        mod = Parameter.Modifier.This;
+                                       types[i] = Import.ImportType (p.ParameterType);
                                } else {
-                                       if (i >= pi.Length - 2 && types[i].IsArray) {
-                                               if (p.IsDefined (param_attr.Type, false)) {
+                                       types[i] = Import.ImportType (p.ParameterType);
+
+                                       if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
+                                               var cattrs = CustomAttributeData.GetCustomAttributes (p);
+                                               if (cattrs != null && cattrs.Any (l => l.Constructor.DeclaringType == typeof (ParamArrayAttribute))) {
                                                        mod = Parameter.Modifier.PARAMS;
                                                        is_params = true;
                                                }
@@ -986,7 +982,7 @@ namespace Mono.CSharp {
                                                } else if (value == null) {
                                                        default_value = new NullLiteral (Location.Null);
                                                } else {
-                                                       default_value = Constant.CreateConstant (null, value.GetType (), value, Location.Null);
+                                                       default_value = Constant.CreateConstant (null, Import.ImportType (value.GetType ()), value, Location.Null);
                                                }
                                        }
                                }
@@ -1018,10 +1014,10 @@ namespace Mono.CSharp {
                private ParametersCompiled ()
                {
                        parameters = new Parameter [0];
-                       types = Type.EmptyTypes;
+                       types = TypeSpec.EmptyTypes;
                }
 
-               private ParametersCompiled (Parameter [] parameters, Type [] types)
+               private ParametersCompiled (IParameterData [] parameters, TypeSpec [] types)
                {
                        this.parameters = parameters;
                    this.types = types;
@@ -1063,34 +1059,85 @@ namespace Mono.CSharp {
                        this.has_arglist = has_arglist;
                }
                
-               public static ParametersCompiled CreateFullyResolved (Parameter p, Type type)
+               public static ParametersCompiled CreateFullyResolved (Parameter p, TypeSpec type)
                {
-                       return new ParametersCompiled (new Parameter [] { p }, new Type [] { type });
+                       return new ParametersCompiled (new Parameter [] { p }, new TypeSpec [] { type });
                }
                
-               public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, Type[] types)
+               public static ParametersCompiled CreateFullyResolved (IParameterData[] parameters, TypeSpec[] types)
                {
                        return new ParametersCompiled (parameters, types);
                }
 
-               public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes)
+               public static AParametersCollection CreateFullyResolved (TypeSpec[] types)
+               {
+                       var pd = new ParameterData [types.Length];
+                       for (int i = 0; i < pd.Length; ++i)
+                               pd[i] = new ParameterData (null, Parameter.Modifier.NONE, null);
+
+                       return new ParametersCompiled (pd, types);
+               }
+
+               //
+               // Returns non-zero value for equal CLS parameter signatures
+               //
+               public static int IsSameClsSignature (AParametersCollection a, AParametersCollection b)
+               {
+                       int res = 0;
+
+                       for (int i = 0; i < a.Count; ++i) {
+                               var a_type = a.Types[i];
+                               var b_type = b.Types[i];
+                               if (TypeSpecComparer.Override.IsEqual (a_type, b_type)) {
+                                       const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
+                                       if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
+                                               res |= 1;
+
+                                       continue;
+                               }
+
+                               var ac_a = a_type as ArrayContainer;
+                               if (ac_a == null)
+                                       return 0;
+
+                               var ac_b = b_type as ArrayContainer;
+                               if (ac_b == null)
+                                       return 0;
+
+                               if (ac_a.Element is ArrayContainer || ac_b.Element is ArrayContainer) {
+                                       res |= 2;
+                                       continue;
+                               }
+
+                               if (ac_a.Rank != ac_b.Rank && TypeSpecComparer.Override.IsEqual (ac_a.Element, ac_b.Element)) {
+                                       res |= 1;
+                                       continue;
+                               }
+
+                               return 0;
+                       }
+
+                       return res;
+               }
+
+               public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, TypeSpec compilerTypes)
                {
                        return MergeGenerated (ctx, userParams, checkConflicts,
                                new Parameter [] { compilerParams },
-                               new Type [] { compilerTypes });
+                               new TypeSpec [] { compilerTypes });
                }
 
                //
                // Use this method when you merge compiler generated parameters with user parameters
                //
-               public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes)
+               public static ParametersCompiled MergeGenerated (CompilerContext ctx, ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, TypeSpec[] compilerTypes)
                {
                        Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
                        userParams.FixedParameters.CopyTo(all_params, 0);
 
-                       Type [] all_types;
+                       TypeSpec [] all_types;
                        if (userParams.types != null) {
-                               all_types = new Type [all_params.Length];
+                               all_types = new TypeSpec [all_params.Length];
                                userParams.Types.CopyTo (all_types, 0);
                        } else {
                                all_types = null;
@@ -1129,13 +1176,13 @@ namespace Mono.CSharp {
                        if (types != null)
                                return true;
                        
-                       types = new Type [Count];
+                       types = new TypeSpec [Count];
                        
                        bool ok = true;
                        Parameter p;
                        for (int i = 0; i < FixedParameters.Length; ++i) {
                                p = this [i];
-                               Type t = p.Resolve (ec);
+                               TypeSpec t = p.Resolve (ec, i);
                                if (t == null) {
                                        ok = false;
                                        continue;
@@ -1147,10 +1194,10 @@ namespace Mono.CSharp {
                        return ok;
                }
 
-               public void ResolveVariable ()
+               public void ResolveDefaultValues (ResolveContext rc)
                {
                        for (int i = 0; i < FixedParameters.Length; ++i) {
-                               this [i].ResolveVariable (i);
+                               this [i].ResolveDefaultValue (rc);
                        }
                }
 
index e2aed9a1cf31e5fd7bebe0deb14a21c3dfbf6624..9e2e5c40ba7ffa650438e53a6b32dfea40c41680 100644 (file)
@@ -1,8 +1,9 @@
 //
 // pending.cs: Pending method implementation
 //
-// Author:
+// Authors:
 //   Miguel de Icaza (miguel@gnu.org)
+//   Marek Safar (marek.safar@gmail.com)
 //
 // Dual licensed under the terms of the MIT X11 or GNU GPL
 //
@@ -14,12 +15,13 @@ using System;
 using System.Collections.Generic;
 using System.Reflection;
 using System.Reflection.Emit;
+using System.Linq;
 
 namespace Mono.CSharp {
 
        struct TypeAndMethods {
-               public Type          type;
-               public MethodInfo [] methods;
+               public TypeSpec          type;
+               public IList<MethodSpec> methods;
 
                // 
                // Whether it is optional, this is used to allow the explicit/implicit
@@ -30,14 +32,7 @@ namespace Mono.CSharp {
                // class X : IA { }  class Y : X, IA { IA.Explicit (); }
                //
                public bool          optional;
-               
-               // Far from ideal, but we want to avoid creating a copy
-               // of methods above.
-               public Type [][]     args;
-
-               //This is used to store the modifiers of arguments
-               public Parameter.Modifier [][] mods;
-               
+                               
                //
                // This flag on the method says `We found a match, but
                // because it was private, we could not use the match
@@ -47,95 +42,25 @@ namespace Mono.CSharp {
                // If a method is defined here, then we always need to
                // create a proxy for it.  This is used when implementing
                // an interface's indexer with a different IndexerName.
-               public MethodInfo [] need_proxy;
+               public MethodSpec [] need_proxy;
        }
 
-       public class PendingImplementation {
+       public class PendingImplementation
+       {
                /// <summary>
                ///   The container for this PendingImplementation
                /// </summary>
                TypeContainer container;
                
-               /// <summary>
-               ///   This filter is used by FindMembers, and it is used to
-               ///   extract only virtual/abstract fields
-               /// </summary>
-               static MemberFilter virtual_method_filter;
-
                /// <summary>
                ///   This is the array of TypeAndMethods that describes the pending implementations
                ///   (both interfaces and abstract methods in base class)
                /// </summary>
                TypeAndMethods [] pending_implementations;
 
-               static bool IsVirtualFilter (MemberInfo m, object filterCriteria)
-               {
-                       MethodInfo mi = m as MethodInfo;
-                       return (mi == null) ? false : mi.IsVirtual;
-               }
-
-               /// <summary>
-               ///   Inits the virtual_method_filter
-               /// </summary>
-               static PendingImplementation ()
-               {
-                       virtual_method_filter = new MemberFilter (IsVirtualFilter);
-               }
-
-               // <remarks>
-               //   Returns a list of the abstract methods that are exposed by all of our
-               //   bases that we must implement.  Notice that this `flattens' the
-               //   method search space, and takes into account overrides.  
-               // </remarks>
-               static IList<MethodBase> GetAbstractMethods (Type t)
-               {
-                       List<MethodBase> list = null;
-                       bool searching = true;
-                       Type current_type = t;
-                       
-                       do {
-                               MemberList mi;
-                               
-                               mi = TypeContainer.FindMembers (
-                                       current_type, MemberTypes.Method,
-                                       BindingFlags.Public | BindingFlags.NonPublic |
-                                       BindingFlags.Instance | BindingFlags.DeclaredOnly,
-                                       virtual_method_filter, null);
-
-                               if (current_type == TypeManager.object_type)
-                                       searching = false;
-                               else {
-                                       current_type = current_type.BaseType;
-                                       if (!current_type.IsAbstract)
-                                               searching = false;
-                               }
-
-                               if (mi.Count == 0)
-                                       continue;
-
-                               if (mi.Count == 1 && !(mi [0] is MethodBase))
-                                       searching = false;
-                               else 
-                                       list = TypeManager.CopyNewMethods (list, mi);
-                       } while (searching);
-
-                       if (list == null)
-                               return null;
-                       
-                       for (int i = 0; i < list.Count; i++){
-                               while (list.Count > i && !((MethodInfo) list [i]).IsAbstract)
-                                       list.RemoveAt (i);
-                       }
-
-                       if (list.Count == 0)
-                               return null;
-
-                       return list;
-               }
-
-               PendingImplementation (TypeContainer container, MissingInterfacesInfo[] missing_ifaces, IList<MethodBase> abstract_methods, int total)
+               PendingImplementation (TypeContainer container, MissingInterfacesInfo[] missing_ifaces, IList<MethodSpec> abstract_methods, int total)
                {
-                       TypeBuilder type_builder = container.TypeBuilder;
+                       var type_builder = container.Definition;
                        
                        this.container = container;
                        pending_implementations = new TypeAndMethods [total];
@@ -143,91 +68,34 @@ namespace Mono.CSharp {
                        int i = 0;
                        if (abstract_methods != null) {
                                int count = abstract_methods.Count;
-                               pending_implementations [i].methods = new MethodInfo [count];
-                               pending_implementations [i].need_proxy = new MethodInfo [count];
-                               
-                               abstract_methods.CopyTo (pending_implementations [i].methods, 0);
+                               pending_implementations [i].methods = new MethodSpec [count];
+                               pending_implementations [i].need_proxy = new MethodSpec [count];
+
+                               pending_implementations [i].methods = abstract_methods;
                                pending_implementations [i].found = new MethodData [count];
-                               pending_implementations [i].args = new Type [count][];
-                               pending_implementations [i].mods = new Parameter.Modifier [count][];
                                pending_implementations [i].type = type_builder;
-
-                               int j = 0;
-                               foreach (MemberInfo m in abstract_methods) {
-                                       MethodInfo mi = (MethodInfo) m;
-                                       
-                                       AParametersCollection pd = TypeManager.GetParameterData (mi);
-                                       Type [] types = pd.Types;
-                                       
-                                       pending_implementations [i].args [j] = types;
-                                       pending_implementations [i].mods [j] = null;
-                                       if (pd.Count > 0) {
-                                               Parameter.Modifier [] pm = new Parameter.Modifier [pd.Count];
-                                               for (int k = 0; k < pd.Count; k++)
-                                                       pm [k] = pd.FixedParameters[k].ModFlags;
-                                               pending_implementations [i].mods [j] = pm;
-                                       }
-                                               
-                                       j++;
-                               }
                                ++i;
                        }
 
                        foreach (MissingInterfacesInfo missing in missing_ifaces) {
-                               MethodInfo [] mi;
-                               Type t = missing.Type;
-                               
-                               if (!t.IsInterface)
-                                       continue;
-
-                               if (t is TypeBuilder){
-                                       TypeContainer iface;
+                               var iface = missing.Type;
+                               var mi = MemberCache.GetInterfaceMembers (iface);
 
-                                       iface = TypeManager.LookupInterface (t);
-                                       
-                                       mi = iface.GetMethods ();
-                               } else 
-                                       mi = t.GetMethods ();
-                               
-                               int count = mi.Length;
-                               pending_implementations [i].type = t;
+                               int count = mi.Count;
+                               pending_implementations [i].type = iface;
                                pending_implementations [i].optional = missing.Optional;
                                pending_implementations [i].methods = mi;
-                               pending_implementations [i].args = new Type [count][];
-                               pending_implementations [i].mods = new Parameter.Modifier [count][];
                                pending_implementations [i].found = new MethodData [count];
-                               pending_implementations [i].need_proxy = new MethodInfo [count];
-                               
-                               int j = 0;
-                               foreach (MethodInfo m in mi){
-                                       pending_implementations [i].args [j] = Type.EmptyTypes;
-                                       pending_implementations [i].mods [j] = null;
-
-                                       // If there is a previous error, just ignore
-                                       if (m == null)
-                                               continue;
-
-                                       AParametersCollection pd = TypeManager.GetParameterData (m);
-                                       pending_implementations [i].args [j] = pd.Types;
-                                       
-                                       if (pd.Count > 0){
-                                               Parameter.Modifier [] pm = new Parameter.Modifier [pd.Count];
-                                               for (int k = 0; k < pd.Count; k++)
-                                                       pm [k] = pd.FixedParameters [k].ModFlags;
-                                               pending_implementations [i].mods [j] = pm;
-                                       }
-                       
-                                       j++;
-                               }
+                               pending_implementations [i].need_proxy = new MethodSpec [count];
                                i++;
                        }
                }
 
                struct MissingInterfacesInfo {
-                       public Type Type;
+                       public TypeSpec Type;
                        public bool Optional;
 
-                       public MissingInterfacesInfo (Type t)
+                       public MissingInterfacesInfo (TypeSpec t)
                        {
                                Type = t;
                                Optional = false;
@@ -236,42 +104,40 @@ namespace Mono.CSharp {
 
                static MissingInterfacesInfo [] EmptyMissingInterfacesInfo = new MissingInterfacesInfo [0];
                
-               static MissingInterfacesInfo [] GetMissingInterfaces (TypeBuilder type_builder)
+               static MissingInterfacesInfo [] GetMissingInterfaces (TypeContainer container)
                {
                        //
-                       // Notice that TypeBuilders will only return the interfaces that the Type
+                       // Notice that Interfaces will only return the interfaces that the Type
                        // is supposed to implement, not all the interfaces that the type implements.
                        //
-                       // Even better -- on MS it returns an empty array, no matter what.
-                       //
-                       // Completely broken.  So we do it ourselves!
-                       //
-                       Type [] impl = TypeManager.GetExplicitInterfaces (type_builder);
+                       var impl = container.Definition.Interfaces;
 
-                       if (impl == null || impl.Length == 0)
+                       if (impl == null || impl.Count == 0)
                                return EmptyMissingInterfacesInfo;
 
-                       MissingInterfacesInfo [] ret = new MissingInterfacesInfo [impl.Length];
+                       MissingInterfacesInfo[] ret = new MissingInterfacesInfo[impl.Count];
 
-                       for (int i = 0; i < impl.Length; i++)
+                       for (int i = 0; i < impl.Count; i++)
                                ret [i] = new MissingInterfacesInfo (impl [i]);
 
                        // we really should not get here because Object doesnt implement any
                        // interfaces. But it could implement something internal, so we have
                        // to handle that case.
-                       if (type_builder.BaseType == null)
+                       if (container.BaseType == null)
                                return ret;
                        
-                       Type [] base_impls = TypeManager.GetInterfaces (type_builder.BaseType);
-                       
-                       foreach (Type t in base_impls) {
-                               for (int i = 0; i < ret.Length; i ++) {
-                                       if (t == ret [i].Type) {
-                                               ret [i].Optional = true;
-                                               break;
+                       var base_impls = container.BaseType.Interfaces;
+                       if (base_impls != null) {
+                               foreach (TypeSpec t in base_impls) {
+                                       for (int i = 0; i < ret.Length; i++) {
+                                               if (t == ret[i].Type) {
+                                                       ret[i].Optional = true;
+                                                       break;
+                                               }
                                        }
                                }
                        }
+
                        return ret;
                }
                
@@ -284,11 +150,9 @@ namespace Mono.CSharp {
                //
                static public PendingImplementation GetPendingImplementations (TypeContainer container)
                {
-                       TypeBuilder type_builder = container.TypeBuilder;
-                       MissingInterfacesInfo [] missing_interfaces;
-                       Type b = type_builder.BaseType;
+                       TypeSpec b = container.BaseType;
 
-                       missing_interfaces = GetMissingInterfaces (type_builder);
+                       var missing_interfaces = GetMissingInterfaces (container);
 
                        //
                        // If we are implementing an abstract class, and we are not
@@ -298,11 +162,11 @@ namespace Mono.CSharp {
                        //
                        // We also pre-compute the methods.
                        //
-                       bool implementing_abstract = ((b != null) && b.IsAbstract && !type_builder.IsAbstract);
-                       IList<MethodBase> abstract_methods = null;
+                       bool implementing_abstract = ((b != null) && b.IsAbstract && (container.ModFlags & Modifiers.ABSTRACT) == 0);
+                       IList<MethodSpec> abstract_methods = null;
 
                        if (implementing_abstract){
-                               abstract_methods = GetAbstractMethods (b);
+                               abstract_methods = MemberCache.GetNotImplementedAbstractMethods (b);
                                
                                if (abstract_methods == null)
                                        implementing_abstract = false;
@@ -326,12 +190,12 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Whether the specified method is an interface method implementation
                /// </summary>
-               public MethodInfo IsInterfaceMethod (string name, Type ifaceType, MethodData method)
+               public MethodSpec IsInterfaceMethod (MemberName name, TypeSpec ifaceType, MethodData method)
                {
                        return InterfaceMethod (name, ifaceType, method, Operation.Lookup);
                }
 
-               public void ImplementMethod (string name, Type ifaceType, MethodData method, bool clear_one) 
+               public void ImplementMethod (MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one) 
                {
                        InterfaceMethod (name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll);
                }
@@ -353,38 +217,45 @@ namespace Mono.CSharp {
                ///   that was used in the interface, then we always need to create a proxy for it.
                ///
                /// </remarks>
-               public MethodInfo InterfaceMethod (string name, Type iType, MethodData method, Operation op)
+               public MethodSpec InterfaceMethod (MemberName name, TypeSpec iType, MethodData method, Operation op)
                {
                        if (pending_implementations == null)
                                return null;
 
-                       Type ret_type = method.method.ReturnType;
+                       TypeSpec ret_type = method.method.ReturnType;
                        ParametersCompiled args = method.method.ParameterInfo;
-                       int arg_len = args.Count;
                        bool is_indexer = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod;
 
                        foreach (TypeAndMethods tm in pending_implementations){
                                if (!(iType == null || tm.type == iType))
                                        continue;
 
-                               int method_count = tm.methods.Length;
-                               MethodInfo m;
+                               int method_count = tm.methods.Count;
+                               MethodSpec m;
                                for (int i = 0; i < method_count; i++){
                                        m = tm.methods [i];
 
                                        if (m == null)
                                                continue;
 
-                                       //
-                                       // Check if we have the same parameters
-                                       //
+                                       if (is_indexer) {
+                                               if (!m.IsAccessor || m.Parameters.IsEmpty)
+                                                       continue;
+                                       } else {
+                                               if (name.Name != m.Name)
+                                                       continue;
 
-                                       if (tm.args [i] == null && arg_len != 0)
-                                               continue;
-                                       if (tm.args [i] != null && tm.args [i].Length != arg_len)
+                                               if (m.Arity != name.Arity)
+                                                       continue;
+                                       }
+
+                                       if (!TypeSpecComparer.Override.IsEqual (m.Parameters, args))
                                                continue;
 
-                                       string mname = TypeManager.GetMethodName (m);
+                                       if (!TypeSpecComparer.Override.IsEqual (m.ReturnType, ret_type)) {
+                                               tm.found[i] = method;
+                                               continue;
+                                       }
 
                                        //
                                        // `need_proxy' is not null when we're implementing an
@@ -394,45 +265,6 @@ namespace Mono.CSharp {
                                        // signature and not on the name (this is done in the Lookup
                                        // for an interface indexer).
                                        //
-
-                                       if (is_indexer) {
-                                               IMethodData md = TypeManager.GetMethod (m);
-                                               if (md != null) {
-                                                       if (!(md is Indexer.SetIndexerMethod || md is Indexer.GetIndexerMethod))
-                                                               continue;
-                                               } else {
-                                                       if (TypeManager.GetPropertyFromAccessor (m) == null)
-                                                               continue;
-                                               }
-                                       } else if (name != mname) {
-                                               continue;
-                                       }
-
-                                       int j;
-
-                                       for (j = 0; j < arg_len; j++) {
-                                               if (!TypeManager.IsEqual (tm.args [i][j], args.Types [j]))
-                                                       break;
-                                               if (tm.mods [i][j] == args.FixedParameters [j].ModFlags)
-                                                       continue;
-                                               // The modifiers are different, but if one of them
-                                               // is a PARAMS modifier, and the other isn't, ignore
-                                               // the difference.
-                                               if (tm.mods [i][j] != Parameter.Modifier.PARAMS &&
-                                                   args.FixedParameters [j].ModFlags != Parameter.Modifier.PARAMS)
-                                                       break;
-                                       }
-                                       if (j != arg_len)
-                                               continue;
-
-                                       Type rt = TypeManager.TypeToCoreType (m.ReturnType);
-                                       if (!TypeManager.IsEqual (ret_type, rt) &&
-                                               !(ret_type == null && rt == TypeManager.void_type) &&
-                                               !(rt == null && ret_type == TypeManager.void_type)) {
-                                               tm.found [i] = method;
-                                               continue;
-                                       }
-
                                        if (op != Operation.Lookup) {
                                                // If `t != null', then this is an explicitly interface
                                                // implementation and we can always clear the method.
@@ -440,10 +272,10 @@ namespace Mono.CSharp {
                                                // interface indexer.  In this case, we need to create
                                                // a proxy if the implementation's IndexerName doesn't
                                                // match the IndexerName in the interface.
-                                               if (iType == null && name != mname)
-                                                       tm.need_proxy [i] = method.MethodBuilder;
-                                               else
-                                                       tm.methods [i] = null;
+                                               if (iType == null && name.Name != m.Name) {     // TODO: This is very expensive comparison
+                                                       tm.need_proxy[i] = method.method.Spec;
+                                               else
+                                                       tm.methods[i] = null;
                                        } else {
                                                tm.found [i] = method;
                                        }
@@ -471,11 +303,17 @@ namespace Mono.CSharp {
                ///   For that case, we create an explicit implementation function
                ///   I.M in Y.
                /// </summary>
-               void DefineProxy (Type iface, MethodInfo base_method, MethodInfo iface_method,
-                                 AParametersCollection param)
+               void DefineProxy (TypeSpec iface, MethodSpec base_method, MethodSpec iface_method)
                {
                        // TODO: Handle nested iface names
-                       string proxy_name = SimpleName.RemoveGenericArity (iface.FullName) + "." + iface_method.Name;
+                       string proxy_name;
+                       var ns = iface.MemberDefinition.Namespace;
+                       if (string.IsNullOrEmpty (ns))
+                               proxy_name = iface.MemberDefinition.Name + "." + iface_method.Name;
+                       else
+                               proxy_name = ns + "." + iface.MemberDefinition.Name + "." + iface_method.Name;
+
+                       var param = iface_method.Parameters;
 
                        MethodBuilder proxy = container.TypeBuilder.DefineMethod (
                                proxy_name,
@@ -484,14 +322,10 @@ namespace Mono.CSharp {
                                MethodAttributes.CheckAccessOnOverride |
                                MethodAttributes.Virtual,
                                CallingConventions.Standard | CallingConventions.HasThis,
-                               base_method.ReturnType, param.GetEmitTypes ());
-
-                       Type[] gargs = TypeManager.GetGenericArguments (iface_method);
-                       if (gargs.Length > 0) {
-                               string[] gnames = new string[gargs.Length];
-                               for (int i = 0; i < gargs.Length; ++i)
-                                       gnames[i] = gargs[i].Name;
+                               base_method.ReturnType.GetMetaInfo (), param.GetMetaInfo ());
 
+                       if (iface_method.IsGeneric) {
+                               var gnames = iface_method.GenericDefinition.TypeParameters.Select (l => l.Name).ToArray ();
                                proxy.DefineGenericParameters (gnames);
                        }
 
@@ -502,15 +336,15 @@ namespace Mono.CSharp {
                        }
 
                        int top = param.Count;
-                       ILGenerator ig = proxy.GetILGenerator ();
+                       var ec = new EmitContext (null, proxy.GetILGenerator (), null);
 
                        for (int i = 0; i <= top; i++)
-                               ParameterReference.EmitLdArg (ig, i);
+                               ParameterReference.EmitLdArg (ec, i);
 
-                       ig.Emit (OpCodes.Call, base_method);
-                       ig.Emit (OpCodes.Ret);
+                       ec.Emit (OpCodes.Call, base_method);
+                       ec.Emit (OpCodes.Ret);
 
-                       container.TypeBuilder.DefineMethodOverride (proxy, iface_method);
+                       container.TypeBuilder.DefineMethodOverride (proxy, (MethodInfo) iface_method.GetMetaInfo ());
                }
                
                /// <summary>
@@ -518,39 +352,26 @@ namespace Mono.CSharp {
                ///   the given method (which turns out, it is valid to have an interface
                ///   implementation in a base
                /// </summary>
-               bool BaseImplements (Type iface_type, MethodInfo mi, out MethodInfo base_method)
+               bool BaseImplements (TypeSpec iface_type, MethodSpec mi, out MethodSpec base_method)
                {
-                       MethodSignature ms;
-                       
-                       AParametersCollection param = TypeManager.GetParameterData (mi);
-                       ms = new MethodSignature (mi.Name, TypeManager.TypeToCoreType (mi.ReturnType), param.Types);
-                       MemberList list = TypeContainer.FindMembers (
-                               container.TypeBuilder.BaseType, MemberTypes.Method | MemberTypes.Property,
-                               BindingFlags.Public | BindingFlags.Instance,
-                               MethodSignature.method_signature_filter, ms);
-
-                       if (list.Count == 0) {
-                               base_method = null;
-                               return false;
-                       }
-
-                       if (TypeManager.ImplementsInterface (container.TypeBuilder.BaseType, iface_type)) {
-                               base_method = null;
-                               return true;
-                       }
+                       var base_type = container.BaseType;
+                       base_method = (MethodSpec) MemberCache.FindMember (base_type, new MemberFilter (mi), BindingRestriction.None);
 
-                       base_method = (MethodInfo) list [0];
+                       if (base_method == null || (base_method.Modifiers & Modifiers.PUBLIC) == 0)
+                               return false;
 
                        if (base_method.DeclaringType.IsInterface)
                                return false;
 
-                       if (!base_method.IsPublic)
-                               return false;
+                       // Why was it here ????
+                       //if (TypeManager.ImplementsInterface (base_type, iface_type)) {
+                       //      return true;
+                       //}
 
                        if (!base_method.IsAbstract && !base_method.IsVirtual)
                                // FIXME: We can avoid creating a proxy if base_method can be marked 'final virtual' instead.
                                //        However, it's too late now, the MethodBuilder has already been created (see bug 377519)
-                               DefineProxy (iface_type, base_method, mi, param);
+                               DefineProxy (iface_type, base_method, mi);
 
                        return true;
                }
@@ -566,63 +387,64 @@ namespace Mono.CSharp {
                        int i;
                        
                        for (i = 0; i < top; i++){
-                               Type type = pending_implementations [i].type;
+                               TypeSpec type = pending_implementations [i].type;
                                int j = 0;
 
                                bool base_implements_type = type.IsInterface &&
-                                       container.TypeBuilder.BaseType != null &&
-                                       TypeManager.ImplementsInterface (container.TypeBuilder.BaseType, type);
+                                       container.BaseType != null &&
+                                       container.BaseType.ImplementsInterface (type);
 
-                               foreach (MethodInfo mi in pending_implementations [i].methods){
+                               foreach (var mi in pending_implementations [i].methods){
                                        if (mi == null)
                                                continue;
 
                                        if (type.IsInterface){
-                                               MethodInfo need_proxy =
+                                               var need_proxy =
                                                        pending_implementations [i].need_proxy [j];
 
                                                if (need_proxy != null) {
-                                                       DefineProxy (type, need_proxy, mi, TypeManager.GetParameterData (mi));
+                                                       DefineProxy (type, need_proxy, mi);
                                                        continue;
                                                }
 
                                                if (pending_implementations [i].optional)
                                                        continue;
 
-                                               MethodInfo candidate = null;
+                                               MethodSpec candidate = null;
                                                if (base_implements_type || BaseImplements (type, mi, out candidate))
                                                        continue;
 
                                                if (candidate == null) {
                                                        MethodData md = pending_implementations [i].found [j];
                                                        if (md != null)
-                                                               candidate = md.MethodBuilder;
+                                                               candidate = md.method.Spec;
                                                }
-                                               
+
                                                Report.SymbolRelatedToPreviousError (mi);
                                                if (candidate != null) {
                                                        Report.SymbolRelatedToPreviousError (candidate);
                                                        if (candidate.IsStatic) {
                                                                Report.Error (736, container.Location,
                                                                        "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' is static",
-                                                                       container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true), TypeManager.CSharpSignature (candidate));
-                                                       } else if (!candidate.IsPublic) {
+                                                                       container.GetSignatureForError (), mi.GetSignatureForError (), TypeManager.CSharpSignature (candidate));
+                                                       } else if ((candidate.Modifiers & Modifiers.PUBLIC) == 0) {
                                                                Report.Error (737, container.Location,
                                                                        "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' in not public",
-                                                                       container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true), TypeManager.CSharpSignature (candidate, true));
+                                                                       container.GetSignatureForError (), mi.GetSignatureForError (), candidate.GetSignatureForError ());
                                                        } else {
                                                                Report.Error (738, container.Location,
                                                                        "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' return type `{3}' does not match interface member return type `{4}'",
-                                                                       container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true), TypeManager.CSharpSignature (candidate),
+                                                                       container.GetSignatureForError (), mi.GetSignatureForError (), TypeManager.CSharpSignature (candidate),
                                                                        TypeManager.CSharpName (candidate.ReturnType), TypeManager.CSharpName (mi.ReturnType));
                                                        }
                                                } else {
                                                        Report.Error (535, container.Location, "`{0}' does not implement interface member `{1}'",
-                                                               container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true));
+                                                               container.GetSignatureForError (), mi.GetSignatureForError ());
                                                }
                                        } else {
+                                               Report.SymbolRelatedToPreviousError (mi);
                                                Report.Error (534, container.Location, "`{0}' does not implement inherited abstract member `{1}'",
-                                                       container.GetSignatureForError (), TypeManager.CSharpSignature (mi, true));
+                                                       container.GetSignatureForError (), mi.GetSignatureForError ());
                                        }
                                        errors = true;
                                        j++;
@@ -630,5 +452,5 @@ namespace Mono.CSharp {
                        }
                        return errors;
                }
-       } /* end of class */
+       }
 }
index c40680d86f847effa1b6094ebdc0c0fda8965c9c..28e9e1e8095e270fb64228e68cebb501aa1fbc41 100644 (file)
@@ -47,7 +47,7 @@ namespace Mono.CSharp
                        if (!base.VerifyClsCompliance ())
                                return false;
 
-                       if (!AttributeTester.IsClsCompliant (MemberType)) {
+                       if (!MemberType.IsCLSCompliant ()) {
                                Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
                                        GetSignatureForError ());
                        }
@@ -85,26 +85,91 @@ namespace Mono.CSharp
                }
        }
 
-       public class PropertySpec : MemberSpec
+       public class PropertySpec : MemberSpec, IInterfaceMemberSpec
        {
                PropertyInfo info;
+               TypeSpec memberType;
+               MethodSpec set, get;
 
-               public PropertySpec (MemberKind kind, IMemberDefinition definition, PropertyInfo info, Modifiers modifiers)
-                       : base (kind, definition, info.Name, modifiers)
+               public PropertySpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, PropertyInfo info, Modifiers modifiers)
+                       : base (kind, declaringType, definition, modifiers)
                {
                        this.info = info;
+                       this.memberType = memberType;
                }
 
-               public override Type DeclaringType {
-                       get { return info.DeclaringType; }
+               #region Properties
+
+               public MethodSpec Get {
+                       get {
+                               return get;
+                       }
+                       set {
+                               get = value;
+                               get.IsAccessor = true;
+                       }
+               }
+
+               public MethodSpec Set { 
+                       get {
+                               return set;
+                       }
+                       set {
+                               set = value;
+                               set.IsAccessor = true;
+                       }
+               }
+
+               public bool IsNotRealProperty {
+                       get {
+                               return (state & StateFlags.IsNotRealProperty) != 0;
+                       }
+                       set {
+                               state |= StateFlags.IsNotRealProperty;
+                       }
+               }
+
+               public bool HasDifferentAccessibility {
+                       get {
+                               return HasGet && HasSet && 
+                                       (Get.Modifiers & Modifiers.AccessibilityMask) != (Set.Modifiers & Modifiers.AccessibilityMask);
+                       }
+               }
+
+               public bool HasGet {
+                       get {
+                               return Get != null && Get.Kind != MemberKind.FakeMethod;
+                       }
+               }
+
+               public bool HasSet {
+                       get {
+                               return Set != null && Set.Kind != MemberKind.FakeMethod;
+                       }
                }
 
                public PropertyInfo MetaInfo {
-                       get { return info; }
+                       get {
+                               if ((state & StateFlags.PendingMetaInflate) != 0)
+                                       throw new NotSupportedException ();
+
+                               return info;
+                       }
                }
 
-               public Type PropertyType {
-                       get { return info.PropertyType; }
+               public TypeSpec MemberType {
+                       get {
+                               return memberType;
+                       }
+               }
+
+               #endregion
+
+               public override MemberSpec InflateMember (TypeParameterInflator inflator)
+               {
+                       var ps = (PropertySpec) base.InflateMember (inflator);
+                       ps.memberType = inflator.Inflate (memberType);
+                       return ps;
                }
        }
 
@@ -132,6 +197,8 @@ namespace Mono.CSharp
                        {
                                base.Define (parent);
 
+                               Spec = new MethodSpec (IsDummy ? MemberKind.FakeMethod : MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
+
                                if (IsDummy)
                                        return null;
                                
@@ -140,12 +207,12 @@ namespace Mono.CSharp
                                if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
                                        return null;
 
-                               Spec = new MethodSpec (MemberKind.Method, this, method_data.MethodBuilder, ParameterInfo, ModFlags);
+                               Spec.SetMetaInfo (method_data.MethodBuilder);
 
                                return method_data.MethodBuilder;
                        }
 
-                       public override Type ReturnType {
+                       public override TypeSpec ReturnType {
                                get {
                                        return method.MemberType;
                                }
@@ -174,7 +241,7 @@ namespace Mono.CSharp
                                base (method, "set_")
                        {
                                parameters = new ParametersCompiled (Compiler,
-                                       new Parameter (method.type_name, "value", Parameter.Modifier.NONE, null, Location));
+                                       new Parameter (method.type_expr, "value", Parameter.Modifier.NONE, null, Location));
                        }
 
                        public SetMethod (PropertyBase method, Accessor accessor):
@@ -183,7 +250,7 @@ namespace Mono.CSharp
                                this.parameters = accessor.Parameters;
                        }
 
-                       protected override void ApplyToExtraTarget (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+                       protected override void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                        {
                                if (a.Target == AttributeTargets.Parameter) {
                                        if (param_attr == null)
@@ -208,6 +275,8 @@ namespace Mono.CSharp
                                
                                base.Define (parent);
 
+                               Spec = new MethodSpec (IsDummy ? MemberKind.FakeMethod : MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
+
                                if (IsDummy)
                                        return null;
 
@@ -216,12 +285,12 @@ namespace Mono.CSharp
                                if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
                                        return null;
 
-                               Spec = new MethodSpec (MemberKind.Method, this, method_data.MethodBuilder, ParameterInfo, ModFlags);
+                               Spec.SetMetaInfo (method_data.MethodBuilder);
 
                                return method_data.MethodBuilder;
                        }
 
-                       public override Type ReturnType {
+                       public override TypeSpec ReturnType {
                                get {
                                        return TypeManager.void_type;
                                }
@@ -260,7 +329,7 @@ namespace Mono.CSharp
                                }
                        }
 
-                       public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+                       public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                        {
                                if (a.IsInternalMethodImplAttribute) {
                                        method.is_external_implementation = true;
@@ -286,12 +355,12 @@ namespace Mono.CSharp
 
                                if (IsDummy) {
                                        if (method.InterfaceType != null && parent.PartialContainer.PendingImplementations != null) {
-                                               MethodInfo mi = parent.PartialContainer.PendingImplementations.IsInterfaceMethod (
-                                                       MethodName.Name, method.InterfaceType, new MethodData (method, ModFlags, flags, this));
+                                               var mi = parent.PartialContainer.PendingImplementations.IsInterfaceMethod (
+                                                       MethodName, method.InterfaceType, new MethodData (method, ModFlags, flags, this));
                                                if (mi != null) {
                                                        Report.SymbolRelatedToPreviousError (mi);
                                                        Report.Error (551, Location, "Explicit interface implementation `{0}' is missing accessor `{1}'",
-                                                               method.GetSignatureForError (), TypeManager.CSharpSignature (mi, true));
+                                                               method.GetSignatureForError (), mi.GetSignatureForError ());
                                                }
                                        }
                                        return null;
@@ -342,34 +411,19 @@ namespace Mono.CSharp
                                }
                        }
 
-                       public override ObsoleteAttribute GetObsoleteAttribute ()
+                       public override ObsoleteAttribute GetAttributeObsolete ()
                        {
-                               return method.GetObsoleteAttribute ();
+                               return method.GetAttributeObsolete ();
                        }
 
                        public override string GetSignatureForError()
                        {
-                               return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
+                               return method.GetSignatureForError () + "." + prefix.Substring (0, 3);
                        }
 
                        void CheckModifiers (Modifiers modflags)
                        {
-                               modflags &= Modifiers.AccessibilityMask;
-                               Modifiers flags = 0;
-                               Modifiers mflags = method.ModFlags & Modifiers.AccessibilityMask;
-
-                               if ((mflags & Modifiers.PUBLIC) != 0) {
-                                       flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
-                               }
-                               else if ((mflags & Modifiers.PROTECTED) != 0) {
-                                       if ((mflags & Modifiers.INTERNAL) != 0)
-                                               flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
-
-                                       flags |= Modifiers.PRIVATE;
-                               } else if ((mflags & Modifiers.INTERNAL) != 0)
-                                       flags |= Modifiers.PRIVATE;
-
-                               if ((mflags == modflags) || (modflags & (~flags)) != 0) {
+                               if (!ModifiersExtensions.IsRestrictedModifier (modflags & Modifiers.AccessibilityMask, method.ModFlags & Modifiers.AccessibilityMask)) {
                                        Report.Error (273, Location,
                                                "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
                                                GetSignatureForError (), method.GetSignatureForError ());
@@ -381,7 +435,7 @@ namespace Mono.CSharp
                                if ((caching_flags & Flags.MethodOverloadsExist) == 0)
                                        return true;
 
-                               return Parent.MemberCache.CheckExistingMembersOverloads (this, Name, ParameterInfo, Report);
+                               return Parent.MemberCache.CheckExistingMembersOverloads (this, ParameterInfo);
                        }
                }
 
@@ -399,7 +453,7 @@ namespace Mono.CSharp
                         this.define_set_first = define_set_first;
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.HasSecurityAttribute) {
                                a.Error_InvalidSecurityParent ();
@@ -411,7 +465,7 @@ namespace Mono.CSharp
                                return;
                        }
 
-                       PropertyBuilder.SetCustomAttribute (ctor, cdata);
+                       PropertyBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
                public override AttributeTargets AttributeTargets {
@@ -420,19 +474,62 @@ namespace Mono.CSharp
                        }
                }
 
+               protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
+               {
+                       var ok = base.CheckOverrideAgainstBase (base_member);
+
+                       //
+                       // Check base property accessors conflict
+                       //
+                       var base_prop = (PropertySpec) base_member;
+                       if (!Get.IsDummy) {
+                               if (!base_prop.HasGet) {
+                                       Report.SymbolRelatedToPreviousError (base_prop);
+                                       Report.Error (545, Get.Location,
+                                               "`{0}': cannot override because `{1}' does not have an overridable get accessor",
+                                               Get.GetSignatureForError (), base_prop.GetSignatureForError ());
+                                       ok = false;
+                               } else if (Get.HasCustomAccessModifier || base_prop.HasDifferentAccessibility) {
+                                       if (!CheckAccessModifiers (Get, base_prop.Get)) {
+                                               Error_CannotChangeAccessModifiers (Get, base_prop.Get);
+                                               ok = false;
+                                       }
+                               }
+                       }
+
+                       if (!Set.IsDummy) {
+                               if (!base_prop.HasSet) {
+                                       Report.SymbolRelatedToPreviousError (base_prop);
+                                       Report.Error (546, Set.Location,
+                                               "`{0}': cannot override because `{1}' does not have an overridable set accessor",
+                                               Set.GetSignatureForError (), base_prop.GetSignatureForError ());
+                                       ok = false;
+                               } else if (Set.HasCustomAccessModifier || base_prop.HasDifferentAccessibility) {
+                                       if (!CheckAccessModifiers (Set, base_prop.Set)) {
+                                               Error_CannotChangeAccessModifiers (Set, base_prop.Set);
+                                               ok = false;
+                                       }
+                               }
+                       }
+
+                       if (!Set.HasCustomAccessModifier && !Get.HasCustomAccessModifier) {
+                               if (!CheckAccessModifiers (this, base_prop)) {
+                                       Error_CannotChangeAccessModifiers (this, base_prop);
+                                       ok = false;
+                               }
+                       }
+
+                       return ok;
+               }
+
                protected override void DoMemberTypeDependentChecks ()
                {
                        base.DoMemberTypeDependentChecks ();
 
                        IsTypePermitted ();
-#if MS_COMPATIBLE
-                       if (MemberType.IsGenericParameter)
-                               return;
-#endif
 
-                       if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
-                               Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
-                       }
+                       if (MemberType.IsStatic)
+                               Error_StaticReturnType ();
                }
 
                protected override void DoMemberTypeIndependentChecks ()
@@ -479,85 +576,33 @@ namespace Mono.CSharp
                                DefineSet (!define_set_first);
                }
 
-               protected void DefineBuilders (MemberKind kind, Type[] parameterTypes)
+               protected void DefineBuilders (MemberKind kind, ParametersCompiled parameters)
                {
                        // FIXME - PropertyAttributes.HasDefault ?
 
                        PropertyBuilder = Parent.TypeBuilder.DefineProperty (
-                               GetFullName (MemberName), PropertyAttributes.None, MemberType, parameterTypes);
+                               GetFullName (MemberName), PropertyAttributes.None, MemberType.GetMetaInfo (), parameters.GetMetaInfo ());
+
+                       PropertySpec spec;
+                       if (kind == MemberKind.Indexer)
+                               spec = new IndexerSpec (Parent.Definition, this, MemberType, parameters, PropertyBuilder, ModFlags);
+                       else
+                               spec = new PropertySpec (kind, Parent.Definition, this, MemberType, PropertyBuilder, ModFlags);
+
+                       spec.Get = Get.Spec;
+                       spec.Set = Set.Spec;
 
                        if (!Get.IsDummy) {
                                PropertyBuilder.SetGetMethod (GetBuilder);
-                               Parent.MemberCache.AddMember (GetBuilder, Get.Spec);
                        }
 
                        if (!Set.IsDummy) {
                                PropertyBuilder.SetSetMethod (SetBuilder);
-                               Parent.MemberCache.AddMember (SetBuilder, Set.Spec);
                        }
 
-                       var spec = new PropertySpec (kind, this, PropertyBuilder, ModFlags);
-                       Parent.MemberCache.AddMember (PropertyBuilder, spec);
-               }
-
-               protected abstract PropertyInfo ResolveBaseProperty ();
-
-               // TODO: rename to Resolve......
-               protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
-               {
-                       PropertyInfo base_property = ResolveBaseProperty ();
-                       if (base_property == null)
-                               return null;
-
-                       base_ret_type = base_property.PropertyType;
-                       MethodInfo get_accessor = base_property.GetGetMethod (true);
-                       MethodInfo set_accessor = base_property.GetSetMethod (true);
-                       MethodAttributes get_accessor_access = 0, set_accessor_access = 0;
-
-                       //
-                       // Check base property accessors conflict
-                       //
-                       if ((ModFlags & (Modifiers.OVERRIDE | Modifiers.NEW)) == Modifiers.OVERRIDE) {
-                               if (get_accessor == null) {
-                                       if (Get != null && !Get.IsDummy) {
-                                               Report.SymbolRelatedToPreviousError (base_property);
-                                               Report.Error (545, Location,
-                                                       "`{0}.get': cannot override because `{1}' does not have an overridable get accessor",
-                                                       GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
-                                       }
-                               } else {
-                                       get_accessor_access = get_accessor.Attributes & MethodAttributes.MemberAccessMask;
-
-                                       if (!Get.IsDummy && !CheckAccessModifiers (
-                                               ModifiersExtensions.MethodAttr (Get.ModFlags) & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
-                                               Error_CannotChangeAccessModifiers (Get.Location, get_accessor, get_accessor_access, ".get");
-                               }
-
-                               if (set_accessor == null) {
-                                       if (Set != null && !Set.IsDummy) {
-                                               Report.SymbolRelatedToPreviousError (base_property);
-                                               Report.Error (546, Location,
-                                                       "`{0}.set': cannot override because `{1}' does not have an overridable set accessor",
-                                                       GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
-                                       }
-                               } else {
-                                       set_accessor_access = set_accessor.Attributes & MethodAttributes.MemberAccessMask;
-
-                                       if (!Set.IsDummy && !CheckAccessModifiers (
-                                               ModifiersExtensions.MethodAttr (Set.ModFlags) & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
-                                               Error_CannotChangeAccessModifiers (Set.Location, set_accessor, set_accessor_access, ".set");
-                               }
-                       }
-
-                       // When one accessor does not exist and property hides base one
-                       // we need to propagate this upwards
-                       if (set_accessor == null)
-                               set_accessor = get_accessor;
-
-                       //
-                       // Get the less restrictive access
-                       //
-                       return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
+                       Parent.MemberCache.AddMember (this, Get.IsDummy ? Get.Name : GetBuilder.Name, Get.Spec);
+                       Parent.MemberCache.AddMember (this, Set.IsDummy ? Set.Name : SetBuilder.Name, Set.Spec);
+                       Parent.MemberCache.AddMember (this, PropertyBuilder.Name, spec);
                }
 
                public override void Emit ()
@@ -571,13 +616,13 @@ namespace Mono.CSharp
                                if (OptAttributes != null)
                                        OptAttributes.Emit ();
 
-                               if (TypeManager.IsDynamicType (member_type)) {
+                               if (member_type == InternalType.Dynamic) {
                                        PredefinedAttributes.Get.Dynamic.EmitAttribute (PropertyBuilder);
                                } else {
                                        var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
                                        if (trans_flags != null) {
                                                var pa = PredefinedAttributes.Get.DynamicTransform;
-                                               if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
+                                               if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
                                                        PropertyBuilder.SetCustomAttribute (
                                                                new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
                                                }
@@ -602,8 +647,7 @@ namespace Mono.CSharp
                        return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
                }
 
-               public override bool IsUsed
-               {
+               public override bool IsUsed {
                        get {
                                if (IsExplicitImpl)
                                        return true;
@@ -641,13 +685,19 @@ namespace Mono.CSharp
                        readonly Property property;
 
                        public BackingField (Property p)
-                               : base (p.Parent, p.type_name,
+                               : base (p.Parent, p.type_expr,
                                Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
                                new MemberName ("<" + p.GetFullName (p.MemberName) + ">k__BackingField", p.Location), null)
                        {
                                this.property = p;
                        }
 
+                       public string OriginalName {
+                               get {
+                                       return property.Name;
+                               }
+                       }
+
                        public override string GetSignatureForError ()
                        {
                                return property.GetSignatureForError ();
@@ -747,8 +797,7 @@ namespace Mono.CSharp
                        if (!CheckBase ())
                                return false;
 
-                       DefineBuilders (MemberKind.Property, null);
-                       TypeManager.RegisterProperty (PropertyBuilder, this);
+                       DefineBuilders (MemberKind.Property, ParametersCompiled.EmptyReadOnlyParameters);
                        return true;
                }
 
@@ -762,160 +811,8 @@ namespace Mono.CSharp
 
                        base.Emit ();
                }
-
-               protected override PropertyInfo ResolveBaseProperty ()
-               {
-                       return Parent.PartialContainer.BaseCache.FindMemberToOverride (
-                               Parent.TypeBuilder, Name, ParametersCompiled.EmptyReadOnlyParameters, null, true) as PropertyInfo;
-               }
        }
 
-       /// </summary>
-       ///  Gigantic workaround  for lameness in SRE follows :
-       ///  This class derives from EventInfo and attempts to basically
-       ///  wrap around the EventBuilder so that FindMembers can quickly
-       ///  return this in it search for members
-       /// </summary>
-       public class MyEventBuilder : EventInfo {
-               
-               //
-               // We use this to "point" to our Builder which is
-               // not really a MemberInfo
-               //
-               EventBuilder MyBuilder;
-               
-               //
-               // We "catch" and wrap these methods
-               //
-               MethodInfo raise, remove, add;
-
-               EventAttributes attributes;
-               Type declaring_type, reflected_type, event_type;
-               string name;
-
-               Event my_event;
-
-               public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
-               {
-                       MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
-
-                       // And now store the values in our own fields.
-                       
-                       declaring_type = type_builder;
-
-                       reflected_type = type_builder;
-                       
-                       attributes = event_attr;
-                       this.name = name;
-                       my_event = ev;
-                       this.event_type = event_type;
-               }
-               
-               //
-               // Methods that you have to override.  Note that you only need 
-               // to "implement" the variants that take the argument (those are
-               // the "abstract" methods, the others (GetAddMethod()) are 
-               // regular.
-               //
-               public override MethodInfo GetAddMethod (bool nonPublic)
-               {
-                       return add;
-               }
-               
-               public override MethodInfo GetRemoveMethod (bool nonPublic)
-               {
-                       return remove;
-               }
-               
-               public override MethodInfo GetRaiseMethod (bool nonPublic)
-               {
-                       return raise;
-               }
-               
-               //
-               // These methods make "MyEventInfo" look like a Builder
-               //
-               public void SetRaiseMethod (MethodBuilder raiseMethod)
-               {
-                       raise = raiseMethod;
-                       MyBuilder.SetRaiseMethod (raiseMethod);
-               }
-
-               public void SetRemoveOnMethod (MethodBuilder removeMethod)
-               {
-                       remove = removeMethod;
-                       MyBuilder.SetRemoveOnMethod (removeMethod);
-               }
-
-               public void SetAddOnMethod (MethodBuilder addMethod)
-               {
-                       add = addMethod;
-                       MyBuilder.SetAddOnMethod (addMethod);
-               }
-
-               public void SetCustomAttribute (ConstructorInfo ctor, byte[] cdata)
-               {
-                       MyBuilder.SetCustomAttribute (ctor, cdata);
-               }
-               
-               public override object [] GetCustomAttributes (bool inherit)
-               {
-                       // FIXME : There's nothing which can be seemingly done here because
-                       // we have no way of getting at the custom attribute objects of the
-                       // EventBuilder !
-                       return null;
-               }
-
-               public override object [] GetCustomAttributes (Type t, bool inherit)
-               {
-                       // FIXME : Same here !
-                       return null;
-               }
-
-               public override bool IsDefined (Type t, bool b)
-               {
-                       return true;
-               }
-
-               public override EventAttributes Attributes {
-                       get {
-                               return attributes;
-                       }
-               }
-
-               public override string Name {
-                       get {
-                               return name;
-                       }
-               }
-
-               public override Type DeclaringType {
-                       get {
-                               return declaring_type;
-                       }
-               }
-
-               public override Type ReflectedType {
-                       get {
-                               return reflected_type;
-                       }
-               }
-
-               public Type EventType {
-                       get {
-                               return event_type;
-                       }
-               }
-               
-               public void SetUsed ()
-               {
-                       if (my_event != null) {
-//                             my_event.SetAssigned ();
-                               my_event.SetIsUsed ();
-                       }
-               }
-       }
-       
        /// <summary>
        /// For case when event is declared like property (with add and remove accessors).
        /// </summary>
@@ -956,7 +853,7 @@ namespace Mono.CSharp
                }
 
 
-               static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
+               static readonly string[] attribute_targets = new string [] { "event" };
 
                public EventProperty (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags,
                                      MemberName name,
@@ -1005,7 +902,7 @@ namespace Mono.CSharp
                                        var field_info = ((EventField) method).BackingField;
                                        FieldExpr f_expr = new FieldExpr (field_info, Location);
                                        if ((method.ModFlags & Modifiers.STATIC) == 0)
-                                               f_expr.InstanceExpression = new CompilerGeneratedThis (field_info.Spec.FieldType, Location);
+                                               f_expr.InstanceExpression = new CompilerGeneratedThis (field_info.Spec.MemberType, Location);
 
                                        block = new ToplevelBlock (Compiler, ParameterInfo, Location);
                                        block.AddStatement (new StatementExpression (
@@ -1058,7 +955,7 @@ namespace Mono.CSharp
                        Remove = new RemoveDelegateMethod (this);
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Target == AttributeTargets.Field) {
                                BackingField.ApplyAttributeBuilder (a, ctor, cdata, pa);
@@ -1155,7 +1052,7 @@ namespace Mono.CSharp
                                get { return method_data.implementing != null; }
                        }
 
-                       public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+                       public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                        {
                                if (a.IsInternalMethodImplAttribute) {
                                        method.is_external_implementation = true;
@@ -1164,7 +1061,7 @@ namespace Mono.CSharp
                                base.ApplyAttributeBuilder (a, ctor, cdata, pa);
                        }
 
-                       protected override void ApplyToExtraTarget (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+                       protected override void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                        {
                                if (a.Target == AttributeTargets.Parameter) {
                                        if (param_attr == null)
@@ -1198,20 +1095,21 @@ namespace Mono.CSharp
 
                                MethodBuilder mb = method_data.MethodBuilder;
                                ParameterInfo.ApplyAttributes (mb);
-                               Spec = new MethodSpec (MemberKind.Method, this, mb, ParameterInfo, method.ModFlags);
+                               Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags);
+                               Spec.IsAccessor = true;
 
                                return mb;
                        }
 
-                       public override Type ReturnType {
+                       public override TypeSpec ReturnType {
                                get {
                                        return TypeManager.void_type;
                                }
                        }
 
-                       public override ObsoleteAttribute GetObsoleteAttribute ()
+                       public override ObsoleteAttribute GetAttributeObsolete ()
                        {
-                               return method.GetObsoleteAttribute ();
+                               return method.GetAttributeObsolete ();
                        }
 
                        public override string[] ValidAttributeTargets {
@@ -1246,7 +1144,7 @@ namespace Mono.CSharp
                        Modifiers.NEW;
 
                public AEventAccessor Add, Remove;
-               public MyEventBuilder     EventBuilder;
+               public EventBuilder     EventBuilder;
                public MethodBuilder AddBuilder, RemoveBuilder;
 
                ParametersCompiled parameters;
@@ -1258,14 +1156,14 @@ namespace Mono.CSharp
                {
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if ((a.HasSecurityAttribute)) {
                                a.Error_InvalidSecurityParent ();
                                return;
                        }
-                       
-                       EventBuilder.SetCustomAttribute (ctor, cdata);
+
+                       EventBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
                public bool AreAccessorsDuplicateImplementation (MethodCore mc)
@@ -1279,6 +1177,18 @@ namespace Mono.CSharp
                        }
                }
 
+               protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
+               {
+                       var ok = base.CheckOverrideAgainstBase (base_member);
+
+                       if (!CheckAccessModifiers (this, base_member)) {
+                               Error_CannotChangeAccessModifiers (this, base_member);
+                               ok = false;
+                       }
+
+                       return ok;
+               }
+
                public override bool Define ()
                {
                        if (!base.Define ())
@@ -1294,21 +1204,9 @@ namespace Mono.CSharp
                        if (!CheckBase ())
                                return false;
 
-                       if (TypeManager.delegate_combine_delegate_delegate == null) {
-                               TypeManager.delegate_combine_delegate_delegate = TypeManager.GetPredefinedMethod (
-                                       TypeManager.delegate_type, "Combine", Location,
-                                       TypeManager.delegate_type, TypeManager.delegate_type);
-                       }
-                       if (TypeManager.delegate_remove_delegate_delegate == null) {
-                               TypeManager.delegate_remove_delegate_delegate = TypeManager.GetPredefinedMethod (
-                                       TypeManager.delegate_type, "Remove", Location,
-                                       TypeManager.delegate_type, TypeManager.delegate_type);
-                       }
-
                        //
                        // Now define the accessors
                        //
-
                        AddBuilder = Add.Define (Parent);
                        if (AddBuilder == null)
                                return false;
@@ -1317,20 +1215,16 @@ namespace Mono.CSharp
                        if (RemoveBuilder == null)
                                return false;
 
-                       EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
+                       EventBuilder = Parent.TypeBuilder.DefineEvent (Name, EventAttributes.None, MemberType.GetMetaInfo ());
                        EventBuilder.SetAddOnMethod (AddBuilder);
                        EventBuilder.SetRemoveOnMethod (RemoveBuilder);
 
-                       var spec = new EventSpec (this, EventBuilder, ModFlags, Add.Spec, Remove.Spec) {
-                               EventType = MemberType
-                       };
+                       var spec = new EventSpec (Parent.Definition, this, MemberType, ModFlags, Add.Spec, Remove.Spec);
 
-                       TypeManager.RegisterEventField (EventBuilder, spec);
+                       Parent.MemberCache.AddMember (this, Name, spec);
+                       Parent.MemberCache.AddMember (this, AddBuilder.Name, Add.Spec);
+                       Parent.MemberCache.AddMember (this, RemoveBuilder.Name, Remove.Spec);
 
-                       Parent.MemberCache.AddMember (EventBuilder, spec);
-                       Parent.MemberCache.AddMember (AddBuilder, Add.Spec);
-                       Parent.MemberCache.AddMember (RemoveBuilder, Remove.Spec);
-                       
                        return true;
                }
 
@@ -1346,19 +1240,6 @@ namespace Mono.CSharp
                        base.Emit ();
                }
 
-               protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
-               {
-                       MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
-                               Parent.TypeBuilder, Name);
-
-                       if (mi == null)
-                               return null;
-
-                       AParametersCollection pd = TypeManager.GetParameterData (mi);
-                       base_ret_type = pd.Types [0];
-                       return mi;
-               }
-
                //
                //   Represents header string for documentation comment.
                //
@@ -1367,41 +1248,51 @@ namespace Mono.CSharp
                }
        }
 
-       public class EventSpec : MemberSpec
+       public class EventSpec : MemberSpec, IInterfaceMemberSpec
        {
-               EventInfo info;
+               MethodSpec add, remove;
 
-               public EventSpec (IMemberDefinition definition, EventInfo info, Modifiers modifiers, MethodSpec add, MethodSpec remove)
-                       : base (MemberKind.Event, definition, info.Name, modifiers)
+               public EventSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec eventType, Modifiers modifiers, MethodSpec add, MethodSpec remove)
+                       : base (MemberKind.Event, declaringType, definition, modifiers)
                {
-                       this.info = info;
                        this.AccessorAdd = add;
                        this.AccessorRemove = remove;
-
-                       // TODO MemberCache: Remove
-                       if (TypeManager.IsBeingCompiled (info))
-                               state &= ~MemberSpec.StateFlags.Obsolete_Undetected;
+                       this.MemberType = eventType;
                }
 
-               public MethodSpec AccessorAdd { get; private set; }
-               public MethodSpec AccessorRemove { get; private set; }
+               #region Properties
 
-               public override Type DeclaringType {
-                       get { return info.DeclaringType; }
+               public MethodSpec AccessorAdd { 
+                       get {
+                               return add;
+                       }
+                       set {
+                               add = value;
+                       }
                }
 
-               public Type EventType { get; set; }
-
-               public bool IsAbstract {
-                       get { return (Modifiers & Modifiers.ABSTRACT) != 0; }
+               public MethodSpec AccessorRemove {
+                       get {
+                               return remove;
+                       }
+                       set {
+                               remove = value;
+                       }
                }
 
-               public EventInfo MetaInfo {
-                       get { return info; }
+               public TypeSpec MemberType { get; private set; }
+
+               #endregion
+
+               public override MemberSpec InflateMember (TypeParameterInflator inflator)
+               {
+                       var es = (EventSpec) base.InflateMember (inflator);
+                       es.MemberType = inflator.Inflate (MemberType);
+                       return es;
                }
        }
  
-       public class Indexer : PropertyBase
+       public class Indexer : PropertyBase, IParametersMember
        {
                public class GetIndexerMethod : GetMethod
                {
@@ -1483,7 +1374,7 @@ namespace Mono.CSharp
                const Modifiers AllowedInterfaceModifiers =
                        Modifiers.NEW;
 
-               public readonly ParametersCompiled parameters;
+               readonly ParametersCompiled parameters;
 
                public Indexer (DeclSpace parent, FullNamedExpression type, MemberName name, Modifiers mod,
                                ParametersCompiled parameters, Attributes attrs,
@@ -1505,7 +1396,7 @@ namespace Mono.CSharp
                                Set = new SetIndexerMethod (this, set_block);
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.IndexerName) {
                                if (IsExplicitImpl) {
@@ -1523,7 +1414,7 @@ namespace Mono.CSharp
 
                protected override bool CheckForDuplications ()
                {
-                       return Parent.MemberCache.CheckExistingMembersOverloads (this, GetFullName (MemberName), parameters, Report);
+                       return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
                }
                
                public override bool Define ()
@@ -1537,6 +1428,10 @@ namespace Mono.CSharp
                        if (OptAttributes != null) {
                                Attribute indexer_attr = OptAttributes.Search (PredefinedAttributes.Get.IndexerName);
                                if (indexer_attr != null) {
+                                       var compiling = indexer_attr.Type.MemberDefinition as TypeContainer;
+                                       if (compiling != null)
+                                               compiling.Define ();
+
                                        string name = indexer_attr.GetIndexerAttributeValue ();
                                        if ((ModFlags & Modifiers.OVERRIDE) != 0) {
                                                Report.Error (609, indexer_attr.Location,
@@ -1549,7 +1444,7 @@ namespace Mono.CSharp
                        }
 
                        if (InterfaceType != null) {
-                               string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
+                               string base_IndexerName = InterfaceType.MemberDefinition.GetAttributeDefaultMember ();
                                if (base_IndexerName != Name)
                                        ShortName = base_IndexerName;
                        }
@@ -1566,8 +1461,7 @@ namespace Mono.CSharp
                        if (!CheckBase ())
                                return false;
 
-                       DefineBuilders (MemberKind.Indexer, parameters.GetEmitTypes ());
-                       TypeManager.RegisterIndexer (PropertyBuilder, parameters);
+                       DefineBuilders (MemberKind.Indexer, parameters);
                        return true;
                }
 
@@ -1599,10 +1493,16 @@ namespace Mono.CSharp
                        return sb.ToString ();
                }
 
-               protected override PropertyInfo ResolveBaseProperty ()
-               {
-                       return Parent.PartialContainer.BaseCache.FindMemberToOverride (
-                               Parent.TypeBuilder, Name, parameters, null, true) as PropertyInfo;
+               public AParametersCollection Parameters {
+                       get {
+                               return parameters;
+                       }
+               }
+
+               public ParametersCompiled ParameterInfo {
+                       get {
+                               return parameters;
+                       }
                }
 
                protected override bool VerifyClsCompliance ()
@@ -1614,4 +1514,26 @@ namespace Mono.CSharp
                        return true;
                }
        }
+
+       public class IndexerSpec : PropertySpec, IParametersMember
+       {
+               AParametersCollection parameters;
+
+               public IndexerSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, AParametersCollection parameters, PropertyInfo info, Modifiers modifiers)
+                       : base (MemberKind.Indexer, declaringType, definition, memberType, info, modifiers)
+               {
+                       this.parameters = parameters;
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       return DeclaringType.GetSignatureForError () + ".this" + parameters.GetSignatureForError ("[", "]", parameters.Count);
+               }
+
+               public AParametersCollection Parameters {
+                       get {
+                               return parameters;
+                       }
+               }
+       }
 }
index 77058a17208e6acf67e085ff7297d1028f83790c..3ca7fd681ea6c8f72c30415f38fc3327156da84d 100644 (file)
@@ -179,35 +179,17 @@ namespace Mono.CSharp {
                        SymbolRelatedToPreviousError (loc.ToString (), symbol);
                }
 
-               public void SymbolRelatedToPreviousError (MemberInfo mi)
+               public void SymbolRelatedToPreviousError (MemberSpec ms)
                {
                        if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport)
                                return;
 
-                       Type dt = TypeManager.DropGenericTypeArguments (mi.DeclaringType);
-                       if (TypeManager.IsDelegateType (dt)) {
-                               SymbolRelatedToPreviousError (dt);
-                               return;
-                       }                       
-                       
-                       DeclSpace temp_ds = TypeManager.LookupDeclSpace (dt);
-                       if (temp_ds == null) {
-                               SymbolRelatedToPreviousError (dt.Assembly.Location, TypeManager.GetFullNameSignature (mi));
+                       var mc = ms.MemberDefinition as MemberCore;
+                       if (mc != null) {
+                               SymbolRelatedToPreviousError (mc);
                        } else {
-                               MethodBase mb = mi as MethodBase;
-                               if (mb != null) {
-                                       mb = TypeManager.DropGenericMethodArguments (mb);
-                                       IMethodData md = TypeManager.GetMethod (mb);
-                                       if (md != null)
-                                               SymbolRelatedToPreviousError (md.Location, md.GetSignatureForError ());
-
-                                       return;
-                               }
-
-                               // FIXME: Completely wrong, it has to use FindMembers
-                               MemberCore mc = temp_ds.GetDefinition (mi.Name);
-                               if (mc != null)
-                                       SymbolRelatedToPreviousError (mc);
+                               var im = ms.MemberDefinition as ImportedMemberDefinition;
+                               SymbolRelatedToPreviousError (im.Assembly.Location, "");
                        }
                }
 
@@ -216,31 +198,6 @@ namespace Mono.CSharp {
                        SymbolRelatedToPreviousError (mc.Location, mc.GetSignatureForError ());
                }
 
-               public void SymbolRelatedToPreviousError (Type type)
-               {
-                       if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport)
-                               return;
-
-                       type = TypeManager.DropGenericTypeArguments (type);
-
-                       if (TypeManager.IsGenericParameter (type)) {
-                               TypeParameter tp = TypeManager.LookupTypeParameter (type);
-                               if (tp != null) {
-                                       SymbolRelatedToPreviousError (tp.Location, "");
-                                       return;
-                               }
-                       }
-
-                       if (type is TypeBuilder) {
-                               DeclSpace temp_ds = TypeManager.LookupDeclSpace (type);
-                               SymbolRelatedToPreviousError (temp_ds.Location, TypeManager.CSharpName (type));
-                       } else if (TypeManager.HasElementType (type)) {
-                               SymbolRelatedToPreviousError (TypeManager.GetElementType (type));
-                       } else {
-                               SymbolRelatedToPreviousError (type.Assembly.Location, TypeManager.CSharpName (type));
-                       }
-               }
-
                void SymbolRelatedToPreviousError (string loc, string symbol)
                {
                        string msg = String.Format ("{0} (Location of the symbol related to previous ", loc);
@@ -404,7 +361,7 @@ namespace Mono.CSharp {
                        Error (code, loc, String.Format (format, arg1, arg2));
                }
 
-               public void Error (int code, Location loc, string format, params object[] args)
+               public void Error (int code, Location loc, string format, params string[] args)
                {
                        Error (code, loc, String.Format (format, args));
                }
@@ -956,8 +913,8 @@ namespace Mono.CSharp {
                                        if (!first)
                                                sb.Append (", ");
                                        first = false;
-                                       
-                                       sb.Append (TypeManager.CSharpName (pi.ParameterType));
+
+                                       sb.Append (pi.ParameterType.FullName);
                                }
                                sb.Append (")\n");
                        }
index 5ef66ceeaa0dc4fee365f8e24388e9515fcad017..4c6335c0b79ab42689d99ed9f78a9572a51b8c8a 100644 (file)
@@ -117,17 +117,6 @@ namespace Mono.CSharp {
                //
                static List<string> AllDefines;
                
-               //
-               // This keeps track of the order in which classes were defined
-               // so that we can poulate them in that order.
-               //
-               // Order is important, because we need to be able to tell, by
-               // examining the list of methods of the base class, which ones are virtual
-               // or abstract as well as the parent names (to implement new, 
-               // override).
-               //
-               static List<TypeContainer> type_container_resolve_order;
-
                //
                // Holds a reference to the Private Implementation Details
                // class.
@@ -136,6 +125,8 @@ namespace Mono.CSharp {
                
                static TypeBuilder impl_details_class;
 
+               public static List<Enum> hack_corlib_enums = new List<Enum> ();
+
                //
                // Constructor
                //
@@ -151,10 +142,12 @@ namespace Mono.CSharp {
                
                public static void Reset (bool full)
                {
-                       if (full)
-                               root = null;
+                       impl_details_class = null;
+                       helper_classes = null;
+
+                       if (!full)
+                               return;
                        
-                       type_container_resolve_order = new List<TypeContainer> ();
                        EntryPoint = null;
                        Checked = false;
                        Unsafe = false;
@@ -201,11 +194,6 @@ namespace Mono.CSharp {
                        set { root = value; }
                }
 
-               public static void RegisterOrder (TypeContainer tc)
-               {
-                       type_container_resolve_order.Add (tc);
-               }
-               
                // <remarks>
                //   This function is used to resolve the hierarchy tree.
                //   It processes interfaces, structs and classes in that order.
@@ -228,10 +216,44 @@ namespace Mono.CSharp {
 
                        foreach (TypeContainer tc in root.Types)
                                tc.DefineType ();
+               }
+
+               static void HackCorlib ()
+               {
+                       if (StdLib)
+                               return;
+
+                       //
+                       // HACK: When building corlib mcs uses loaded mscorlib which
+                       // has different predefined types and this method sets mscorlib types
+                       // to be same to avoid type check errors in CreateType.
+                       //
+                       var type = typeof (Type);
+                       var system_4_type_arg = new[] { type, type, type, type };
+
+                       MethodInfo set_corlib_type_builders =
+                               typeof (System.Reflection.Emit.AssemblyBuilder).GetMethod (
+                               "SetCorlibTypeBuilders", BindingFlags.NonPublic | BindingFlags.Instance, null,
+                               system_4_type_arg, null);
+
+                       if (set_corlib_type_builders == null) {
+                               root.Compiler.Report.Warning (-26, 3, "The compilation may fail due to missing `{0}.SetCorlibTypeBuilders(...)' method",
+                                       typeof (System.Reflection.Emit.AssemblyBuilder).FullName);
+                               return;
+                       }
 
-                       if (root.Delegates != null)
-                               foreach (Delegate d in root.Delegates) 
-                                       d.DefineType ();
+                       object[] args = new object[4];
+                       args[0] = TypeManager.object_type.GetMetaInfo ();
+                       args[1] = TypeManager.value_type.GetMetaInfo ();
+                       args[2] = TypeManager.enum_type.GetMetaInfo ();
+                       args[3] = TypeManager.void_type.GetMetaInfo ();
+                       set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
+
+                       // Another Mono corlib HACK
+                       // mono_class_layout_fields requires to have enums created
+                       // before creating a class which used the enum for any of its fields
+                       foreach (var e in hack_corlib_enums)
+                               e.CloseType ();
                }
 
                // <summary>
@@ -246,26 +268,11 @@ namespace Mono.CSharp {
                // </remarks>
                static public void CloseTypes ()
                {
-                       //
-                       // We do this in two passes, first we close the structs,
-                       // then the classes, because it seems the code needs it this
-                       // way.  If this is really what is going on, we should probably
-                       // make sure that we define the structs in order as well.
-                       //
-                       foreach (TypeContainer tc in type_container_resolve_order){
-                               if (tc.Kind == MemberKind.Struct && tc.Parent == root){
-                                       tc.CloseType ();
-                               }
-                       }
+                       HackCorlib ();
 
-                       foreach (TypeContainer tc in type_container_resolve_order){
-                               if (!(tc.Kind == MemberKind.Struct && tc.Parent == root))
-                                       tc.CloseType ();                                        
+                       foreach (TypeContainer tc in root.Types){
+                               tc.CloseType ();
                        }
-                       
-                       if (root.Delegates != null)
-                               foreach (Delegate d in root.Delegates)
-                                       d.CloseType ();
 
                        if (root.CompilerGeneratedClasses != null)
                                foreach (CompilerGeneratedClass c in root.CompilerGeneratedClasses)
@@ -281,10 +288,7 @@ namespace Mono.CSharp {
                                }
                        }
                        
-                       type_container_resolve_order = null;
                        helper_classes = null;
-                       //root = null;
-                       TypeManager.CleanUp ();
                }
 
                /// <summary>
@@ -299,28 +303,6 @@ namespace Mono.CSharp {
                        helper_classes.Add (helper_class);
                }
                
-               static public DeclSpace PopulateCoreType (TypeContainer root, string name)
-               {
-                       DeclSpace ds = (DeclSpace) root.GetDefinition (name);
-                       // Core type was imported
-                       if (ds == null)
-                               return null;
-
-                       ds.Define ();
-                       return ds;
-               }
-               
-               static public void BootCorlib_PopulateCoreTypes ()
-               {
-                       // Clear -nostdlib flag when object type is imported
-                       if (PopulateCoreType (root, "System.Object") == null)
-                               RootContext.StdLib = true;
-
-                       PopulateCoreType (root, "System.ValueType");
-                       PopulateCoreType (root, "System.Attribute");
-                       PopulateCoreType (root, "System.Runtime.CompilerServices.IndexerNameAttribute");
-               }
-               
                // <summary>
                //   Populates the structs and classes with fields and methods
                // </summary>
@@ -329,52 +311,31 @@ namespace Mono.CSharp {
                // have been defined through `ResolveTree' 
                static public void PopulateTypes ()
                {
-
-                       if (type_container_resolve_order != null){
-                               foreach (TypeContainer tc in type_container_resolve_order)
-                                       tc.ResolveType ();
-                               foreach (TypeContainer tc in type_container_resolve_order) {
-                                       try {
-                                               tc.Define ();
-                                       } catch (Exception e) {
-                                               throw new InternalErrorException (tc, e);
-                                       }
+                       foreach (TypeContainer tc in ToplevelTypes.Types)
+                               tc.ResolveTypeParameters ();
+
+                       foreach (TypeContainer tc in ToplevelTypes.Types) {
+                               try {
+                                       tc.Define ();
+                               } catch (Exception e) {
+                                       throw new InternalErrorException (tc, e);
                                }
                        }
-
-                       var delegates = root.Delegates;
-                       if (delegates != null){
-                               foreach (Delegate d in delegates)
-                                       d.Define ();
-                       }
-
-                       //
-                       // Check for cycles in the struct layout
-                       //
-                       if (type_container_resolve_order != null){
-                               var seen = new Dictionary<TypeContainer, object> ();
-                               foreach (TypeContainer tc in type_container_resolve_order)
-                                       TypeManager.CheckStructCycles (tc, seen);
-                       }
                }
 
                static public void EmitCode ()
                {
-                       if (type_container_resolve_order != null) {
-                               foreach (TypeContainer tc in type_container_resolve_order)
-                                       tc.EmitType ();
+                       foreach (var tc in ToplevelTypes.Types)
+                               tc.DefineConstants ();
 
-                               if (ToplevelTypes.Compiler.Report.Errors > 0)
-                                       return;
+                       foreach (TypeContainer tc in ToplevelTypes.Types)
+                               tc.EmitType ();
 
-                               foreach (TypeContainer tc in type_container_resolve_order)
-                                       tc.VerifyMembers ();
-                       }
-                       
-                       if (root.Delegates != null) {
-                               foreach (Delegate d in root.Delegates)
-                                       d.Emit ();
-                       }                       
+                       if (ToplevelTypes.Compiler.Report.Errors > 0)
+                               return;
+
+                       foreach (TypeContainer tc in ToplevelTypes.Types)
+                               tc.VerifyMembers ();
 
                        if (root.CompilerGeneratedClasses != null)
                                foreach (CompilerGeneratedClass c in root.CompilerGeneratedClasses)
@@ -417,7 +378,7 @@ namespace Mono.CSharp {
                                impl_details_class = ToplevelTypes.Builder.DefineType (
                                        "<PrivateImplementationDetails>",
                                         TypeAttributes.NotPublic,
-                                        TypeManager.object_type);
+                                        TypeManager.object_type.GetMetaInfo ());
                                 
                                RegisterCompilerGeneratedType (impl_details_class);
                        }
index 032c09ec6628468b5d246d35558bfdc49358ac3e..0144f0130300ae893ee1a083325b921b5d1d5350 100644 (file)
@@ -34,7 +34,7 @@ namespace Mono.CSharp
                        this.assembly = assembly;
                }
 
-               public Assembly Assembly {
+               public override Assembly Assembly {
                        get { return assembly; }
                }
 
@@ -111,7 +111,7 @@ namespace Mono.CSharp
                        return AddPartial (nextPart, nextPart.Name);
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, ConstructorInfo ctor, byte[] cdata, PredefinedAttributes pa)
+               public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.CLSCompliant) {
                                if (CodeGen.Assembly.ClsCompliantAttribute == null) {
@@ -123,7 +123,7 @@ namespace Mono.CSharp
                                }
                        }
 
-                       builder.SetCustomAttribute (ctor, cdata);
+                       builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
                public ModuleBuilder Builder {
@@ -147,11 +147,11 @@ namespace Mono.CSharp
                                OptAttributes.Emit ();
 
                        if (is_unsafe) {
-                               Type t = TypeManager.CoreLookupType (context, "System.Security", "UnverifiableCodeAttribute", MemberKind.Class, true);
+                               TypeSpec t = TypeManager.CoreLookupType (context, "System.Security", "UnverifiableCodeAttribute", MemberKind.Class, true);
                                if (t != null) {
-                                       ConstructorInfo unverifiable_code_ctor = TypeManager.GetPredefinedConstructor (t, Location.Null, Type.EmptyTypes);
+                                       var unverifiable_code_ctor = TypeManager.GetPredefinedConstructor (t, Location.Null, TypeSpec.EmptyTypes);
                                        if (unverifiable_code_ctor != null)
-                                               builder.SetCustomAttribute (new CustomAttributeBuilder (unverifiable_code_ctor, new object [0]));
+                                               builder.SetCustomAttribute (new CustomAttributeBuilder ((ConstructorInfo) unverifiable_code_ctor.GetMetaInfo (), new object[0]));
                                }
                        }
                }
@@ -176,11 +176,6 @@ namespace Mono.CSharp
                        return null;
                }
 
-               public override bool GetClsCompliantAttributeValue ()
-               {
-                       return CodeGen.Assembly.IsClsCompliant;
-               }
-
                public bool HasDefaultCharSet {
                        get {
                                return has_default_charset;
@@ -194,14 +189,14 @@ namespace Mono.CSharp
 
                public override bool IsClsComplianceRequired ()
                {
-                       return true;
+                       return CodeGen.Assembly.IsClsCompliant;
                }
 
-               protected override bool AddMemberType (DeclSpace ds)
+               protected override bool AddMemberType (TypeContainer ds)
                {
                        if (!AddToContainer (ds, ds.Name))
                                return false;
-                       ds.NamespaceEntry.NS.AddDeclSpace (ds.Basename, ds);
+                       ds.NamespaceEntry.NS.AddType (ds.Definition);
                        return true;
                }
 
@@ -259,9 +254,9 @@ namespace Mono.CSharp
                }
        }
 
-       class RootDeclSpace : DeclSpace {
+       class RootDeclSpace : TypeContainer {
                public RootDeclSpace (NamespaceEntry ns)
-                       : base (ns, null, MemberName.Null, null)
+                       : base (ns, null, MemberName.Null, null, 0)
                {
                        PartialContainer = RootContext.ToplevelTypes;
                }
@@ -280,31 +275,22 @@ namespace Mono.CSharp
                        get { throw new InternalErrorException ("should not be called"); }
                }
 
-               public override bool Define ()
-               {
-                       throw new InternalErrorException ("should not be called");
-               }
+               //public override bool Define ()
+               //{
+               //    throw new InternalErrorException ("should not be called");
+               //}
 
                public override TypeBuilder DefineType ()
                {
                        throw new InternalErrorException ("should not be called");
                }
 
-               public override MemberCache MemberCache {
-                       get { return PartialContainer.MemberCache; }
-               }
-
                public override ModuleContainer Module {
                        get {
                                return PartialContainer.Module;
                        }
                }
 
-               public override bool GetClsCompliantAttributeValue ()
-               {
-                       return PartialContainer.GetClsCompliantAttributeValue ();
-               }
-
                public override bool IsClsComplianceRequired ()
                {
                        return PartialContainer.IsClsComplianceRequired ();
index 12bd6b6977dee2cb219ee6bb34f6c54440036f05..38a7529f89242fb61d8e95671044b6ca6bc12fc9 100644 (file)
@@ -92,8 +92,6 @@ namespace Mono.CSharp {
 
                        return Clone (clonectx);
                }
-
-               public abstract void MutateHoistedGenericType (AnonymousMethodStorey storey);
        }
 
        public sealed class EmptyStatement : Statement
@@ -122,10 +120,6 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ();
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement target)
                {
                        // nothing needed.
@@ -155,14 +149,6 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       TrueStatement.MutateHoistedGenericType (storey);
-                       if (FalseStatement != null)
-                               FalseStatement.MutateHoistedGenericType (storey);
-               }
-
                public override bool Resolve (BlockContext ec)
                {
                        bool ok = true;
@@ -221,8 +207,7 @@ namespace Mono.CSharp {
                
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label false_target = ig.DefineLabel ();
+                       Label false_target = ec.DefineLabel ();
                        Label end;
 
                        //
@@ -248,19 +233,19 @@ namespace Mono.CSharp {
                        if (FalseStatement != null){
                                bool branch_emitted = false;
                                
-                               end = ig.DefineLabel ();
+                               end = ec.DefineLabel ();
                                if (!is_true_ret){
-                                       ig.Emit (OpCodes.Br, end);
+                                       ec.Emit (OpCodes.Br, end);
                                        branch_emitted = true;
                                }
 
-                               ig.MarkLabel (false_target);
+                               ec.MarkLabel (false_target);
                                FalseStatement.Emit (ec);
 
                                if (branch_emitted)
-                                       ig.MarkLabel (end);
+                                       ec.MarkLabel (end);
                        } else {
-                               ig.MarkLabel (false_target);
+                               ec.MarkLabel (false_target);
                        }
                }
 
@@ -318,17 +303,16 @@ namespace Mono.CSharp {
                
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label loop = ig.DefineLabel ();
+                       Label loop = ec.DefineLabel ();
                        Label old_begin = ec.LoopBegin;
                        Label old_end = ec.LoopEnd;
                        
-                       ec.LoopBegin = ig.DefineLabel ();
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopBegin = ec.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
                                
-                       ig.MarkLabel (loop);
+                       ec.MarkLabel (loop);
                        EmbeddedStatement.Emit (ec);
-                       ig.MarkLabel (ec.LoopBegin);
+                       ec.MarkLabel (ec.LoopBegin);
 
                        //
                        // Dead code elimination
@@ -338,22 +322,16 @@ namespace Mono.CSharp {
 
                                expr.EmitSideEffect (ec);
                                if (res)
-                                       ec.ig.Emit (OpCodes.Br, loop); 
+                                       ec.Emit (OpCodes.Br, loop); 
                        } else
                                expr.EmitBranchable (ec, loop, true);
                        
-                       ig.MarkLabel (ec.LoopEnd);
+                       ec.MarkLabel (ec.LoopEnd);
 
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       EmbeddedStatement.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Do target = (Do) t;
@@ -422,42 +400,41 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       ILGenerator ig = ec.ig;
                        Label old_begin = ec.LoopBegin;
                        Label old_end = ec.LoopEnd;
                        
-                       ec.LoopBegin = ig.DefineLabel ();
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopBegin = ec.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
 
                        //
                        // Inform whether we are infinite or not
                        //
                        if (expr is Constant){
                                // expr is 'true', since the 'empty' case above handles the 'false' case
-                               ig.MarkLabel (ec.LoopBegin);
+                               ec.MarkLabel (ec.LoopBegin);
                                expr.EmitSideEffect (ec);
                                Statement.Emit (ec);
-                               ig.Emit (OpCodes.Br, ec.LoopBegin);
+                               ec.Emit (OpCodes.Br, ec.LoopBegin);
                                        
                                //
                                // Inform that we are infinite (ie, `we return'), only
                                // if we do not `break' inside the code.
                                //
-                               ig.MarkLabel (ec.LoopEnd);
+                               ec.MarkLabel (ec.LoopEnd);
                        } else {
-                               Label while_loop = ig.DefineLabel ();
+                               Label while_loop = ec.DefineLabel ();
 
-                               ig.Emit (OpCodes.Br, ec.LoopBegin);
-                               ig.MarkLabel (while_loop);
+                               ec.Emit (OpCodes.Br, ec.LoopBegin);
+                               ec.MarkLabel (while_loop);
 
                                Statement.Emit (ec);
                        
-                               ig.MarkLabel (ec.LoopBegin);
+                               ec.MarkLabel (ec.LoopBegin);
                                ec.Mark (loc);
 
                                expr.EmitBranchable (ec, while_loop, true);
                                
-                               ig.MarkLabel (ec.LoopEnd);
+                               ec.MarkLabel (ec.LoopEnd);
                        }       
 
                        ec.LoopBegin = old_begin;
@@ -476,12 +453,6 @@ namespace Mono.CSharp {
                        target.expr = expr.Clone (clonectx);
                        target.Statement = Statement.Clone (clonectx);
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       Statement.MutateHoistedGenericType (storey);
-               }
        }
 
        public class For : Statement {
@@ -573,23 +544,22 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       ILGenerator ig = ec.ig;
                        Label old_begin = ec.LoopBegin;
                        Label old_end = ec.LoopEnd;
-                       Label loop = ig.DefineLabel ();
-                       Label test = ig.DefineLabel ();
+                       Label loop = ec.DefineLabel ();
+                       Label test = ec.DefineLabel ();
 
-                       ec.LoopBegin = ig.DefineLabel ();
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopBegin = ec.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
 
-                       ig.Emit (OpCodes.Br, test);
-                       ig.MarkLabel (loop);
+                       ec.Emit (OpCodes.Br, test);
+                       ec.MarkLabel (loop);
                        Statement.Emit (ec);
 
-                       ig.MarkLabel (ec.LoopBegin);
+                       ec.MarkLabel (ec.LoopBegin);
                        Increment.Emit (ec);
 
-                       ig.MarkLabel (test);
+                       ec.MarkLabel (test);
                        //
                        // If test is null, there is no test, and we are just
                        // an infinite loop
@@ -602,31 +572,19 @@ namespace Mono.CSharp {
                                //
                                if (Test is Constant) {
                                        Test.EmitSideEffect (ec);
-                                       ig.Emit (OpCodes.Br, loop);
+                                       ec.Emit (OpCodes.Br, loop);
                                } else {
                                        Test.EmitBranchable (ec, loop, true);
                                }
                                
                        } else
-                               ig.Emit (OpCodes.Br, loop);
-                       ig.MarkLabel (ec.LoopEnd);
+                               ec.Emit (OpCodes.Br, loop);
+                       ec.MarkLabel (ec.LoopEnd);
 
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (InitStatement != null)
-                               InitStatement.MutateHoistedGenericType (storey);
-                       if (Test != null)
-                               Test.MutateHoistedGenericType (storey);
-                       if (Increment != null)
-                               Increment.MutateHoistedGenericType (storey);
-
-                       Statement.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        For target = (For) t;
@@ -661,11 +619,6 @@ namespace Mono.CSharp {
                        expr.EmitStatement (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-               }
-
                public override string ToString ()
                {
                        return "StatementExpression (" + expr + ")";
@@ -768,19 +721,13 @@ namespace Mono.CSharp {
                                Expr.Emit (ec);
 
                                if (unwind_protect)
-                                       ec.ig.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
+                                       ec.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
                        }
 
                        if (unwind_protect)
-                               ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);
+                               ec.Emit (OpCodes.Leave, ec.ReturnLabel);
                        else
-                               ec.ig.Emit (OpCodes.Ret);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (Expr != null)
-                               Expr.MutateHoistedGenericType (storey);
+                               ec.Emit (OpCodes.Ret);
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -830,11 +777,7 @@ namespace Mono.CSharp {
                        if (label == null)
                                throw new InternalErrorException ("goto emitted before target resolved");
                        Label l = label.LabelTarget (ec);
-                       ec.ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l);
                }
        }
 
@@ -843,7 +786,6 @@ namespace Mono.CSharp {
                bool defined;
                bool referenced;
                Label label;
-               ILGenerator ig;
 
                FlowBranching.UsageVector vectors;
                
@@ -857,10 +799,9 @@ namespace Mono.CSharp {
                {
                        if (defined)
                                return label;
-                       ig = ec.ig;
-                       label = ec.ig.DefineLabel ();
-                       defined = true;
 
+                       label = ec.DefineLabel ();
+                       defined = true;
                        return label;
                }
 
@@ -901,14 +842,8 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       if (ig != null && ig != ec.ig)
-                               throw new InternalErrorException ("cannot happen");
                        LabelTarget (ec);
-                       ec.ig.MarkLabel (label);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
+                       ec.MarkLabel (label);
                }
 
                public void AddReference ()
@@ -952,11 +887,7 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
+                       ec.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
                }
        }
 
@@ -992,7 +923,7 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       Type type = ec.Switch.SwitchType;
+                       TypeSpec type = ec.Switch.SwitchType;
                        Constant res = c.TryReduce (ec, type, c.Location);
                        if (res == null) {
                                c.Error_ValueCannotBeConverted (ec, loc, type, true);
@@ -1019,12 +950,7 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Br, sl.GetILLabelCode (ec));
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
+                       ec.Emit (OpCodes.Br, sl.GetILLabelCode (ec));
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -1068,20 +994,14 @@ namespace Mono.CSharp {
                protected override void DoEmit (EmitContext ec)
                {
                        if (expr == null)
-                               ec.ig.Emit (OpCodes.Rethrow);
+                               ec.Emit (OpCodes.Rethrow);
                        else {
                                expr.Emit (ec);
 
-                               ec.ig.Emit (OpCodes.Throw);
+                               ec.Emit (OpCodes.Throw);
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (expr != null)
-                               expr.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Throw target = (Throw) t;
@@ -1109,13 +1029,9 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ec.ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopEnd);
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopEnd);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-               }
-               
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        // nothing needed
@@ -1140,11 +1056,7 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ec.ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopBegin);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopBegin);
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -1171,7 +1083,7 @@ namespace Mono.CSharp {
        public class LocalInfo : IKnownVariable, ILocalVariable {
                public readonly FullNamedExpression Type;
 
-               public Type VariableType;
+               public TypeSpec VariableType;
                public readonly string Name;
                public readonly Location Location;
                public readonly Block Block;
@@ -1208,9 +1120,9 @@ namespace Mono.CSharp {
                        Location = l;
                }
 
-               public LocalInfo (DeclSpace ds, Block block, Location l)
+               public LocalInfo (TypeContainer ds, Block block, Location l)
                {
-                       VariableType = ds.IsGeneric ? ds.CurrentType : ds.TypeBuilder;
+                       VariableType = ds.IsGeneric ? ds.CurrentType : ds.Definition;
                        Block = block;
                        Location = l;
                }
@@ -1221,23 +1133,23 @@ namespace Mono.CSharp {
                                return;
 
                        if (builder == null) {
-                               builder = ec.ig.DeclareLocal (TypeManager.TypeToReflectionType (VariableType), Pinned);
+                               builder = ec.DeclareLocal (VariableType, Pinned);
                        }
                }
 
                public void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldloc, builder);
+                       ec.Emit (OpCodes.Ldloc, builder);
                }
 
                public void EmitAssign (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Stloc, builder);
+                       ec.Emit (OpCodes.Stloc, builder);
                }
 
                public void EmitAddressOf (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldloca, builder);
+                       ec.Emit (OpCodes.Ldloca, builder);
                }
 
                public void EmitSymbolInfo (EmitContext ec)
@@ -1288,10 +1200,7 @@ namespace Mono.CSharp {
                                
                        VariableType = texpr.Type;
 
-                       if (TypeManager.IsGenericParameter (VariableType))
-                               return true;
-
-                       if (VariableType.IsAbstract && VariableType.IsSealed) {
+                       if (VariableType.IsStatic) {
                                FieldBase.Error_VariableOfStaticClass (Location, Name, VariableType, ec.Report);
                                return false;
                        }
@@ -1947,7 +1856,7 @@ namespace Mono.CSharp {
                        foreach (var de in variables) {
                                string name = de.Key;
                                LocalInfo vi = de.Value;
-                               Type variable_type = vi.VariableType;
+                               TypeSpec variable_type = vi.VariableType;
 
                                if (variable_type == null) {
                                        if (vi.Type is VarExpr)
@@ -1965,7 +1874,7 @@ namespace Mono.CSharp {
                                // which in turn causes the 'must be constant' error to be triggered.
                                constants.Remove (name);
 
-                               if (!Const.IsConstantTypeValid (variable_type)) {
+                               if (!variable_type.IsConstantCompatible) {
                                        Const.Error_InvalidConstantType (variable_type, loc, ec.Report);
                                        continue;
                                }
@@ -2242,14 +2151,14 @@ namespace Mono.CSharp {
 
                protected void EmitScopeInitializers (EmitContext ec)
                {
-                       SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
+                       SymbolWriter.OpenCompilerGeneratedBlock (ec);
 
                        using (ec.With (EmitContext.Options.OmitDebugInfo, true)) {
                                foreach (Statement s in scope_initializers)
                                        s.Emit (ec);
                        }
 
-                       SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
+                       SymbolWriter.CloseCompilerGeneratedBlock (ec);
                }
 
                protected virtual void EmitSymbolInfo (EmitContext ec)
@@ -2261,33 +2170,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       MutateVariables (storey);
-
-                       if (scope_initializers != null) {
-                               foreach (Statement s in scope_initializers)
-                                       s.MutateHoistedGenericType (storey);
-                       }
-
-                       foreach (Statement s in statements)
-                               s.MutateHoistedGenericType (storey);
-               }
-
-               void MutateVariables (AnonymousMethodStorey storey)
-               {
-                       if (variables != null) {
-                               foreach (LocalInfo vi in variables.Values) {
-                                       vi.VariableType = storey.MutateType (vi.VariableType);
-                               }
-                       }
-
-                       if (temporary_variables != null) {
-                               foreach (LocalInfo vi in temporary_variables)
-                                       vi.VariableType = storey.MutateType (vi.VariableType);
-                       }
-               }
-
                public override string ToString ()
                {
                        return String.Format ("{0} ({1}:{2})", GetType (),ID, StartLocation);
@@ -2392,7 +2274,7 @@ namespace Mono.CSharp {
                                //
                                // Creates anonymous method storey for this block
                                //
-                               am_storey = new AnonymousMethodStorey (this, ec.CurrentTypeDefinition, mc, gm, "AnonStorey");
+                               am_storey = new AnonymousMethodStorey (this, ec.CurrentMemberDefinition.Parent.PartialContainer, mc, gm, "AnonStorey");
                        }
 
                        return am_storey;
@@ -2432,14 +2314,21 @@ namespace Mono.CSharp {
                                                while (parent.am_storey == null || parent.am_storey.Parent is AnonymousMethodStorey)
                                                        parent = parent.Parent.Explicit;
 
-                                               am_storey.AddParentStoreyReference (parent.am_storey);
+                                               am_storey.AddParentStoreyReference (ec, parent.am_storey);
                                        }
 
-                                       am_storey.ChangeParentStorey (ec.CurrentAnonymousMethod.Storey);
+                                       am_storey.SetNestedStoryParent (ec.CurrentAnonymousMethod.Storey);
+
+                                       // TODO MemberCache: Review
+                                       am_storey.Mutator = ec.CurrentAnonymousMethod.Storey.Mutator;
                                }
 
+                               am_storey.CreateType ();
+                               if (am_storey.Mutator == null && ec.CurrentTypeParameters != null)
+                                       am_storey.Mutator = new TypeParameterMutator (ec.CurrentTypeParameters, am_storey.CurrentTypeParameters);
+
                                am_storey.DefineType ();
-                               am_storey.ResolveType ();
+                               am_storey.ResolveTypeParameters ();
                                am_storey.Define ();
                                am_storey.Parent.PartialContainer.AddCompilerGeneratedClass (am_storey);
 
@@ -2448,7 +2337,7 @@ namespace Mono.CSharp {
                                        foreach (ExplicitBlock ref_block in ref_blocks) {
                                                for (ExplicitBlock b = ref_block.Explicit; b != this; b = b.Parent.Explicit) {
                                                        if (b.am_storey != null) {
-                                                               b.am_storey.AddParentStoreyReference (am_storey);
+                                                               b.am_storey.AddParentStoreyReference (ec, am_storey);
 
                                                                // Stop propagation inside same top block
                                                                if (b.Toplevel == Toplevel)
@@ -2509,7 +2398,7 @@ namespace Mono.CSharp {
                        get { return Block.Parameters [Index]; }
                }
 
-               public Type ParameterType {
+               public TypeSpec ParameterType {
                        get { return Block.Parameters.Types [Index]; }
                }
 
@@ -2573,13 +2462,6 @@ namespace Mono.CSharp {
                                block.EmitScopeInitializers (ec);
                                child.Emit (ec);
                        }
-
-                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                       {
-                               type = storey.MutateType (type);
-                               child.MutateHoistedGenericType (storey);
-                               block.MutateHoistedGenericType (storey);
-                       }
                }
 
                GenericMethod generic;
@@ -2791,7 +2673,7 @@ namespace Mono.CSharp {
                //   analysis code to ensure that it's been fully initialized before control
                //   leaves the constructor.
                // </summary>
-               public LocalInfo AddThisVariable (DeclSpace ds, Location l)
+               public LocalInfo AddThisVariable (TypeContainer ds, Location l)
                {
                        if (this_variable == null) {
                                this_variable = new LocalInfo (ds, this, l);
@@ -2933,18 +2815,18 @@ namespace Mono.CSharp {
                        EmitMeta (ec);
 
                        if (ec.HasReturnLabel)
-                               ec.ReturnLabel = ec.ig.DefineLabel ();
+                               ec.ReturnLabel = ec.DefineLabel ();
 
                        base.Emit (ec);
 
                        ec.Mark (EndLocation);
 
                        if (ec.HasReturnLabel)
-                               ec.ig.MarkLabel (ec.ReturnLabel);
+                               ec.MarkLabel (ec.ReturnLabel);
 
                        if (ec.return_value != null) {
-                               ec.ig.Emit (OpCodes.Ldloc, ec.return_value);
-                               ec.ig.Emit (OpCodes.Ret);
+                               ec.Emit (OpCodes.Ldloc, ec.return_value);
+                               ec.Emit (OpCodes.Ret);
                        } else {
                                //
                                // If `HasReturnLabel' is set, then we already emitted a
@@ -2961,8 +2843,8 @@ namespace Mono.CSharp {
 
                                if (ec.HasReturnLabel || !unreachable) {
                                        if (ec.ReturnType != TypeManager.void_type)
-                                               ec.ig.Emit (OpCodes.Ldloc, ec.TemporaryReturn ());
-                                       ec.ig.Emit (OpCodes.Ret);
+                                               ec.Emit (OpCodes.Ldloc, ec.TemporaryReturn ());
+                                       ec.Emit (OpCodes.Ret);
                                }
                        }
 
@@ -2979,8 +2861,6 @@ namespace Mono.CSharp {
 
                public override void EmitMeta (EmitContext ec)
                {
-                       parameters.ResolveVariable ();
-
                        // Avoid declaring an IL variable for this_variable since it is not accessed
                        // from the generated IL
                        if (this_variable != null)
@@ -3038,7 +2918,7 @@ namespace Mono.CSharp {
                public Label GetILLabel (EmitContext ec)
                {
                        if (!il_label_set){
-                               il_label = ec.ig.DefineLabel ();
+                               il_label = ec.DefineLabel ();
                                il_label_set = true;
                        }
                        return il_label;
@@ -3047,7 +2927,7 @@ namespace Mono.CSharp {
                public Label GetILLabelCode (EmitContext ec)
                {
                        if (!il_label_code_set){
-                               il_label_code = ec.ig.DefineLabel ();
+                               il_label_code = ec.DefineLabel ();
                                il_label_code_set = true;
                        }
                        return il_label_code;
@@ -3057,7 +2937,7 @@ namespace Mono.CSharp {
                // Resolves the expression, reduces it to a literal if possible
                // and then converts it to the requested type.
                //
-               public bool ResolveAndReduce (ResolveContext ec, Type required_type, bool allow_nullable)
+               public bool ResolveAndReduce (ResolveContext ec, TypeSpec required_type, bool allow_nullable)
                {       
                        Expression e = label.Resolve (ec);
 
@@ -3088,7 +2968,7 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public void Error_AlreadyOccurs (ResolveContext ec, Type switch_type, SwitchLabel collision_with)
+               public void Error_AlreadyOccurs (ResolveContext ec, TypeSpec switch_type, SwitchLabel collision_with)
                {
                        string label;
                        if (converted == null)
@@ -3142,7 +3022,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   The governing switch type
                /// </summary>
-               public Type SwitchType;
+               public TypeSpec SwitchType;
 
                //
                // Computed
@@ -3172,7 +3052,7 @@ namespace Mono.CSharp {
                // The types allowed to be implicitly cast from
                // on the governing type
                //
-               static Type [] allowed_types;
+               static TypeSpec [] allowed_types;
 
                public Switch (Expression e, List<SwitchSection> sects, Location l)
                {
@@ -3201,7 +3081,7 @@ namespace Mono.CSharp {
                //
                Expression SwitchGoverningType (ResolveContext ec, Expression expr)
                {
-                       Type t = expr.Type;
+                       TypeSpec t = expr.Type;
 
                        if (t == TypeManager.byte_type ||
                            t == TypeManager.sbyte_type ||
@@ -3218,7 +3098,7 @@ namespace Mono.CSharp {
                                return expr;
 
                        if (allowed_types == null){
-                               allowed_types = new Type [] {
+                               allowed_types = new TypeSpec [] {
                                        TypeManager.sbyte_type,
                                        TypeManager.byte_type,
                                        TypeManager.short_type,
@@ -3239,7 +3119,7 @@ namespace Mono.CSharp {
                        // conversions, we have to report an error
                        //
                        Expression converted = null;
-                       foreach (Type tt in allowed_types){
+                       foreach (TypeSpec tt in allowed_types){
                                Expression e;
                                
                                e = Convert.ImplicitUserConversion (ec, expr, tt, loc);
@@ -3306,50 +3186,50 @@ namespace Mono.CSharp {
                        return !error;
                }
 
-               void EmitObjectInteger (ILGenerator ig, object k)
+               void EmitObjectInteger (EmitContext ec, object k)
                {
                        if (k is int)
-                               IntConstant.EmitInt (ig, (int) k);
+                               ec.EmitInt ((int) k);
                        else if (k is Constant) {
-                               EmitObjectInteger (ig, ((Constant) k).GetValue ());
+                               EmitObjectInteger (ec, ((Constant) k).GetValue ());
                        } 
                        else if (k is uint)
-                               IntConstant.EmitInt (ig, unchecked ((int) (uint) k));
+                               ec.EmitInt (unchecked ((int) (uint) k));
                        else if (k is long)
                        {
                                if ((long) k >= int.MinValue && (long) k <= int.MaxValue)
                                {
-                                       IntConstant.EmitInt (ig, (int) (long) k);
-                                       ig.Emit (OpCodes.Conv_I8);
+                                       ec.EmitInt ((int) (long) k);
+                                       ec.Emit (OpCodes.Conv_I8);
                                }
                                else
-                                       LongConstant.EmitLong (ig, (long) k);
+                                       ec.EmitLong ((long) k);
                        }
                        else if (k is ulong)
                        {
                                ulong ul = (ulong) k;
                                if (ul < (1L<<32))
                                {
-                                       IntConstant.EmitInt (ig, unchecked ((int) ul));
-                                       ig.Emit (OpCodes.Conv_U8);
+                                       ec.EmitInt (unchecked ((int) ul));
+                                       ec.Emit (OpCodes.Conv_U8);
                                }
                                else
                                {
-                                       LongConstant.EmitLong (ig, unchecked ((long) ul));
+                                       ec.EmitLong (unchecked ((long) ul));
                                }
                        }
                        else if (k is char)
-                               IntConstant.EmitInt (ig, (int) ((char) k));
+                               ec.EmitInt ((int) ((char) k));
                        else if (k is sbyte)
-                               IntConstant.EmitInt (ig, (int) ((sbyte) k));
+                               ec.EmitInt ((int) ((sbyte) k));
                        else if (k is byte)
-                               IntConstant.EmitInt (ig, (int) ((byte) k));
+                               ec.EmitInt ((int) ((byte) k));
                        else if (k is short)
-                               IntConstant.EmitInt (ig, (int) ((short) k));
+                               ec.EmitInt ((int) ((short) k));
                        else if (k is ushort)
-                               IntConstant.EmitInt (ig, (int) ((ushort) k));
+                               ec.EmitInt ((int) ((ushort) k));
                        else if (k is bool)
-                               IntConstant.EmitInt (ig, ((bool) k) ? 1 : 0);
+                               ec.EmitInt (((bool) k) ? 1 : 0);
                        else
                                throw new Exception ("Unhandled case");
                }
@@ -3458,25 +3338,24 @@ namespace Mono.CSharp {
                        key_blocks.Sort ();
 
                        // okay now we can start...
-                       ILGenerator ig = ec.ig;
-                       Label lbl_end = ig.DefineLabel ();      // at the end ;-)
+                       Label lbl_end = ec.DefineLabel ();      // at the end ;-)
                        Label lbl_default = default_target;
 
                        Type type_keys = null;
                        if (element_keys.Length > 0)
                                type_keys = element_keys [0].GetType ();        // used for conversions
 
-                       Type compare_type;
+                       TypeSpec compare_type;
                        
                        if (TypeManager.IsEnumType (SwitchType))
-                               compare_type = TypeManager.GetEnumUnderlyingType (SwitchType);
+                               compare_type = EnumSpec.GetUnderlyingType (SwitchType);
                        else
                                compare_type = SwitchType;
                        
                        for (int iBlock = key_blocks.Count - 1; iBlock >= 0; --iBlock)
                        {
                                KeyBlock kb = ((KeyBlock) key_blocks [iBlock]);
-                               lbl_default = (iBlock == 0) ? default_target : ig.DefineLabel ();
+                               lbl_default = (iBlock == 0) ? default_target : ec.DefineLabel ();
                                if (kb.Length <= 2)
                                {
                                        foreach (object key in kb.element_keys) {
@@ -3485,8 +3364,8 @@ namespace Mono.CSharp {
                                                        val.EmitBranchable (ec, sl.GetILLabel (ec), false);
                                                } else {
                                                        val.Emit (ec);
-                                                       EmitObjectInteger (ig, key);
-                                                       ig.Emit (OpCodes.Beq, sl.GetILLabel (ec));
+                                                       EmitObjectInteger (ec, key);
+                                                       ec.Emit (OpCodes.Beq, sl.GetILLabel (ec));
                                                }
                                        }
                                }
@@ -3501,20 +3380,20 @@ namespace Mono.CSharp {
 
                                                // check block range (could be > 2^31)
                                                val.Emit (ec);
-                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.first, type_keys));
-                                               ig.Emit (OpCodes.Blt, lbl_default);
+                                               EmitObjectInteger (ec, System.Convert.ChangeType (kb.first, type_keys));
+                                               ec.Emit (OpCodes.Blt, lbl_default);
                                                val.Emit (ec);
-                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.last, type_keys));
-                                               ig.Emit (OpCodes.Bgt, lbl_default);
+                                               EmitObjectInteger (ec, System.Convert.ChangeType (kb.last, type_keys));
+                                               ec.Emit (OpCodes.Bgt, lbl_default);
 
                                                // normalize range
                                                val.Emit (ec);
                                                if (kb.first != 0)
                                                {
-                                                       EmitObjectInteger (ig, System.Convert.ChangeType (kb.first, type_keys));
-                                                       ig.Emit (OpCodes.Sub);
+                                                       EmitObjectInteger (ec, System.Convert.ChangeType (kb.first, type_keys));
+                                                       ec.Emit (OpCodes.Sub);
                                                }
-                                               ig.Emit (OpCodes.Conv_I4);      // assumes < 2^31 labels!
+                                               ec.Emit (OpCodes.Conv_I4);      // assumes < 2^31 labels!
                                        }
                                        else
                                        {
@@ -3523,13 +3402,13 @@ namespace Mono.CSharp {
                                                int first = (int) kb.first;
                                                if (first > 0)
                                                {
-                                                       IntConstant.EmitInt (ig, first);
-                                                       ig.Emit (OpCodes.Sub);
+                                                       ec.EmitInt (first);
+                                                       ec.Emit (OpCodes.Sub);
                                                }
                                                else if (first < 0)
                                                {
-                                                       IntConstant.EmitInt (ig, -first);
-                                                       ig.Emit (OpCodes.Add);
+                                                       ec.EmitInt (-first);
+                                                       ec.Emit (OpCodes.Add);
                                                }
                                        }
 
@@ -3550,12 +3429,12 @@ namespace Mono.CSharp {
                                                        switch_labels [iJump] = lbl_default;
                                        }
                                        // emit the switch opcode
-                                       ig.Emit (OpCodes.Switch, switch_labels);
+                                       ec.Emit (OpCodes.Switch, switch_labels);
                                }
 
                                // mark the default for this block
                                if (iBlock != 0)
-                                       ig.MarkLabel (lbl_default);
+                                       ec.MarkLabel (lbl_default);
                        }
 
                        // TODO: find the default case and emit it here,
@@ -3564,7 +3443,7 @@ namespace Mono.CSharp {
 
                        // the last default just goes to the end
                        if (element_keys.Length > 0)
-                               ig.Emit (OpCodes.Br, lbl_default);
+                               ec.Emit (OpCodes.Br, lbl_default);
 
                        // now emit the code for the sections
                        bool found_default = false;
@@ -3572,27 +3451,27 @@ namespace Mono.CSharp {
                        foreach (SwitchSection ss in Sections) {
                                foreach (SwitchLabel sl in ss.Labels) {
                                        if (sl.Converted == SwitchLabel.NullStringCase) {
-                                               ig.MarkLabel (null_target);
+                                               ec.MarkLabel (null_target);
                                        } else if (sl.Label == null) {
-                                               ig.MarkLabel (lbl_default);
+                                               ec.MarkLabel (lbl_default);
                                                found_default = true;
                                                if (!has_null_case)
-                                                       ig.MarkLabel (null_target);
+                                                       ec.MarkLabel (null_target);
                                        }
-                                       ig.MarkLabel (sl.GetILLabel (ec));
-                                       ig.MarkLabel (sl.GetILLabelCode (ec));
+                                       ec.MarkLabel (sl.GetILLabel (ec));
+                                       ec.MarkLabel (sl.GetILLabelCode (ec));
                                }
                                ss.Block.Emit (ec);
                        }
                        
                        if (!found_default) {
-                               ig.MarkLabel (lbl_default);
+                               ec.MarkLabel (lbl_default);
                                if (!has_null_case) {
-                                       ig.MarkLabel (null_target);
+                                       ec.MarkLabel (null_target);
                                }
                        }
                        
-                       ig.MarkLabel (lbl_end);
+                       ec.MarkLabel (lbl_end);
                }
 
                SwitchSection FindSection (SwitchLabel label)
@@ -3607,12 +3486,6 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       foreach (SwitchSection ss in Sections)
-                               ss.Block.MutateHoistedGenericType (storey);
-               }
-
                public static void Reset ()
                {
                        unique_counter = 0;
@@ -3736,12 +3609,13 @@ namespace Mono.CSharp {
                                string_dictionary_type = new MemberAccess (system_collections_generic, "Hashtable", loc);
                        }
 
-                       Field field = new Field (ec.CurrentTypeDefinition, string_dictionary_type,
+                       var ctype = ec.CurrentMemberDefinition.Parent.PartialContainer;
+                       Field field = new Field (ctype, string_dictionary_type,
                                Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED,
                                new MemberName (CompilerGeneratedClass.MakeName (null, "f", "switch$map", unique_counter++), loc), null);
                        if (!field.Define ())
                                return;
-                       ec.CurrentTypeDefinition.PartialContainer.AddField (field);
+                       ctype.AddField (field);
 
                        var init = new List<Expression> ();
                        int counter = 0;
@@ -3781,8 +3655,7 @@ namespace Mono.CSharp {
 
                void DoEmitStringSwitch (LocalTemporary value, EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label l_initialized = ig.DefineLabel ();
+                       Label l_initialized = ec.DefineLabel ();
 
                        //
                        // Skip initialization when value is null
@@ -3794,7 +3667,7 @@ namespace Mono.CSharp {
                        //
                        switch_cache_field.EmitBranchable (ec, l_initialized, true);
                        string_dictionary.EmitStatement (ec);
-                       ig.MarkLabel (l_initialized);
+                       ec.MarkLabel (l_initialized);
 
                        LocalTemporary string_switch_variable = new LocalTemporary (TypeManager.int32_type);
 
@@ -3822,7 +3695,7 @@ namespace Mono.CSharp {
 
                                LocalTemporary get_item_object = new LocalTemporary (TypeManager.object_type);
                                get_item_object.EmitAssign (ec, get_item, true, false);
-                               ec.ig.Emit (OpCodes.Brfalse, default_target);
+                               ec.Emit (OpCodes.Brfalse, default_target);
 
                                ExpressionStatement get_item_int = (ExpressionStatement) new SimpleAssign (string_switch_variable,
                                        new Cast (new TypeExpression (TypeManager.int32_type, loc), get_item_object, loc)).Resolve (rc);
@@ -3837,10 +3710,8 @@ namespace Mono.CSharp {
                
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
-                       default_target = ig.DefineLabel ();
-                       null_target = ig.DefineLabel ();
+                       default_target = ec.DefineLabel ();
+                       null_target = ec.DefineLabel ();
 
                        // Store variable for comparission purposes
                        // TODO: Don't duplicate non-captured VariableReference
@@ -3848,7 +3719,7 @@ namespace Mono.CSharp {
                        if (HaveUnwrap) {
                                value = new LocalTemporary (SwitchType);
                                unwrap.EmitCheck (ec);
-                               ig.Emit (OpCodes.Brfalse, null_target);
+                               ec.Emit (OpCodes.Brfalse, null_target);
                                new_expr.Emit (ec);
                                value.Store (ec);
                        } else if (!is_constant) {
@@ -3864,7 +3735,7 @@ namespace Mono.CSharp {
                        Label old_end = ec.LoopEnd;
                        Switch old_switch = ec.Switch;
                        
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
                        ec.Switch = this;
 
                        // Emit Code.
@@ -3881,7 +3752,7 @@ namespace Mono.CSharp {
                                value.Release (ec);
 
                        // Restore context state. 
-                       ig.MarkLabel (ec.LoopEnd);
+                       ec.MarkLabel (ec.LoopEnd);
 
                        //
                        // Restore the previous context
@@ -3912,7 +3783,7 @@ namespace Mono.CSharp {
                {
                        if (!prepared) {
                                prepared = true;
-                               resume_point = ec.ig.DefineLabel ();
+                               resume_point = ec.DefineLabel ();
                        }
                        return resume_point;
                }
@@ -3940,47 +3811,45 @@ namespace Mono.CSharp {
 
                protected sealed override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        EmitPreTryBody (ec);
 
                        if (resume_points != null) {
-                               IntConstant.EmitInt (ig, (int) Iterator.State.Running);
-                               ig.Emit (OpCodes.Stloc, iter.CurrentPC);
+                               ec.EmitInt ((int) Iterator.State.Running);
+                               ec.Emit (OpCodes.Stloc, iter.CurrentPC);
                        }
 
-                       ig.BeginExceptionBlock ();
+                       ec.BeginExceptionBlock ();
 
                        if (resume_points != null) {
-                               ig.MarkLabel (resume_point);
+                               ec.MarkLabel (resume_point);
 
                                // For normal control flow, we want to fall-through the Switch
                                // So, we use CurrentPC rather than the $PC field, and initialize it to an outside value above
-                               ig.Emit (OpCodes.Ldloc, iter.CurrentPC);
-                               IntConstant.EmitInt (ig, first_resume_pc);
-                               ig.Emit (OpCodes.Sub);
+                               ec.Emit (OpCodes.Ldloc, iter.CurrentPC);
+                               ec.EmitInt (first_resume_pc);
+                               ec.Emit (OpCodes.Sub);
 
                                Label [] labels = new Label [resume_points.Count];
                                for (int i = 0; i < resume_points.Count; ++i)
                                        labels [i] = ((ResumableStatement) resume_points [i]).PrepareForEmit (ec);
-                               ig.Emit (OpCodes.Switch, labels);
+                               ec.Emit (OpCodes.Switch, labels);
                        }
 
                        EmitTryBody (ec);
 
-                       ig.BeginFinallyBlock ();
+                       ec.BeginFinallyBlock ();
 
-                       Label start_finally = ec.ig.DefineLabel ();
+                       Label start_finally = ec.DefineLabel ();
                        if (resume_points != null) {
-                               ig.Emit (OpCodes.Ldloc, iter.SkipFinally);
-                               ig.Emit (OpCodes.Brfalse_S, start_finally);
-                               ig.Emit (OpCodes.Endfinally);
+                               ec.Emit (OpCodes.Ldloc, iter.SkipFinally);
+                               ec.Emit (OpCodes.Brfalse_S, start_finally);
+                               ec.Emit (OpCodes.Endfinally);
                        }
 
-                       ig.MarkLabel (start_finally);
+                       ec.MarkLabel (start_finally);
                        EmitFinallyBody (ec);
 
-                       ig.EndExceptionBlock ();
+                       ec.EndExceptionBlock ();
                }
 
                public void SomeCodeFollows ()
@@ -4018,7 +3887,7 @@ namespace Mono.CSharp {
                {
                        if (!prepared_for_dispose) {
                                prepared_for_dispose = true;
-                               dispose_try_block = ec.ig.DefineLabel ();
+                               dispose_try_block = ec.DefineLabel ();
                        }
                        return dispose_try_block;
                }
@@ -4030,17 +3899,15 @@ namespace Mono.CSharp {
 
                        emitted_dispose = true;
 
-                       ILGenerator ig = ec.ig;
-
-                       Label end_of_try = ig.DefineLabel ();
+                       Label end_of_try = ec.DefineLabel ();
 
                        // Ensure that the only way we can get into this code is through a dispatcher
                        if (have_dispatcher)
-                               ig.Emit (OpCodes.Br, end);
+                               ec.Emit (OpCodes.Br, end);
 
-                       ig.BeginExceptionBlock ();
+                       ec.BeginExceptionBlock ();
 
-                       ig.MarkLabel (dispose_try_block);
+                       ec.MarkLabel (dispose_try_block);
 
                        Label [] labels = null;
                        for (int i = 0; i < resume_points.Count; ++i) {
@@ -4065,10 +3932,10 @@ namespace Mono.CSharp {
 
                                if (emit_dispatcher) {
                                        //SymbolWriter.StartIteratorDispatcher (ec.ig);
-                                       ig.Emit (OpCodes.Ldloc, iterator.CurrentPC);
-                                       IntConstant.EmitInt (ig, first_resume_pc);
-                                       ig.Emit (OpCodes.Sub);
-                                       ig.Emit (OpCodes.Switch, labels);
+                                       ec.Emit (OpCodes.Ldloc, iterator.CurrentPC);
+                                       ec.EmitInt (first_resume_pc);
+                                       ec.Emit (OpCodes.Sub);
+                                       ec.Emit (OpCodes.Switch, labels);
                                        //SymbolWriter.EndIteratorDispatcher (ec.ig);
                                }
 
@@ -4076,13 +3943,13 @@ namespace Mono.CSharp {
                                        s.EmitForDispose (ec, iterator, end_of_try, emit_dispatcher);
                        }
 
-                       ig.MarkLabel (end_of_try);
+                       ec.MarkLabel (end_of_try);
 
-                       ig.BeginFinallyBlock ();
+                       ec.BeginFinallyBlock ();
 
                        EmitFinallyBody (ec);
 
-                       ig.EndExceptionBlock ();
+                       ec.EndExceptionBlock ();
                }
        }
 
@@ -4119,7 +3986,7 @@ namespace Mono.CSharp {
 
                        // Avoid creating libraries that reference the internal
                        // mcs NullType:
-                       Type t = expr.Type;
+                       TypeSpec t = expr.Type;
                        if (t == TypeManager.null_type)
                                t = TypeManager.object_type;
                        
@@ -4127,7 +3994,7 @@ namespace Mono.CSharp {
                        temp.Resolve (ec);
 
                        if (TypeManager.void_monitor_enter_object == null || TypeManager.void_monitor_exit_object == null) {
-                               Type monitor_type = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Monitor", MemberKind.Class, true);
+                               TypeSpec monitor_type = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Monitor", MemberKind.Class, true);
                                TypeManager.void_monitor_enter_object = TypeManager.GetPredefinedMethod (
                                        monitor_type, "Enter", loc, TypeManager.object_type);
                                TypeManager.void_monitor_exit_object = TypeManager.GetPredefinedMethod (
@@ -4139,11 +4006,9 @@ namespace Mono.CSharp {
                
                protected override void EmitPreTryBody (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        temp.EmitAssign (ec, expr);
                        temp.Emit (ec);
-                       ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.void_monitor_enter_object.MetaInfo);
+                       ec.Emit (OpCodes.Call, TypeManager.void_monitor_enter_object);
                }
 
                protected override void EmitTryBody (EmitContext ec)
@@ -4154,16 +4019,9 @@ namespace Mono.CSharp {
                protected override void EmitFinallyBody (EmitContext ec)
                {
                        temp.Emit (ec);
-                       ec.ig.Emit (OpCodes.Call, (MethodInfo) TypeManager.void_monitor_exit_object.MetaInfo);
+                       ec.Emit (OpCodes.Call, TypeManager.void_monitor_exit_object);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr.MutateHoistedGenericType (storey);
-                       temp.MutateHoistedGenericType (storey);
-                       Statement.MutateHoistedGenericType (storey);
-               }
-               
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Lock target = (Lock) t;
@@ -4194,11 +4052,6 @@ namespace Mono.CSharp {
                                Block.Emit (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Block.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Unchecked target = (Unchecked) t;
@@ -4228,11 +4081,6 @@ namespace Mono.CSharp {
                                Block.Emit (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Block.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Checked target = (Checked) t;
@@ -4265,11 +4113,6 @@ namespace Mono.CSharp {
                        Block.Emit (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Block.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Unsafe target = (Unsafe) t;
@@ -4285,7 +4128,7 @@ namespace Mono.CSharp {
                Expression type;
                List<KeyValuePair<LocalInfo, Expression>> declarators;
                Statement statement;
-               Type expr_type;
+               TypeSpec expr_type;
                Emitter[] data;
                bool has_ret;
 
@@ -4320,8 +4163,8 @@ namespace Mono.CSharp {
 
                        public override void EmitExit (EmitContext ec)
                        {
-                               ec.ig.Emit (OpCodes.Ldc_I4_0);
-                               ec.ig.Emit (OpCodes.Conv_U);
+                               ec.Emit (OpCodes.Ldc_I4_0);
+                               ec.Emit (OpCodes.Conv_U);
                                vi.EmitAssign (ec);
                        }
                }
@@ -4358,19 +4201,19 @@ namespace Mono.CSharp {
 
                                // TODO: Should use Binary::Add
                                pinned_string.Emit (ec);
-                               ec.ig.Emit (OpCodes.Conv_I);
+                               ec.Emit (OpCodes.Conv_I);
 
                                PropertyExpr pe = new PropertyExpr (pinned_string.VariableType, TypeManager.int_get_offset_to_string_data, pinned_string.Location);
                                //pe.InstanceExpression = pinned_string;
                                pe.Resolve (new ResolveContext (ec.MemberContext)).Emit (ec);
 
-                               ec.ig.Emit (OpCodes.Add);
+                               ec.Emit (OpCodes.Add);
                                vi.EmitAssign (ec);
                        }
 
                        public override void EmitExit (EmitContext ec)
                        {
-                               ec.ig.Emit (OpCodes.Ldnull);
+                               ec.Emit (OpCodes.Ldnull);
                                pinned_string.EmitAssign (ec);
                        }
                }
@@ -4446,7 +4289,7 @@ namespace Mono.CSharp {
                                // Case 2: Array
                                //
                                if (e.Type.IsArray){
-                                       Type array_type = TypeManager.GetElementType (e.Type);
+                                       TypeSpec array_type = TypeManager.GetElementType (e.Type);
                                        
                                        //
                                        // Provided that array_type is unmanaged,
@@ -4541,12 +4384,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       // Fixed statement cannot be used inside anonymous methods or lambdas
-                       throw new NotSupportedException ();
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Fixed target = (Fixed) t;
@@ -4568,7 +4405,7 @@ namespace Mono.CSharp {
                public Block  VarBlock;
 
                Expression type_expr;
-               Type type;
+               TypeSpec type;
                
                public Catch (Expression type, string name, Block block, Block var_block, Location l)
                {
@@ -4579,7 +4416,7 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public Type CatchType {
+               public TypeSpec CatchType {
                        get {
                                return type;
                        }
@@ -4593,12 +4430,10 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        if (CatchType != null)
-                               ig.BeginCatchBlock (CatchType);
+                               ec.BeginCatchBlock (CatchType);
                        else
-                               ig.BeginCatchBlock (TypeManager.object_type);
+                               ec.BeginCatchBlock (TypeManager.object_type);
 
                        if (VarBlock != null)
                                VarBlock.Emit (ec);
@@ -4610,7 +4445,7 @@ namespace Mono.CSharp {
                                
                                // Only to make verifier happy
                                if (TypeManager.IsGenericParameter (lvr.Type))
-                                       ig.Emit (OpCodes.Unbox_Any, lvr.Type);
+                                       ec.Emit (OpCodes.Unbox_Any, lvr.Type);
 
                                Expression source;
                                if (lvr.IsHoisted) {
@@ -4624,7 +4459,7 @@ namespace Mono.CSharp {
 
                                lvr.EmitAssign (ec, source, false, false);
                        } else
-                               ig.Emit (OpCodes.Pop);
+                               ec.Emit (OpCodes.Pop);
 
                        Block.Emit (ec);
                }
@@ -4658,15 +4493,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       if (type != null)
-                               type = storey.MutateType (type);
-                       if (VarBlock != null)
-                               VarBlock.MutateHoistedGenericType (storey);
-                       Block.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Catch target = (Catch) t;
@@ -4727,12 +4553,6 @@ namespace Mono.CSharp {
                        fini.Emit (ec);
                }
 
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       stmt.MutateHoistedGenericType (storey);
-                       fini.MutateHoistedGenericType (storey);
-               }
-
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        TryFinally target = (TryFinally) t;
@@ -4773,7 +4593,7 @@ namespace Mono.CSharp {
                        if (!Block.Resolve (ec))
                                ok = false;
 
-                       Type[] prev_catches = new Type [Specific.Count];
+                       TypeSpec[] prev_catches = new TypeSpec [Specific.Count];
                        int last_index = 0;
                        foreach (Catch c in Specific){
                                ec.CurrentBranching.CreateSibling (c.Block, FlowBranching.SiblingType.Catch);
@@ -4791,7 +4611,7 @@ namespace Mono.CSharp {
                                        continue;
                                }
 
-                               Type resolved_type = c.CatchType;
+                               TypeSpec resolved_type = c.CatchType;
                                for (int ii = 0; ii < last_index; ++ii) {
                                        if (resolved_type == prev_catches [ii] || TypeManager.IsSubclassOf (resolved_type, prev_catches [ii])) {
                                                ec.Report.Error (160, c.loc,
@@ -4836,10 +4656,8 @@ namespace Mono.CSharp {
                
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        if (!inside_try_finally)
-                               ig.BeginExceptionBlock ();
+                               ec.BeginExceptionBlock ();
 
                        Block.Emit (ec);
 
@@ -4850,19 +4668,7 @@ namespace Mono.CSharp {
                                General.Emit (ec);
 
                        if (!inside_try_finally)
-                               ig.EndExceptionBlock ();
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       Block.MutateHoistedGenericType (storey);
-
-                       if (General != null)
-                               General.MutateHoistedGenericType (storey);
-                       if (Specific != null) {
-                               foreach (Catch c in Specific)
-                                       c.MutateHoistedGenericType (storey);
-                       }
+                               ec.EndExceptionBlock ();
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -4885,7 +4691,7 @@ namespace Mono.CSharp {
                TemporaryVariable local_copy;
                public Statement Statement;
                Expression expr;
-               Type expr_type;
+               TypeSpec expr_type;
 
                public UsingTemporary (Expression expr, Statement stmt, Location l)
                {
@@ -4902,9 +4708,9 @@ namespace Mono.CSharp {
 
                        expr_type = expr.Type;
 
-                       if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type) &&
+                       if (!expr_type.ImplementsInterface (TypeManager.idisposable_type) &&
                                Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
-                               if (!TypeManager.IsDynamicType (expr_type)) {
+                               if (expr_type != InternalType.Dynamic) {
                                        Using.Error_IsNotConvertibleToIDisposable (ec, expr);
                                        return false;
                                }
@@ -4926,7 +4732,7 @@ namespace Mono.CSharp {
 
                        if (TypeManager.void_dispose_void == null) {
                                TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
-                                       TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+                                       TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
                        }
 
                        return ok;
@@ -4944,51 +4750,29 @@ namespace Mono.CSharp {
 
                protected override void EmitFinallyBody (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
                        if (!TypeManager.IsStruct (expr_type)) {
-                               Label skip = ig.DefineLabel ();
+                               Label skip = ec.DefineLabel ();
                                local_copy.Emit (ec);
-                               ig.Emit (OpCodes.Brfalse, skip);
+                               ec.Emit (OpCodes.Brfalse, skip);
                                local_copy.Emit (ec);
-                               ig.Emit (OpCodes.Callvirt, (MethodInfo) TypeManager.void_dispose_void.MetaInfo);
-                               ig.MarkLabel (skip);
+                               ec.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+                               ec.MarkLabel (skip);
                                return;
                        }
 
-                       Expression ml = Expression.MemberLookup (RootContext.ToplevelTypes.Compiler,
-                               ec.CurrentType, TypeManager.idisposable_type, expr_type,
-                               "Dispose", Location.Null);
+                       MethodSpec ms = MemberCache.FindMember (expr_type,
+                               MemberFilter.Method ("Dispose", 0, ParametersCompiled.EmptyReadOnlyParameters, TypeManager.void_type),
+                               BindingRestriction.InstanceOnly) as MethodSpec;
 
-                       if (!(ml is MethodGroupExpr)) {
+                       if (ms == null) {
                                local_copy.Emit (ec);
-                               ig.Emit (OpCodes.Box, expr_type);
-                               ig.Emit (OpCodes.Callvirt, (MethodInfo) TypeManager.void_dispose_void.MetaInfo);
-                               return;
-                       }
-
-                       MethodSpec mi = null;
-
-                       foreach (var mk in ((MethodGroupExpr) ml).Methods) {
-                               if (mk.Parameters.IsEmpty) {
-                                       mi = mk;
-                                       break;
-                               }
-                       }
-
-                       if (mi == null) {
-                               ec.Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
+                               ec.Emit (OpCodes.Box, expr_type);
+                               ec.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
                                return;
                        }
 
                        local_copy.AddressOf (ec, AddressOp.Load);
-                       ig.Emit (OpCodes.Call, (MethodInfo) mi.MetaInfo);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       expr_type = storey.MutateType (expr_type);
-                       local_copy.MutateHoistedGenericType (storey);
-                       Statement.MutateHoistedGenericType (storey);
+                       ec.Emit (OpCodes.Call, ms);
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -5038,26 +4822,18 @@ namespace Mono.CSharp {
 
                protected override void EmitFinallyBody (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       Label skip = ig.DefineLabel ();
+                       Label skip = ec.DefineLabel ();
 
                        bool emit_null_check = !TypeManager.IsValueType (var.Type);
                        if (emit_null_check) {
                                var.Emit (ec);
-                               ig.Emit (OpCodes.Brfalse, skip);
+                               ec.Emit (OpCodes.Brfalse, skip);
                        }
 
                        Invocation.EmitCall (ec, false, var, TypeManager.void_dispose_void, null, loc);
 
                        if (emit_null_check)
-                               ig.MarkLabel (skip);
-               }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       assign.MutateHoistedGenericType (storey);
-                       var.MutateHoistedGenericType (storey);
-                       stmt.MutateHoistedGenericType (storey);
+                               ec.MarkLabel (skip);
                }
 
                public override bool Resolve (BlockContext ec)
@@ -5075,7 +4851,7 @@ namespace Mono.CSharp {
 
                        if (TypeManager.void_dispose_void == null) {
                                TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
-                                       TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+                                       TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
                        }
 
                        return ok;
@@ -5088,14 +4864,13 @@ namespace Mono.CSharp {
                        if (assign == null)
                                return false;
 
-                       if (assign.Type == TypeManager.idisposable_type ||
-                               TypeManager.ImplementsInterface (assign.Type, TypeManager.idisposable_type)) {
+                       if (assign.Type == TypeManager.idisposable_type || assign.Type.ImplementsInterface (TypeManager.idisposable_type)) {
                                return true;
                        }
 
                        Expression e = Convert.ImplicitConversionStandard (ec, assign, TypeManager.idisposable_type, var.Location);
                        if (e == null) {
-                               if (TypeManager.IsDynamicType (assign.Type)) {
+                               if (assign.Type == InternalType.Dynamic) {
                                        e = Convert.ImplicitConversionRequired (ec, assign, TypeManager.idisposable_type, loc);
                                        var = new TemporaryVariable (e.Type, loc);
                                        assign = new SimpleAssign (var, e, loc).ResolveStatement (ec);
@@ -5248,8 +5023,6 @@ namespace Mono.CSharp {
 
                        protected override void DoEmit (EmitContext ec)
                        {
-                               ILGenerator ig = ec.ig;
-
                                copy.EmitAssign (ec, for_each.expr);
 
                                int rank = length_exprs.Length;
@@ -5257,8 +5030,8 @@ namespace Mono.CSharp {
                                Label[] loop = new Label [rank];
 
                                for (int i = 0; i < rank; i++) {
-                                       test [i] = ig.DefineLabel ();
-                                       loop [i] = ig.DefineLabel ();
+                                       test [i] = ec.DefineLabel ();
+                                       loop [i] = ec.DefineLabel ();
 
                                        if (lengths != null)
                                                lengths [i].EmitAssign (ec, length_exprs [i]);
@@ -5268,20 +5041,20 @@ namespace Mono.CSharp {
                                for (int i = 0; i < rank; i++) {
                                        counter [i].EmitAssign (ec, zero);
 
-                                       ig.Emit (OpCodes.Br, test [i]);
-                                       ig.MarkLabel (loop [i]);
+                                       ec.Emit (OpCodes.Br, test [i]);
+                                       ec.MarkLabel (loop [i]);
                                }
 
                                ((IAssignMethod) for_each.variable).EmitAssign (ec, conv, false, false);
 
                                statement.Emit (ec);
 
-                               ig.MarkLabel (ec.LoopBegin);
+                               ec.MarkLabel (ec.LoopBegin);
 
                                for (int i = rank - 1; i >= 0; i--){
                                        counter [i].EmitIncrement (ec);
 
-                                       ig.MarkLabel (test [i]);
+                                       ec.MarkLabel (test [i]);
                                        counter [i].Emit (ec);
 
                                        if (lengths != null)
@@ -5289,25 +5062,10 @@ namespace Mono.CSharp {
                                        else
                                                length_exprs [i].Emit (ec);
 
-                                       ig.Emit (OpCodes.Blt, loop [i]);
+                                       ec.Emit (OpCodes.Blt, loop [i]);
                                }
 
-                               ig.MarkLabel (ec.LoopEnd);
-                       }
-
-                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                       {
-                               for_each.expr.MutateHoistedGenericType (storey);
-
-                               copy.MutateHoistedGenericType (storey);
-                               conv.MutateHoistedGenericType (storey);
-                               statement.MutateHoistedGenericType (storey);
-
-                               for (int i = 0; i < counter.Length; i++) {
-                                       counter [i].MutateHoistedGenericType (storey);
-                                       if (lengths != null)
-                                               lengths [i].MutateHoistedGenericType (storey);
-                               }
+                               ec.MarkLabel (ec.LoopEnd);
                        }
                }
 
@@ -5315,12 +5073,12 @@ namespace Mono.CSharp {
                {
                        class CollectionForeachStatement : Statement
                        {
-                               Type type;
+                               TypeSpec type;
                                Expression variable, current, conv;
                                Statement statement;
                                Assign assign;
 
-                               public CollectionForeachStatement (Type type, Expression variable,
+                               public CollectionForeachStatement (TypeSpec type, Expression variable,
                                                                   Expression current, Statement statement,
                                                                   Location loc)
                                {
@@ -5361,12 +5119,6 @@ namespace Mono.CSharp {
                                        assign.EmitStatement (ec);
                                        statement.Emit (ec);
                                }
-
-                               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                               {
-                                       assign.MutateHoistedGenericType (storey);
-                                       statement.MutateHoistedGenericType (storey);
-                               }
                        }
 
                        Expression variable, expr;
@@ -5381,7 +5133,7 @@ namespace Mono.CSharp {
                        PropertyExpr get_current;
                        MethodSpec move_next;
                        Expression var_type;
-                       Type enumerator_type;
+                       TypeSpec enumerator_type;
                        bool enumerator_found;
 
                        public CollectionForeach (Expression var_type, Expression var,
@@ -5401,7 +5153,7 @@ namespace Mono.CSharp {
 
                        bool GetEnumeratorFilter (ResolveContext ec, MethodSpec mi)
                        {
-                               Type return_type = mi.ReturnType;
+                               TypeSpec return_type = mi.ReturnType;
 
                                //
                                // Ok, we can access it, now make sure that we can do something
@@ -5409,7 +5161,7 @@ namespace Mono.CSharp {
                                //
 
                                if (return_type == TypeManager.ienumerator_type ||
-                                       TypeManager.ImplementsInterface (return_type, TypeManager.ienumerator_type)) {
+                                       return_type.ImplementsInterface (TypeManager.ienumerator_type)) {
                                        //
                                        // If it is not an interface, lets try to find the methods ourselves.
                                        // For example, if we have:
@@ -5426,7 +5178,7 @@ namespace Mono.CSharp {
 
                                        if (TypeManager.bool_movenext_void == null) {
                                                TypeManager.bool_movenext_void = TypeManager.GetPredefinedMethod (
-                                                       TypeManager.ienumerator_type, "MoveNext", loc, Type.EmptyTypes);
+                                                       TypeManager.ienumerator_type, "MoveNext", loc, TypeSpec.EmptyTypes);
                                        }
 
                                        if (TypeManager.ienumerator_getcurrent == null) {
@@ -5477,37 +5229,23 @@ namespace Mono.CSharp {
                        //
                        // Retrieves a `public bool MoveNext ()' method from the Type `t'
                        //
-                       bool FetchMoveNext (Type t)
+                       bool FetchMoveNext (TypeSpec t)
                        {
-                               MemberInfo[] move_next_list = TypeManager.MemberLookup (null, null, t,
-                                       MemberTypes.Method,
-                                       BindingFlags.Public | BindingFlags.Instance,
-                                       "MoveNext", null);
-
-                               if (move_next_list == null)
-                                       return false;
+                               move_next = MemberCache.FindMember (t,
+                                       MemberFilter.Method ("MoveNext", 0, ParametersCompiled.EmptyReadOnlyParameters, TypeManager.bool_type),
+                                       BindingRestriction.InstanceOnly) as MethodSpec;
 
-                               foreach (MemberInfo m in move_next_list){
-                                       MethodInfo mi = (MethodInfo) m;
-                               
-                                       if ((TypeManager.GetParameterData (mi).Count == 0) &&
-                                           TypeManager.TypeToCoreType (mi.ReturnType) == TypeManager.bool_type) {
-                                               move_next = Import.CreateMethod (mi);
-                                               return true;
-                                       }
-                               }
-
-                               return false;
+                               return move_next != null && (move_next.Modifiers & Modifiers.PUBLIC) != 0;
                        }
                
                        //
                        // Retrieves a `public T get_Current ()' method from the Type `t'
                        //
-                       bool FetchGetCurrent (ResolveContext ec, Type t)
+                       bool FetchGetCurrent (ResolveContext ec, TypeSpec t)
                        {
                                PropertyExpr pe = Expression.MemberLookup (ec.Compiler,
-                                       ec.CurrentType, t, "Current", MemberTypes.Property,
-                                       Expression.AllBindingFlags, loc) as PropertyExpr;
+                                       ec.CurrentType, t, "Current", 0, MemberKind.Property,
+                                       BindingRestriction.AccessibleOnly, loc) as PropertyExpr;
                                if (pe == null)
                                        return false;
 
@@ -5526,41 +5264,24 @@ namespace Mono.CSharp {
                                        TypeManager.CSharpName (expr.Type));
                        }
 
-                       bool IsOverride (MethodSpec ms)
+                       bool TryType (ResolveContext ec, TypeSpec t)
                        {
-                               MethodInfo m = (MethodInfo) ms.MetaInfo;
-                               m = (MethodInfo) TypeManager.DropGenericMethodArguments (m);
-
-                               if (!m.IsVirtual || ((m.Attributes & MethodAttributes.NewSlot) != 0))
-                                       return false;
-                               if (m is MethodBuilder)
-                                       return true;
-
-                               MethodInfo base_method = m.GetBaseDefinition ();
-                               return base_method != m;
-                       }
+                               var mg = Expression.MemberLookup (ec.Compiler, ec.CurrentType, null, t, "GetEnumerator", 0,
+                                       MemberKind.Method, BindingRestriction.NoOverrides | BindingRestriction.InstanceOnly, loc) as MethodGroupExpr;
 
-                       bool TryType (ResolveContext ec, Type t)
-                       {
-                               MethodGroupExpr mg = Expression.MemberLookup (ec.Compiler,
-                                       ec.CurrentType, t, "GetEnumerator", MemberTypes.Method,
-                                       Expression.AllBindingFlags, loc) as MethodGroupExpr;
                                if (mg == null)
                                        return false;
 
                                MethodSpec result = null;
                                MethodSpec tmp_move_next = null;
                                PropertyExpr tmp_get_cur = null;
-                               Type tmp_enumerator_type = enumerator_type;
-                               foreach (var mi in mg.Methods) {
+                               TypeSpec tmp_enumerator_type = enumerator_type;
+                               foreach (MethodSpec mi in mg.Methods) {
                                        if (!mi.Parameters.IsEmpty)
                                                continue;
                        
                                        // Check whether GetEnumerator is public
-                                       if ((mi.MetaInfo.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
-                                               continue;
-
-                                       if (IsOverride (mi))
+                                       if ((mi.Modifiers & Modifiers.AccessibilityMask) != Modifiers.PUBLIC)
                                                continue;
 
                                        enumerator_found = true;
@@ -5573,24 +5294,23 @@ namespace Mono.CSharp {
                                                        if (!TypeManager.IsGenericType (mi.ReturnType))
                                                                continue;
 
-                                                       MethodBase mb = TypeManager.DropGenericMethodArguments (mi);
                                                        ec.Report.SymbolRelatedToPreviousError (t);
                                                        ec.Report.Error(1640, loc, "foreach statement cannot operate on variables of type `{0}' " +
-                                                                    "because it contains multiple implementation of `{1}'. Try casting to a specific implementation",
-                                                                    TypeManager.CSharpName (t), TypeManager.CSharpSignature (mb));
+                                                                        "because it contains multiple implementation of `{1}'. Try casting to a specific implementation",
+                                                                        TypeManager.CSharpName (t), TypeManager.generic_ienumerable_type.GetSignatureForError ());
                                                        return false;
                                                }
 
                                                // Always prefer generics enumerators
                                                if (!TypeManager.IsGenericType (mi.ReturnType)) {
-                                                       if (TypeManager.ImplementsInterface (mi.DeclaringType, result.DeclaringType) ||
-                                                           TypeManager.ImplementsInterface (result.DeclaringType, mi.DeclaringType))
+                                                       if (mi.DeclaringType.ImplementsInterface (result.DeclaringType) ||
+                                                               result.DeclaringType.ImplementsInterface (mi.DeclaringType))
                                                                continue;
 
-                                                       ec.Report.SymbolRelatedToPreviousError (result.MetaInfo);
-                                                       ec.Report.SymbolRelatedToPreviousError (mi.MetaInfo);
+                                                       ec.Report.SymbolRelatedToPreviousError (result);
+                                                       ec.Report.SymbolRelatedToPreviousError (mi);
                                                        ec.Report.Warning (278, 2, loc, "`{0}' contains ambiguous implementation of `{1}' pattern. Method `{2}' is ambiguous with method `{3}'",
-                                                                       TypeManager.CSharpName (t), "enumerable", TypeManager.CSharpSignature (result.MetaInfo), TypeManager.CSharpSignature (mi.MetaInfo));
+                                                                       TypeManager.CSharpName (t), "enumerable", result.GetSignatureForError (), mi.GetSignatureForError ());
                                                        return false;
                                                }
                                        }
@@ -5606,8 +5326,7 @@ namespace Mono.CSharp {
                                        move_next = tmp_move_next;
                                        get_current = tmp_get_cur;
                                        enumerator_type = tmp_enumerator_type;
-                                       var mi = new [] { result };
-                                       get_enumerator = new MethodGroupExpr (mi, enumerator_type, loc);
+                                       get_enumerator = new MethodGroupExpr (result, enumerator_type, loc);
 
                                        if (t != expr.Type) {
                                                expr = Convert.ExplicitConversion (
@@ -5625,10 +5344,10 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       bool ProbeCollectionType (ResolveContext ec, Type t)
+                       bool ProbeCollectionType (ResolveContext ec, TypeSpec t)
                        {
                                int errors = ec.Report.Errors;
-                               for (Type tt = t; tt != null && tt != TypeManager.object_type;){
+                               for (TypeSpec tt = t; tt != null && tt != TypeManager.object_type;){
                                        if (TryType (ec, tt))
                                                return true;
                                        tt = tt.BaseType;
@@ -5640,10 +5359,14 @@ namespace Mono.CSharp {
                                //
                                // Now try to find the method in the interfaces
                                //
-                               Type [] ifaces = TypeManager.GetInterfaces (t);
-                               foreach (Type i in ifaces){
-                                       if (TryType (ec, i))
-                                               return true;
+                               for (TypeSpec tt = t; tt != null && tt != TypeManager.object_type; ) {
+                                       if (tt.Interfaces != null) {
+                                               foreach (TypeSpec i in tt.Interfaces) {
+                                                       if (TryType (ec, i))
+                                                               return true;
+                                               }
+                                       }
+                                       tt = tt.BaseType;
                                }
 
                                return false;
@@ -5653,7 +5376,7 @@ namespace Mono.CSharp {
                        {
                                enumerator_type = TypeManager.ienumerator_type;
 
-                               bool is_dynamic = TypeManager.IsDynamicType (expr.Type);
+                               bool is_dynamic = expr.Type == InternalType.Dynamic;
                                if (is_dynamic)
                                        expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.ienumerable_type, loc);
                                
@@ -5666,7 +5389,7 @@ namespace Mono.CSharp {
                                if (ve != null) {
                                        // Infer implicitly typed local variable from foreach enumerable type
                                        var_type = new TypeExpression (
-                                               is_dynamic ? InternalType.Dynamic : get_current.PropertyInfo.PropertyType,
+                                               is_dynamic ? InternalType.Dynamic : get_current.Type,
                                                var_type.Location);
                                }
 
@@ -5684,7 +5407,7 @@ namespace Mono.CSharp {
 
                                Expression move_next_expr;
                                {
-                                       var mi = new [] { move_next };
+                                       var mi = new List<MemberSpec> (1) { move_next };
                                        MethodGroupExpr mg = new MethodGroupExpr (mi, var_type.Type, loc);
                                        mg.InstanceExpression = enumerator;
 
@@ -5699,7 +5422,7 @@ namespace Mono.CSharp {
                                loop = new While (new BooleanExpression (move_next_expr), block, loc);
 
 
-                               bool implements_idisposable = TypeManager.ImplementsInterface (enumerator_type, TypeManager.idisposable_type);
+                               bool implements_idisposable = enumerator_type.ImplementsInterface (TypeManager.idisposable_type);
                                if (implements_idisposable || !enumerator_type.IsSealed) {
                                        wrapper = new DisposableWrapper (this, implements_idisposable);
                                } else {
@@ -5737,11 +5460,6 @@ namespace Mono.CSharp {
                                        parent.EmitLoopInit (ec);
                                        parent.EmitLoopBody (ec);
                                }
-
-                               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                               {
-                                       throw new NotSupportedException ();
-                               }
                        }
 
                        sealed class DisposableWrapper : ExceptionStatement
@@ -5775,7 +5493,7 @@ namespace Mono.CSharp {
 
                                        if (TypeManager.void_dispose_void == null) {
                                                TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
-                                                       TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+                                                       TypeManager.idisposable_type, "Dispose", loc, TypeSpec.EmptyTypes);
                                        }
                                        return ok;
                                }
@@ -5794,34 +5512,28 @@ namespace Mono.CSharp {
                                {
                                        Expression instance = parent.enumerator;
                                        if (!TypeManager.IsValueType (parent.enumerator_type)) {
-                                               ILGenerator ig = ec.ig;
 
                                                parent.enumerator.Emit (ec);
 
-                                               Label call_dispose = ig.DefineLabel ();
+                                               Label call_dispose = ec.DefineLabel ();
 
                                                if (!implements_idisposable) {
-                                                       ec.ig.Emit (OpCodes.Isinst, TypeManager.idisposable_type);
+                                                       ec.Emit (OpCodes.Isinst, TypeManager.idisposable_type);
                                                        LocalTemporary temp = new LocalTemporary (TypeManager.idisposable_type);
                                                        temp.Store (ec);
                                                        temp.Emit (ec);
                                                        instance = temp;
                                                }
                                                
-                                               ig.Emit (OpCodes.Brtrue_S, call_dispose);
+                                               ec.Emit (OpCodes.Brtrue_S, call_dispose);
 
                                                // using 'endfinally' to empty the evaluation stack
-                                               ig.Emit (OpCodes.Endfinally);
-                                               ig.MarkLabel (call_dispose);
+                                               ec.Emit (OpCodes.Endfinally);
+                                               ec.MarkLabel (call_dispose);
                                        }
 
                                        Invocation.EmitCall (ec, false, instance, TypeManager.void_dispose_void, null, loc);
                                }
-
-                               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                               {
-                                       throw new NotSupportedException ();
-                               }
                        }
 
                        bool ResolveLoop (BlockContext ec)
@@ -5838,13 +5550,6 @@ namespace Mono.CSharp {
                        {
                                loop.Emit (ec);
                        }
-
-                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-                       {
-                               enumerator_type = storey.MutateType (enumerator_type);
-                               init.MutateHoistedGenericType (storey);
-                               loop.MutateHoistedGenericType (storey);
-                       }
                }
 
                Expression type;
@@ -5879,8 +5584,8 @@ namespace Mono.CSharp {
 
                        if (expr.Type == TypeManager.string_type) {
                                statement = new ArrayForeach (this, 1);
-                       } else if (expr.Type.IsArray) {
-                               statement = new ArrayForeach (this, expr.Type.GetArrayRank ());
+                       } else if (expr.Type is ArrayContainer) {
+                               statement = new ArrayForeach (this, ((ArrayContainer) expr.Type).Rank);
                        } else {
                                if (expr.eclass == ExprClass.MethodGroup || expr is AnonymousMethodExpression) {
                                        ec.Report.Error (446, expr.Location, "Foreach statement cannot operate on a `{0}'",
@@ -5896,11 +5601,9 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-
                        Label old_begin = ec.LoopBegin, old_end = ec.LoopEnd;
-                       ec.LoopBegin = ig.DefineLabel ();
-                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.LoopBegin = ec.DefineLabel ();
+                       ec.LoopEnd = ec.DefineLabel ();
 
                        statement.Emit (ec);
 
@@ -5917,10 +5620,5 @@ namespace Mono.CSharp {
                        target.expr = expr.Clone (clonectx);
                        target.statement = statement.Clone (clonectx);
                }
-
-               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
-               {
-                       statement.MutateHoistedGenericType (storey);
-               }
        }
 }
index 8cca4a54b9cc289ce859f3cf9035be9749adc697..8fcb5bf6081b058042eb984fdb684167c9412570 100644 (file)
@@ -20,7 +20,7 @@ using System.Collections.Generic;
 
 namespace Mono.CSharp {
 
-       class ReferenceEquality<T> : IEqualityComparer<T> where T : class
+       sealed class ReferenceEquality<T> : IEqualityComparer<T> where T : class
        {
                public static readonly IEqualityComparer<T> Default = new ReferenceEquality<T> ();
 
@@ -39,7 +39,7 @@ namespace Mono.CSharp {
                }
        }
 
-       class Tuple<T1, T2>
+       class Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
        {
                public Tuple (T1 item1, T2 item2)
                {
@@ -49,6 +49,29 @@ namespace Mono.CSharp {
 
                public T1 Item1 { get; private set; }
                public T2 Item2 { get; private set; }
+
+               public override int GetHashCode ()
+               {
+                       return Item1.GetHashCode () ^ Item2.GetHashCode ();
+               }
+
+               #region IEquatable<Tuple<T1,T2>> Members
+
+               public bool Equals (Tuple<T1, T2> other)
+               {
+                       return EqualityComparer<T1>.Default.Equals (Item1, other.Item1) &&
+                               EqualityComparer<T2>.Default.Equals (Item2, other.Item2);
+               }
+
+               #endregion
+       }
+
+       static class Tuple
+       {
+               public static Tuple<T1, T2> Create<T1, T2> (T1 item1, T2 item2)
+               {
+                       return new Tuple<T1, T2> (item1, item2);
+               }
        }
 
        public class Accessors {
@@ -254,489 +277,6 @@ namespace Mono.CSharp {
                }
        }
 
-       class PartialMethodDefinitionInfo : MethodInfo
-       {
-               MethodOrOperator mc;
-               MethodAttributes attrs;
-
-               public PartialMethodDefinitionInfo (MethodOrOperator mc)
-               {
-                       this.mc = mc;
-                       if ((mc.ModFlags & Modifiers.STATIC) != 0)
-                               attrs = MethodAttributes.Static;
-               }
-
-               public override MethodInfo GetBaseDefinition ()
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override ICustomAttributeProvider ReturnTypeCustomAttributes
-               {
-                       get { throw new NotImplementedException (); }
-               }
-
-               public override MethodAttributes Attributes
-               {
-                       get { return attrs; }
-               }
-
-               public override MethodImplAttributes GetMethodImplementationFlags ()
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override ParameterInfo [] GetParameters ()
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object [] parameters, CultureInfo culture)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override RuntimeMethodHandle MethodHandle
-               {
-                       get { throw new NotImplementedException (); }
-               }
-
-               public override Type DeclaringType
-               {
-                       get { return mc.Parent.TypeBuilder; }
-               }
-
-               public override object [] GetCustomAttributes (Type attributeType, bool inherit)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override object [] GetCustomAttributes (bool inherit)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type ReturnType {
-                       get {
-                               return mc.MemberType;
-                       }
-               }
-
-               public override bool IsDefined (Type attributeType, bool inherit)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override string Name
-               {
-                       get { return mc.Name; }
-               }
-
-               public override Type ReflectedType
-               {
-                       get { throw new NotImplementedException (); }
-               }
-       }
-
-#if NET_4_0 || MS_COMPATIBLE
-       [System.Diagnostics.DebuggerDisplay ("Dynamic type")]
-#endif
-       class DynamicType : Type
-       {
-               public override Assembly Assembly {
-                       get { return CodeGen.Assembly.Builder; }
-               }
-
-               public override string AssemblyQualifiedName {
-                       get { throw new NotImplementedException (); }
-               }
-
-               public override Type BaseType {
-                       get { return null; }
-               }
-
-               public override string FullName {
-                       get { return UnderlyingSystemType.FullName; }
-               }
-
-               public override Guid GUID {
-                       get { throw new NotImplementedException (); }
-               }
-
-               protected override TypeAttributes GetAttributeFlagsImpl ()
-               {
-                       return UnderlyingSystemType.Attributes;
-               }
-
-               protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type GetElementType ()
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override EventInfo[] GetEvents (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override FieldInfo GetField (string name, BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override FieldInfo[] GetFields (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type GetInterface (string name, bool ignoreCase)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type[] GetInterfaces ()
-               {
-                       return Type.EmptyTypes;
-               }
-
-               public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override MethodInfo[] GetMethods (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type GetNestedType (string name, BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type[] GetNestedTypes (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override PropertyInfo[] GetProperties (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override bool HasElementTypeImpl ()
-               {
-                       return false;
-               }
-
-               public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override bool IsArrayImpl ()
-               {
-                       return false;
-               }
-
-               protected override bool IsByRefImpl ()
-               {
-                       return false;
-               }
-
-               protected override bool IsCOMObjectImpl ()
-               {
-                       return false;
-               }
-
-               protected override bool IsPointerImpl ()
-               {
-                       return false;
-               }
-
-               protected override bool IsPrimitiveImpl ()
-               {
-                       return false;
-               }
-
-               public override Module Module {
-                       get { return UnderlyingSystemType.Module; }
-               }
-
-               public override string Namespace {
-                       get { return UnderlyingSystemType.Namespace; }
-               }
-
-               public override Type UnderlyingSystemType {
-                       get { return TypeManager.object_type; }
-               }
-
-               public override object[] GetCustomAttributes (Type attributeType, bool inherit)
-               {
-                       return new object [0];
-               }
-
-               public override object[] GetCustomAttributes (bool inherit)
-               {
-                       return new object [0];
-               }
-
-               public override bool IsDefined (Type attributeType, bool inherit)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override string Name {
-                       get { return UnderlyingSystemType.Name; }
-               }
-
-               public override string ToString ()
-               {
-                       return UnderlyingSystemType.ToString ();
-               }
-
-               public override RuntimeTypeHandle TypeHandle {
-                       get { return UnderlyingSystemType.TypeHandle; }
-               }
-
-               public override Type MakeByRefType ()
-               {
-                       // TODO: Wrong, hides dynamic type
-                       return UnderlyingSystemType.MakeByRefType ();
-               }
-       }
-
-#if NET_4_0 || MS_COMPATIBLE
-       [System.Diagnostics.DebuggerDisplay ("Dynamic array type")]
-#endif
-       class DynamicArrayType : Type
-       {
-               readonly int rank;
-               Type reflection_type;
-
-               public DynamicArrayType (int rank)
-               {
-                       this.rank = rank;
-               }
-
-               public override Assembly Assembly {
-                       get { return UnderlyingSystemType.Assembly; }
-               }
-
-               public override string AssemblyQualifiedName {
-                       get { throw new NotImplementedException (); }
-               }
-
-               public override Type BaseType {
-                       get { return TypeManager.array_type; }
-               }
-
-               public override string FullName {
-                       get { return UnderlyingSystemType.FullName; }
-               }
-
-               public override Guid GUID {
-                       get { throw new NotImplementedException (); }
-               }
-
-               protected override TypeAttributes GetAttributeFlagsImpl ()
-               {
-                       return UnderlyingSystemType.Attributes;
-               }
-
-               public override int GetArrayRank ()
-               {
-                       return rank;
-               }
-
-               protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type GetElementType ()
-               {
-                       return InternalType.Dynamic;
-               }
-
-               public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override EventInfo[] GetEvents (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override FieldInfo GetField (string name, BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override FieldInfo[] GetFields (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type GetInterface (string name, bool ignoreCase)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type[] GetInterfaces ()
-               {
-                       return Type.EmptyTypes;
-               }
-
-               public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override MethodInfo[] GetMethods (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type GetNestedType (string name, BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override Type[] GetNestedTypes (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override PropertyInfo[] GetProperties (BindingFlags bindingAttr)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override bool HasElementTypeImpl ()
-               {
-                       return true;
-               }
-
-               public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override bool IsArrayImpl ()
-               {
-                       return true;
-               }
-
-               protected override bool IsByRefImpl ()
-               {
-                       return false;
-               }
-
-               protected override bool IsCOMObjectImpl ()
-               {
-                       return false;
-               }
-
-               protected override bool IsPointerImpl ()
-               {
-                       return false;
-               }
-
-               protected override bool IsPrimitiveImpl ()
-               {
-                       return false;
-               }
-
-               public override Module Module {
-                       get { return UnderlyingSystemType.Module; }
-               }
-
-               public override string Namespace {
-                       get { return UnderlyingSystemType.Namespace; }
-               }
-
-               public override Type UnderlyingSystemType {
-                       get {
-                               if (reflection_type == null) {
-                                       reflection_type = rank == 1 ?
-                                               TypeManager.object_type.MakeArrayType () :
-                                               TypeManager.object_type.MakeArrayType (rank);
-                               }
-
-                               return reflection_type;
-                       }
-               }
-
-               public override object[] GetCustomAttributes (Type attributeType, bool inherit)
-               {
-                       return new object [0];
-               }
-
-               public override object[] GetCustomAttributes (bool inherit)
-               {
-                       return new object [0];
-               }
-
-               public override bool IsDefined (Type attributeType, bool inherit)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override string Name {
-                       get { return UnderlyingSystemType.Name; }
-               }
-
-               public override string ToString ()
-               {
-                       return UnderlyingSystemType.ToString ();
-               }
-
-               public override RuntimeTypeHandle TypeHandle {
-                       get { return UnderlyingSystemType.TypeHandle; }
-               }
-       }
-
        public class UnixUtils {
                [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
                extern static int _isatty (int fd);
index acdaff64e7c6b286082178617bebf8183885ffd9..5159f73d0bfa97257b8ddbb4a305a6a7123db94b 100644 (file)
@@ -181,50 +181,50 @@ namespace Mono.CSharp {
                                symwriter.DefineCapturedScope (scope_id, id, captured_name);
                }
 
-               public static void OpenCompilerGeneratedBlock (ILGenerator ig)
+               public static void OpenCompilerGeneratedBlock (EmitContext ec)
                {
                        if (symwriter != null) {
-                               int offset = symwriter.GetILOffset (ig);
+                               int offset = symwriter.GetILOffset (ec.ig);
                                symwriter.OpenCompilerGeneratedBlock (offset);
                        }
                }
 
-               public static void CloseCompilerGeneratedBlock (ILGenerator ig)
+               public static void CloseCompilerGeneratedBlock (EmitContext ec)
                {
                        if (symwriter != null) {
-                               int offset = symwriter.GetILOffset (ig);
+                               int offset = symwriter.GetILOffset (ec.ig);
                                symwriter.CloseCompilerGeneratedBlock (offset);
                        }
                }
 
-               public static void StartIteratorBody (ILGenerator ig)
+               public static void StartIteratorBody (EmitContext ec)
                {
                        if (symwriter != null) {
-                               int offset = symwriter.GetILOffset (ig);
+                               int offset = symwriter.GetILOffset (ec.ig);
                                symwriter.StartIteratorBody (offset);
                        }
                }
 
-               public static void EndIteratorBody (ILGenerator ig)
+               public static void EndIteratorBody (EmitContext ec)
                {
                        if (symwriter != null) {
-                               int offset = symwriter.GetILOffset (ig);
+                               int offset = symwriter.GetILOffset (ec.ig);
                                symwriter.EndIteratorBody (offset);
                        }
                }
 
-               public static void StartIteratorDispatcher (ILGenerator ig)
+               public static void StartIteratorDispatcher (EmitContext ec)
                {
                        if (symwriter != null) {
-                               int offset = symwriter.GetILOffset (ig);
+                               int offset = symwriter.GetILOffset (ec.ig);
                                symwriter.StartIteratorDispatcher (offset);
                        }
                }
 
-               public static void EndIteratorDispatcher (ILGenerator ig)
+               public static void EndIteratorDispatcher (EmitContext ec)
                {
                        if (symwriter != null) {
-                               int offset = symwriter.GetILOffset (ig);
+                               int offset = symwriter.GetILOffset (ec.ig);
                                symwriter.EndIteratorDispatcher (offset);
                        }
                }
index ddd960106782ca8df1a7426ae02332fdd0b4f422..a41f4d742e095353d0fe94942cece224fde4cf67 100644 (file)
 // Copyright 2003-2008 Novell, Inc.
 //
 
-//
-// We will eventually remove the SIMPLE_SPEEDUP, and should never change 
-// the behavior of the compilation.  This can be removed if we rework
-// the code to get a list of namespaces available.
-//
-#define SIMPLE_SPEEDUP
-
 using System;
 using System.IO;
 using System.Globalization;
@@ -27,6 +20,7 @@ using System.Reflection.Emit;
 using System.Text;
 using System.Runtime.CompilerServices;
 using System.Diagnostics;
+using System.Linq;
 
 namespace Mono.CSharp {
 
@@ -34,74 +28,75 @@ namespace Mono.CSharp {
        //
        // A list of core types that the compiler requires or uses
        //
-       static public Type object_type;
-       static public Type value_type;
-       static public Type string_type;
-       static public Type int32_type;
-       static public Type uint32_type;
-       static public Type int64_type;
-       static public Type uint64_type;
-       static public Type float_type;
-       static public Type double_type;
-       static public Type char_type;
-       static public Type short_type;
-       static public Type decimal_type;
-       static public Type bool_type;
-       static public Type sbyte_type;
-       static public Type byte_type;
-       static public Type ushort_type;
-       static public Type enum_type;
-       static public Type delegate_type;
-       static public Type multicast_delegate_type;
-       static public Type void_type;
-       static public Type null_type;
-       static public Type array_type;
-       static public Type runtime_handle_type;
-       static public Type type_type;
-       static public Type ienumerator_type;
-       static public Type ienumerable_type;
-       static public Type idisposable_type;
-       static public Type iasyncresult_type;
-       static public Type asynccallback_type;
-       static public Type intptr_type;
-       static public Type uintptr_type;
-       static public Type runtime_field_handle_type;
-       static public Type runtime_argument_handle_type;
-       static public Type attribute_type;
-       static public Type void_ptr_type;
-       static public Type exception_type;
-
-       static public Type typed_reference_type;
-       static public Type arg_iterator_type;
-       static public Type mbr_type;
-       public static Type runtime_helpers_type;
+       static public PredefinedTypeSpec object_type;
+       static public PredefinedTypeSpec value_type;
+       static public PredefinedTypeSpec string_type;
+       static public PredefinedTypeSpec int32_type;
+       static public PredefinedTypeSpec uint32_type;
+       static public PredefinedTypeSpec int64_type;
+       static public PredefinedTypeSpec uint64_type;
+       static public PredefinedTypeSpec float_type;
+       static public PredefinedTypeSpec double_type;
+       static public PredefinedTypeSpec char_type;
+       static public PredefinedTypeSpec short_type;
+       static public PredefinedTypeSpec decimal_type;
+       static public PredefinedTypeSpec bool_type;
+       static public PredefinedTypeSpec sbyte_type;
+       static public PredefinedTypeSpec byte_type;
+       static public PredefinedTypeSpec ushort_type;
+       static public PredefinedTypeSpec enum_type;
+       static public PredefinedTypeSpec delegate_type;
+       static public PredefinedTypeSpec multicast_delegate_type;
+       static public PredefinedTypeSpec void_type;
+       static public PredefinedTypeSpec array_type;
+       static public PredefinedTypeSpec runtime_handle_type;
+       static public PredefinedTypeSpec type_type;
+       static public PredefinedTypeSpec ienumerator_type;
+       static public PredefinedTypeSpec ienumerable_type;
+       static public PredefinedTypeSpec idisposable_type;
+       static public PredefinedTypeSpec intptr_type;
+       static public PredefinedTypeSpec uintptr_type;
+       static public PredefinedTypeSpec runtime_field_handle_type;
+       static public PredefinedTypeSpec attribute_type;
+       static public PredefinedTypeSpec exception_type;
+
+
+       static public TypeSpec null_type;
+       static public TypeSpec typed_reference_type;
+       static public TypeSpec arg_iterator_type;
+       static public TypeSpec mbr_type;
+       public static TypeSpec runtime_helpers_type;
+       static public TypeSpec iasyncresult_type;
+       static public TypeSpec asynccallback_type;
+       static public TypeSpec runtime_argument_handle_type;
+       static public TypeSpec void_ptr_type;
 
        // 
        // C# 2.0
        //
-       static internal Type isvolatile_type;
-       static public Type generic_ilist_type;
-       static public Type generic_icollection_type;
-       static public Type generic_ienumerator_type;
-       static public Type generic_ienumerable_type;
-       static public Type generic_nullable_type;
+       static internal TypeSpec isvolatile_type;
+       static public TypeSpec generic_ilist_type;
+       static public TypeSpec generic_icollection_type;
+       static public TypeSpec generic_ienumerator_type;
+       static public TypeSpec generic_ienumerable_type;
+       static public TypeSpec generic_nullable_type;
 
        //
        // C# 3.0
        //
-       static internal Type expression_type;
-       public static Type parameter_expression_type;
-       public static Type fieldinfo_type;
-       public static Type methodinfo_type;
-       public static Type ctorinfo_type;
+       static internal TypeSpec expression_type;
+       public static TypeSpec parameter_expression_type;
+       public static TypeSpec fieldinfo_type;
+       public static TypeSpec methodinfo_type;
+       public static TypeSpec ctorinfo_type;
 
        //
        // C# 4.0
        //
-       public static Type call_site_type;
-       public static Type generic_call_site_type;
+       public static TypeSpec call_site_type;
+       public static TypeSpec generic_call_site_type;
        public static TypeExpr binder_type;
-       public static Type binder_flags;
+       public static TypeSpec binder_flags;
 
        // 
        // Expressions representing the internal types.  Used during declaration
@@ -116,14 +111,13 @@ namespace Mono.CSharp {
        static public TypeExpr system_int64_expr, system_uint64_expr;
        static public TypeExpr system_char_expr, system_void_expr;
        static public TypeExpr system_valuetype_expr;
-       static public TypeExpr system_intptr_expr;
        public static TypeExpr expression_type_expr;
 
 
        //
        // These methods are called by code generated by the compiler
        //
-       static public FieldInfo string_empty;
+       static public FieldSpec string_empty;
        static public MethodSpec system_type_get_type_from_handle;
        static public MethodSpec bool_movenext_void;
        static public MethodSpec void_dispose_void;
@@ -144,93 +138,35 @@ namespace Mono.CSharp {
        //
        // The constructors.
        //
-       static public ConstructorInfo void_decimal_ctor_five_args;
-       static public ConstructorInfo void_decimal_ctor_int_arg;
-       public static ConstructorInfo void_decimal_ctor_long_arg;
-
-       static Dictionary<TypeBuilder, DeclSpace> builder_to_declspace;
-
-       static Dictionary<Type, MemberCache> builder_to_member_cache;
-
-       // <remarks>
-       //   Tracks the interfaces implemented by typebuilders.  We only
-       //   enter those who do implement or or more interfaces
-       // </remarks>
-       static Dictionary<Type, Type[]> builder_to_ifaces;
-
-       // <remarks>
-       //   Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters)
-       // <remarks>
-       static Dictionary<MemberInfo, AParametersCollection> method_params;
-
-       // <remarks>
-       //  A hash table from override methods to their base virtual method.
-       // <remarks>
-       static Dictionary<MethodBase, MethodBase> method_overrides;
-
-       // <remarks>
-       //  Keeps track of methods
-       // </remarks>
-
-       static Dictionary<MethodBase, IMethodData> builder_to_method;
-
-       // <remarks>
-       //  Contains all public types from referenced assemblies.
-       //  This member is used only if CLS Compliance verification is required.
-       // </remarks>
-       public static Dictionary<string, object> AllClsTopLevelTypes;
-
-       static Dictionary<FieldInfo, FieldBase> fieldbuilders_to_fields;
-       static Dictionary<PropertyInfo, PropertyBase> propertybuilder_to_property;
-       static Dictionary<FieldInfo, ConstSpec> fields;
-       static Dictionary<EventInfo, EventSpec> events;
-       static Dictionary<Assembly, bool> assembly_internals_vis_attrs;
-       static Dictionary<GenericTypeParameterBuilder, TypeParameter> builder_to_type_param;
-       static Dictionary<Type, Type[]> iface_cache;
+       static public MethodSpec void_decimal_ctor_five_args;
+       static public MethodSpec void_decimal_ctor_int_arg;
+       public static MethodSpec void_decimal_ctor_long_arg;
 
-       public static void CleanUp ()
-       {
-               // Lets get everything clean so that we can collect before generating code
-               builder_to_declspace = null;
-               builder_to_member_cache = null;
-               builder_to_ifaces = null;
-               builder_to_type_param = null;
-               method_params = null;
-               builder_to_method = null;
-               iface_cache = null;
-               
-               fields = null;
-               events = null;
-               type_hash = null;
-               propertybuilder_to_property = null;
-
-               TypeHandle.CleanUp ();
-       }
+       static Dictionary<Assembly, bool> assembly_internals_vis_attrs;
 
        //
        // These are expressions that represent some of the internal data types, used
        // elsewhere
        //
-       static void InitExpressionTypes ()
-       {
-               system_object_expr  = new TypeLookupExpression ("System", "Object");
-               system_string_expr  = new TypeLookupExpression ("System", "String");
-               system_boolean_expr = new TypeLookupExpression ("System", "Boolean");
-               system_decimal_expr = new TypeLookupExpression ("System", "Decimal");
-               system_single_expr  = new TypeLookupExpression ("System", "Single");
-               system_double_expr  = new TypeLookupExpression ("System", "Double");
-               system_sbyte_expr   = new TypeLookupExpression ("System", "SByte");
-               system_byte_expr    = new TypeLookupExpression ("System", "Byte");
-               system_int16_expr   = new TypeLookupExpression ("System", "Int16");
-               system_uint16_expr  = new TypeLookupExpression ("System", "UInt16");
-               system_int32_expr   = new TypeLookupExpression ("System", "Int32");
-               system_uint32_expr  = new TypeLookupExpression ("System", "UInt32");
-               system_int64_expr   = new TypeLookupExpression ("System", "Int64");
-               system_uint64_expr  = new TypeLookupExpression ("System", "UInt64");
-               system_char_expr    = new TypeLookupExpression ("System", "Char");
-               system_void_expr    = new TypeLookupExpression ("System", "Void");
-               system_valuetype_expr  = new TypeLookupExpression ("System", "ValueType");
-               system_intptr_expr  = new TypeLookupExpression ("System", "IntPtr");
+       public static void InitExpressionTypes ()
+       {
+               system_object_expr  = new TypeLookupExpression (object_type);
+               system_string_expr  = new TypeLookupExpression (string_type);
+               system_boolean_expr = new TypeLookupExpression (bool_type);
+               system_decimal_expr = new TypeLookupExpression (decimal_type);
+               system_single_expr  = new TypeLookupExpression (float_type);
+               system_double_expr  = new TypeLookupExpression (double_type);
+               system_sbyte_expr   = new TypeLookupExpression (sbyte_type);
+               system_byte_expr    = new TypeLookupExpression (byte_type);
+               system_int16_expr   = new TypeLookupExpression (short_type);
+               system_uint16_expr  = new TypeLookupExpression (ushort_type);
+               system_int32_expr   = new TypeLookupExpression (int32_type);
+               system_uint32_expr  = new TypeLookupExpression (uint32_type);
+               system_int64_expr   = new TypeLookupExpression (int64_type);
+               system_uint64_expr  = new TypeLookupExpression (uint64_type);
+               system_char_expr    = new TypeLookupExpression (char_type);
+               system_void_expr    = new TypeLookupExpression (void_type);
+               system_valuetype_expr  = new TypeLookupExpression (value_type);
        }
 
        static TypeManager ()
@@ -240,28 +176,11 @@ namespace Mono.CSharp {
 
        static public void Reset ()
        {
-               object_type = null;
-
-               InitExpressionTypes ();
-               
-               builder_to_declspace = new Dictionary<TypeBuilder, DeclSpace> (ReferenceEquality<TypeBuilder>.Default);
-               builder_to_member_cache = new Dictionary<Type, MemberCache> (ReferenceEquality<Type>.Default);
-               builder_to_method = new Dictionary<MethodBase, IMethodData> (ReferenceEquality<MethodBase>.Default);
-               builder_to_type_param = new Dictionary<GenericTypeParameterBuilder, TypeParameter> (ReferenceEquality<GenericTypeParameterBuilder>.Default);
-               method_params = new Dictionary<MemberInfo, AParametersCollection> (ReferenceEquality<MemberInfo>.Default);
-               method_overrides = new Dictionary<MethodBase, MethodBase> (ReferenceEquality<MethodBase>.Default);
-               builder_to_ifaces = new Dictionary<Type, Type[]> (ReferenceEquality<Type>.Default);
-
-               fieldbuilders_to_fields = new Dictionary<FieldInfo, FieldBase> (ReferenceEquality<FieldInfo>.Default);
-               propertybuilder_to_property = new Dictionary<PropertyInfo, PropertyBase> (ReferenceEquality<PropertyInfo>.Default);
-               fields = new Dictionary<FieldInfo, ConstSpec> (ReferenceEquality<FieldInfo>.Default);
+//             object_type = null;
+       
                type_hash = new DoubleHash ();
                assembly_internals_vis_attrs = new Dictionary<Assembly, bool> ();
-               iface_cache = new Dictionary<Type, Type[]> (ReferenceEquality<Type>.Default);
                
-               closure = new Closure ();
-               FilterWithClosure_delegate = new MemberFilter (closure.Filter);
-
                // TODO: I am really bored by all this static stuff
                system_type_get_type_from_handle =
                bool_movenext_void =
@@ -285,7 +204,7 @@ namespace Mono.CSharp {
                void_decimal_ctor_int_arg =
                void_decimal_ctor_long_arg = null;
 
-               isvolatile_type = null;
+               string_empty = null;
 
                call_site_type =
                generic_call_site_type =
@@ -293,112 +212,14 @@ namespace Mono.CSharp {
 
                binder_type = null;
 
-               // to uncover regressions
-               AllClsTopLevelTypes = null;
-       }
-
-       public static void AddUserType (DeclSpace ds)
-       {
-               builder_to_declspace.Add (ds.TypeBuilder, ds);
-       }
-
-       //
-       // This entry point is used by types that we define under the covers
-       // 
-       public static void RegisterBuilder (Type tb, Type [] ifaces)
-       {
-               if (ifaces != null)
-                       builder_to_ifaces [tb] = ifaces;
-       }       
-
-       public static void AddMethod (MethodBase builder, IMethodData method)
-       {
-               builder_to_method.Add (builder, method);
-               method_params.Add (builder, method.ParameterInfo);
-       }
-
-       public static IMethodData GetMethod (MethodBase builder)
-       {
-               IMethodData md;
-               if (builder_to_method.TryGetValue (builder, out md))
-                       return md;
-               return null;
-       }
-
-       /// <summary>
-       ///   Returns the DeclSpace whose Type is `t' or null if there is no
-       ///   DeclSpace for `t' (ie, the Type comes from a library)
-       /// </summary>
-       public static DeclSpace LookupDeclSpace (Type t)
-       {
-               DeclSpace ds;
-               var tb = t as TypeBuilder;
-               if (tb != null && builder_to_declspace.TryGetValue (tb, out ds))
-                       return ds;
-
-               return null;
-       }
-
-       /// <summary>
-       ///   Returns the TypeContainer whose Type is `t' or null if there is no
-       ///   TypeContainer for `t' (ie, the Type comes from a library)
-       /// </summary>
-       public static TypeContainer LookupTypeContainer (Type t)
-       {
-               return LookupDeclSpace (t) as TypeContainer;
-       }
-
-       public static MemberCache LookupMemberCache (Type t)
-       {
-               if (IsBeingCompiled (t)) {
-                       DeclSpace container = LookupDeclSpace (t);
-                       if (container != null)
-                               return container.MemberCache;
-               }
-
-               if (t is GenericTypeParameterBuilder) {
-                       TypeParameter container;
-                       if (builder_to_type_param.TryGetValue ((GenericTypeParameterBuilder) t, out container))
-                               return container.MemberCache;
-               }
-
-               return TypeHandle.GetMemberCache (t);
-       }
-
-       public static MemberCache LookupBaseInterfacesCache (Type t)
-       {
-               Type [] ifaces = GetInterfaces (t);
-
-               if (ifaces != null && ifaces.Length == 1)
-                       return LookupMemberCache (ifaces [0]);
-
-               // TODO: the builder_to_member_cache should be indexed by 'ifaces', not 't'
-               MemberCache cache;
-               if (builder_to_member_cache.TryGetValue (t, out cache))
-                       return cache;
-
-               cache = new MemberCache (ifaces);
-               builder_to_member_cache.Add (t, cache);
-               return cache;
-       }
-
-       public static TypeContainer LookupInterface (Type t)
-       {
-               TypeContainer tc = LookupTypeContainer (t);
-               if ((tc == null) || (tc.Kind != MemberKind.Interface))
-                       return null;
-
-               return tc;
-       }
+               typed_reference_type = arg_iterator_type = mbr_type =
+               runtime_helpers_type = iasyncresult_type = asynccallback_type =
+               runtime_argument_handle_type = void_ptr_type = isvolatile_type =
+               generic_ilist_type = generic_icollection_type = generic_ienumerator_type =
+               generic_ienumerable_type = generic_nullable_type = expression_type =
+               parameter_expression_type = fieldinfo_type = methodinfo_type = ctorinfo_type = null;
 
-       public static Delegate LookupDelegate (Type t)
-       {
-               return LookupDeclSpace (t) as Delegate;
-       }
-
-       public static Class LookupClass (Type t)
-       {
-               return LookupDeclSpace (t) as Class;
+               expression_type_expr = null;
        }
 
        //
@@ -416,466 +237,120 @@ namespace Mono.CSharp {
        //
        // Gets the reference to T version of the Type (T&)
        //
-       public static Type GetReferenceType (Type t)
+       public static Type GetReferenceType (TypeSpec t)
        {
-               return t.MakeByRefType ();
+               return t.GetMetaInfo ().MakeByRefType ();
        }
 
-       //
-       // Gets the pointer to T version of the Type  (T*)
-       //
-       public static Type GetPointerType (Type t)
-       {
-               return GetConstructedType (t, "*");
-       }
-
-       public static Type GetConstructedType (Type t, string dim)
+       public static TypeSpec GetConstructedType (TypeSpec t, string dim)
        {
                object ret = null;
                if (type_hash.Lookup (t, dim, out ret))
-                       return (Type) ret;
-
-               if (IsDynamicType (t)) {
-                       ret = new DynamicArrayType (dim.Length - 1);
-                       type_hash.Insert (t, dim, ret);
-                       return (Type) ret;
-               }
-
-               ret = t.Module.GetType (t.ToString () + dim);
-               if (ret != null) {
-                       type_hash.Insert (t, dim, ret);
-                       return (Type) ret;
-               }
-
-               if (dim == "&") {
-                       ret = GetReferenceType (t);
-                       type_hash.Insert (t, dim, ret);
-                       return (Type) ret;
-               }
-
-               if (t.IsGenericParameter || t.IsGenericType) {
-                       int pos = 0;
-                       Type result = t;
-                       while ((pos < dim.Length) && (dim [pos] == '[')) {
-                               pos++;
-
-                               if (dim [pos] == ']') {
-                                       result = result.MakeArrayType ();
-                                       pos++;
-
-                                       if (pos < dim.Length)
-                                               continue;
-
-                                       type_hash.Insert (t, dim, result);
-                                       return result;
-                               }
-
-                               int rank = 0;
-                               while (dim [pos] == ',') {
-                                       pos++; rank++;
-                               }
-
-                               if ((dim [pos] != ']') || (pos != dim.Length-1))
-                                       break;
-
-                               result = result.MakeArrayType (rank + 1);
-                               type_hash.Insert (t, dim, result);
-                               return result;
+                       return (TypeSpec) ret;
+
+               TypeSpec ds;
+               if (dim.Length == 1) {
+                       if (dim[0] == '*') {
+                               ds = PointerContainer.MakeType (t);
+                       } else if (dim[0] == '&') {
+                               ds = ReferenceContainer.MakeType (t);
+                       } else {
+                               throw new NotImplementedException ("net");
                        }
-               }
-
-               type_hash.Insert (t, dim, null);
-               return null;
-       }
+               } else if (dim.Length == 2) {   // optimizes common "[]"
+                       ds = ArrayContainer.MakeType (t);
+               } else {
+                       int rank = dim.IndexOf (']');
+                       if (rank + 1 != dim.Length)
+                               t = GetConstructedType (t, dim.Substring (rank + 1));
 
-       public static Type GetNestedType (Type t, string name)
-       {
-               object ret = null;
-               if (!type_hash.Lookup (t, name, out ret)) {
-                       ret = t.GetNestedType (name,
-                              BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
-                       type_hash.Insert (t, name, ret);
+                       ds = ArrayContainer.MakeType (t, rank);
                }
-               return (Type) ret;
-       }
 
-       /// <summary>
-       /// Fills static table with exported types from all referenced assemblies.
-       /// This information is required for CLS Compliance tests.
-       /// </summary>
-       public static void LoadAllImportedTypes ()
-       {
-               AllClsTopLevelTypes = new Dictionary<string, object> (1500);
-               foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
-                       foreach (Type t in a.GetExportedTypes ()) {
-                               AllClsTopLevelTypes [t.FullName.ToLower (System.Globalization.CultureInfo.InvariantCulture)] = null;
-                       }
-               }
+               type_hash.Insert (t, dim, ds);
+               return ds;
        }
 
        /// <summary>
        ///   Returns the C# name of a type if possible, or the full type name otherwise
        /// </summary>
-       static public string CSharpName (Type t)
-       {
-               if (t == null_type)
-                       return "null";
-
-               if (t == typeof (ArglistAccess))
-                       return "__arglist";
-                       
-               if (t == typeof (AnonymousMethodBody))
-                       return "anonymous method";
-
-               if (t == typeof (MethodGroupExpr))
-                       return "method group";
-
-               if (IsDynamicType (t))
-                       return "dynamic";
-
-               if (t == null)
-                       return "internal error";
-
-               return CSharpName (GetFullName (t), t);
-       }
-
-       static readonly char [] elements = new char [] { '*', '[' };
-
-       public static string CSharpName (string name, Type type)
+       static public string CSharpName (TypeSpec t)
        {
-               if (name.Length > 10) {
-                       string s;
-                       switch (name) {
-                       case "System.Int32": s = "int"; break;
-                       case "System.Int64": s = "long"; break;
-                       case "System.String": s = "string"; break;
-                       case "System.Boolean": s = "bool"; break;
-                       case "System.Void": s = "void"; break;
-                       case "System.Object": s = "object"; break;
-                       case "System.UInt32": s = "uint"; break;
-                       case "System.Int16": s = "short"; break;
-                       case "System.UInt16": s = "ushort"; break;
-                       case "System.UInt64": s = "ulong"; break;
-                       case "System.Single": s = "float"; break;
-                       case "System.Double": s = "double"; break;
-                       case "System.Decimal": s = "decimal"; break;
-                       case "System.Char": s = "char"; break;
-                       case "System.Byte": s = "byte"; break;
-                       case "System.SByte": s = "sbyte"; break;
-                       default: s = null; break;
-                       }
-
-                       if (s != null) {
-                               //
-                               // Predefined names can come from mscorlib only
-                               //
-                               if (type == null || type.Module.Name == "mscorlib.dll" || !RootContext.StdLib)
-                                       return s;
-                                       
-                               return name;
-                       }
-
-                       if (name [0] == AnonymousTypeClass.ClassNamePrefix [0] && name.StartsWith (AnonymousTypeClass.ClassNamePrefix))
-                               return AnonymousTypeClass.SignatureForError;
-
-                       int idx = name.IndexOfAny (elements, 10);
-                       if (idx > 0)
-                               return CSharpName (name.Substring (0, idx), type) + name.Substring (idx);
-               }
-
-               return name.Replace ('+', '.');
+               return t.GetSignatureForError ();
        }
 
-       static public string CSharpName (Type[] types)
+       static public string CSharpName (IList<TypeSpec> types)
        {
-               if (types.Length == 0)
+               if (types.Count == 0)
                        return string.Empty;
 
                StringBuilder sb = new StringBuilder ();
-               for (int i = 0; i < types.Length; ++i) {
+               for (int i = 0; i < types.Count; ++i) {
                        if (i > 0)
-                               sb.Append (", ");
+                               sb.Append (",");
 
                        sb.Append (CSharpName (types [i]));
                }
                return sb.ToString ();
        }
 
-       /// <summary>
-       ///  Returns the signature of the method with full namespace classification
-       /// </summary>
-       static public string GetFullNameSignature (MemberInfo mi)
-       {
-               PropertyInfo pi = mi as PropertyInfo;
-               if (pi != null) {
-                       MethodBase pmi = pi.GetGetMethod (true);
-                       if (pmi == null)
-                               pmi = pi.GetSetMethod (true);
-                       if (GetParameterData (pmi).Count > 0)
-                               mi = pmi;
-               }
-               return (mi is MethodBase)
-                       ? CSharpSignature (mi as MethodBase) 
-                       : CSharpName (mi.DeclaringType) + '.' + mi.Name;
-       }
-
-       private static int GetFullName (Type t, StringBuilder sb)
-       {
-               int pos = 0;
-
-               if (!t.IsGenericType) {
-                       sb.Append (t.FullName);
-                       return 0;
-               }
-
-               if (t.DeclaringType != null) {
-                       pos = GetFullName (t.DeclaringType, sb);
-                       sb.Append ('.');
-               } else if (t.Namespace != null && t.Namespace.Length != 0) {
-                       sb.Append (t.Namespace);
-                       sb.Append ('.');
-               }
-               sb.Append (RemoveGenericArity (t.Name));
-
-               Type[] this_args = GetTypeArguments (t);
-
-               if (this_args.Length < pos)
-                       throw new InternalErrorException (
-                               "Enclosing class " + t.DeclaringType + " has more type arguments than " + t);
-               if (this_args.Length == pos)
-                       return pos;
-
-               sb.Append ('<');
-               for (;;) {
-                       sb.Append (CSharpName (this_args [pos++]));
-                       if (pos == this_args.Length)
-                               break;
-                       sb.Append (',');
-               }
-               sb.Append ('>');
-               return pos;
-       }
-
-       static string GetFullName (Type t)
-       {
-               if (t.IsArray) {
-                       string dimension = t.Name.Substring (t.Name.LastIndexOf ('['));
-                       return GetFullName (GetElementType (t)) + dimension;
-               }
-
-               if (IsNullableType (t) && !t.IsGenericTypeDefinition) {
-                       t = TypeToCoreType (GetTypeArguments (t)[0]);
-                       return CSharpName (t) + "?";
-               }
-
-               if (t.IsGenericParameter)
-                       return t.Name;
-               if (!t.IsGenericType)
-                       return t.FullName;
-
-               StringBuilder sb = new StringBuilder ();
-               int pos = GetFullName (t, sb);
-               if (pos <= 0)
-                       throw new InternalErrorException ("Generic Type " + t + " doesn't have type arguments");
-               return sb.ToString ();
-       }
-
-       public static string RemoveGenericArity (string from)
-       {
-               int i = from.IndexOf ('`');
-               if (i > 0)
-                       return from.Substring (0, i);
-               return from;
-       }
-
-       /// <summary>
-       /// When we need to report accessors as well
-       /// </summary>
-       static public string CSharpSignature (MethodBase mb)
-       {
-               return CSharpSignature (mb, false);
-       }
-
-       static public string CSharpSignature (MethodSpec ms)
-       {
-               return CSharpSignature (ms.MetaInfo);
-       }
-
-       /// <summary>
-       ///   Returns the signature of the method
-       /// </summary>
-       static public string CSharpSignature (MethodBase mb, bool show_accessor)
-       {
-               StringBuilder sig = new StringBuilder (CSharpName (mb.DeclaringType));
-               sig.Append ('.');
-
-               AParametersCollection iparams = GetParameterData (mb);
-               string parameters = iparams.GetSignatureForError ();
-               int accessor_end = 0;
-
-               if (!mb.IsConstructor && TypeManager.IsSpecialMethod (mb)) {
-                       string op_name = Operator.GetName (mb.Name);
-                       if (op_name != null) {
-                               if (op_name == "explicit" || op_name == "implicit") {
-                                       sig.Append (op_name);
-                                       sig.Append (" operator ");
-                                       sig.Append (CSharpName (((MethodInfo)mb).ReturnType));
-                               } else {
-                                       sig.Append ("operator ");
-                                       sig.Append (op_name);
-                               }
-                               sig.Append (parameters);
-                               return sig.ToString ();
-                       }
-
-                       bool is_getter = mb.Name.StartsWith ("get_");
-                       bool is_setter = mb.Name.StartsWith ("set_");
-                       if (is_getter || is_setter || mb.Name.StartsWith ("add_")) {
-                               accessor_end = 3;
-                       } else if (mb.Name.StartsWith ("remove_")) {
-                               accessor_end = 6;
-                       }
-
-                       // Is indexer
-                       if (iparams.Count > (is_getter ? 0 : 1)) {
-                               sig.Append ("this[");
-                               if (is_getter)
-                                       sig.Append (parameters.Substring (1, parameters.Length - 2));
-                               else
-                                       sig.Append (parameters.Substring (1, parameters.LastIndexOf (',') - 1));
-                               sig.Append (']');
-                       } else {
-                               sig.Append (mb.Name.Substring (accessor_end + 1));
-                       }
-               } else {
-                       if (mb.Name == ".ctor")
-                               sig.Append (RemoveGenericArity (mb.DeclaringType.Name));
-                       else {
-                               sig.Append (mb.Name);
-
-                               if (IsGenericMethod (mb)) {
-                                       Type[] args = GetGenericArguments (mb);
-                                       sig.Append ('<');
-                                       for (int i = 0; i < args.Length; i++) {
-                                               if (i > 0)
-                                                       sig.Append (',');
-                                               sig.Append (CSharpName (args [i]));
-                                       }
-                                       sig.Append ('>');
-                               }
-                       }
-
-                       sig.Append (parameters);
-               }
-
-               if (show_accessor && accessor_end > 0) {
-                       sig.Append ('.');
-                       sig.Append (mb.Name.Substring (0, accessor_end));
-               }
-
-               return sig.ToString ();
-       }
-
-       public static string GetMethodName (MethodInfo m)
+       static public string GetFullNameSignature (MemberSpec mi)
        {
-               if (!IsGenericMethodDefinition (m) && !IsGenericMethod (m))
-                       return m.Name;
-
-               return MemberName.MakeName (m.Name, TypeManager.GetGenericArguments (m).Length);
+               return mi.GetSignatureForError ();
        }
 
-       static public string CSharpSignature (EventInfo ei)
+       static public string CSharpSignature (MemberSpec mb)
        {
-               return CSharpName (ei.DeclaringType) + "." + ei.Name;
+               return mb.GetSignatureForError ();
        }
 
        //
        // Looks up a type, and aborts if it is not found.  This is used
        // by predefined types required by the compiler
        //
-       public static Type CoreLookupType (CompilerContext ctx, string ns_name, string name, MemberKind type_kind, bool required)
+       public static TypeSpec CoreLookupType (CompilerContext ctx, string ns_name, string name, MemberKind kind, bool required)
+       {
+               return CoreLookupType (ctx, ns_name, name, 0, kind, required);
+       }
+
+       public static TypeSpec CoreLookupType (CompilerContext ctx, string ns_name, string name, int arity, MemberKind kind, bool required)
        {
                Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, true);
-               Expression expr = ns.Lookup (ctx, name, Location.Null);
+               var te = ns.Lookup (ctx, name, arity, Location.Null);
+               var ts = te == null ? null : te.Type;
 
-               if (expr == null) {
-                       if (required) {
-                               ctx.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported",
-                                       ns_name, name);
-                       }
+               if (!required)
+                       return ts;
+
+               if (ts == null) {
+                       ctx.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported",
+                               ns_name, name);
                        return null;
                }
 
-               Type t = expr.Type;
-               if (RootContext.StdLib || t == null || !required)
-                       return t;
-
-               // TODO: All predefined imported types have to have correct signature
-               if (!IsBeingCompiled (t))
-                       return t;
-
-               DeclSpace ds = (DeclSpace)RootContext.ToplevelTypes.GetDefinition (t.FullName);
-               if (ds is Delegate) {
-                       if (type_kind == MemberKind.Delegate)
-                               return t;
-               } else {
-                       TypeContainer tc = (TypeContainer)ds;
-                       if (tc.Kind == type_kind)
-                               return t;
+               if (ts.Kind != kind) {
+                       ctx.Report.Error (520, "The predefined type `{0}.{1}' is not declared correctly",
+                               ns_name, name);
+                       return null;
                }
 
-               ctx.Report.Error (520, ds.Location, "The predefined type `{0}.{1}' is not declared correctly",
-                       ns_name, name);
-               return null;
+               return ts;
        }
 
-       static MemberInfo GetPredefinedMember (Type t, string name, MemberTypes mt, Location loc, params Type [] args)
+       static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, Location loc)
        {
-               const BindingFlags flags = instance_and_static | BindingFlags.Public | BindingFlags.DeclaredOnly;
-
-               MemberInfo [] members = MemberLookup (null, null, t, mt, flags, name, null);
-               if (members != null) {
-                       for (int i = 0; i < members.Length; ++i) {
-                               MemberInfo member = members [i];
-                               if (mt == MemberTypes.Method || mt == MemberTypes.Constructor) {
-                                       MethodBase mb = member as MethodBase;
-                                       if (mb == null)
-                                               continue;
-
-                                       AParametersCollection pd = TypeManager.GetParameterData (mb);
-                                       if (IsEqual (pd.Types, args))
-                                               return member;
-                               }
-                               if (mt == MemberTypes.Field) {
-                                       FieldInfo fi = member as FieldInfo;
-                                       if (fi == null)
-                                               continue;
-
-                                       if (args.Length >= 1 && !IsEqual (TypeToCoreType (fi.FieldType), args [0]))
-                                               continue;
-
-                                       return member;
-                               }
-
-                               if (mt == MemberTypes.Property) {
-                                       PropertyInfo pi = member as PropertyInfo;
-                                       if (pi == null)
-                                               continue;
+               const BindingRestriction restrictions = BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly;
+               var member = MemberCache.FindMember (t, filter, restrictions);
 
-                                       if (args.Length >= 1 && !IsEqual (TypeToCoreType (pi.PropertyType), args [0]))
-                                               continue;
-
-                                       return member;
-                               }
-                       }
-               }
+               if (member != null)
+                       return member;
 
                string method_args = null;
-               if (mt == MemberTypes.Method || mt == MemberTypes.Constructor)
-                       method_args = "(" + TypeManager.CSharpName (args) + ")";
+               if (filter.Parameters != null)
+                       method_args = filter.Parameters.GetSignatureForError ();
 
                RootContext.ToplevelTypes.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
-                       TypeManager.CSharpName (t), name, method_args);
+                       TypeManager.CSharpName (t), filter.Name, method_args);
 
                return null;
        }
@@ -883,35 +358,78 @@ namespace Mono.CSharp {
        //
        // Returns the ConstructorInfo for "args"
        //
-       public static ConstructorInfo GetPredefinedConstructor (Type t, Location loc, params Type [] args)
+       public static MethodSpec GetPredefinedConstructor (TypeSpec t, Location loc, params TypeSpec [] args)
        {
-               return (ConstructorInfo) GetPredefinedMember (t, ConstructorInfo.ConstructorName, MemberTypes.Constructor, loc, args);
+               var pc = ParametersCompiled.CreateFullyResolved (args);
+               return GetPredefinedMember (t, MemberFilter.Constructor (pc), loc) as MethodSpec;
        }
 
        //
-       // Returns the MethodInfo for a method named `name' defined
+       // Returns the method specification for a method named `name' defined
        // in type `t' which takes arguments of types `args'
        //
-       public static MethodSpec GetPredefinedMethod (Type t, string name, Location loc, params Type [] args)
+       public static MethodSpec GetPredefinedMethod (TypeSpec t, string name, Location loc, params TypeSpec [] args)
        {
-               var m = GetPredefinedMember (t, name, MemberTypes.Method, loc, args) as MethodBase;
-               if (m == null)
-                       return null;
+               var pc = ParametersCompiled.CreateFullyResolved (args);
+               return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), loc);
+       }
 
-               return Import.CreateMethod (m);
+       public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, Location loc)
+       {
+               return GetPredefinedMember (t, filter, loc) as MethodSpec;
        }
 
-       public static FieldInfo GetPredefinedField (Type t, string name, Location loc, params Type [] args)
+       public static FieldSpec GetPredefinedField (TypeSpec t, string name, Location loc, TypeSpec type)
        {
-               return (FieldInfo) GetPredefinedMember (t, name, MemberTypes.Field, loc, args);
+               return GetPredefinedMember (t, MemberFilter.Field (name, type), loc) as FieldSpec;
        }
 
-       public static PropertySpec GetPredefinedProperty (Type t, string name, Location loc, params Type [] args)
+       public static PropertySpec GetPredefinedProperty (TypeSpec t, string name, Location loc, TypeSpec type)
        {
-               var p = GetPredefinedMember (t, name, MemberTypes.Property, loc, args) as PropertyInfo;
-               if (p == null)
-                       return null;
-               return Import.CreateProperty (p);
+               return GetPredefinedMember (t, MemberFilter.Property (name, type), loc) as PropertySpec;
+       }
+
+       public static IList<PredefinedTypeSpec> InitCoreTypes ()
+       {
+               var core_types = new PredefinedTypeSpec[] {
+                       object_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Object"),
+                       value_type = new PredefinedTypeSpec (MemberKind.Class, "System", "ValueType"),
+                       attribute_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Attribute"),
+
+                       int32_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Int32"),
+                       int64_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Int64"),
+                       uint32_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UInt32"),
+                       uint64_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UInt64"),
+                       byte_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Byte"),
+                       sbyte_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "SByte"),
+                       short_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Int16"),
+                       ushort_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UInt16"),
+
+                       ienumerator_type = new PredefinedTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator"),
+                       ienumerable_type = new PredefinedTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable"),
+                       idisposable_type = new PredefinedTypeSpec (MemberKind.Interface, "System", "IDisposable"),
+
+                       char_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Char"),
+                       string_type = new PredefinedTypeSpec (MemberKind.Class, "System", "String"),
+                       float_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Single"),
+                       double_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Double"),
+                       decimal_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Decimal"),
+                       bool_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Boolean"),
+                       intptr_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "IntPtr"),
+                       uintptr_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UIntPtr"),
+
+                       multicast_delegate_type = new PredefinedTypeSpec (MemberKind.Class, "System", "MulticastDelegate"),
+                       delegate_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Delegate"),
+                       enum_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Enum"),
+                       array_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Array"),
+                       void_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Void"),
+                       type_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Type"),
+                       exception_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Exception"),
+                       runtime_field_handle_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle"),
+                       runtime_handle_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle"),
+               };
+
+               return core_types;
        }
 
        /// <remarks>
@@ -919,66 +437,22 @@ namespace Mono.CSharp {
        ///   population of the type has happened (for example, to
        ///   bootstrap the corlib.dll
        /// </remarks>
-       public static bool InitCoreTypes (CompilerContext ctx)
+       public static bool InitCoreTypes (CompilerContext ctx, IList<PredefinedTypeSpec> predefined)
        {
-               object_type   = CoreLookupType (ctx, "System", "Object", MemberKind.Class, true);
-               system_object_expr.Type = object_type;
-               value_type    = CoreLookupType (ctx, "System", "ValueType", MemberKind.Class, true);
-               system_valuetype_expr.Type = value_type;
-               attribute_type = CoreLookupType (ctx, "System", "Attribute", MemberKind.Class, true);
-
-               int32_type    = CoreLookupType (ctx, "System", "Int32", MemberKind.Struct, true);
-               system_int32_expr.Type = int32_type;
-               int64_type    = CoreLookupType (ctx, "System", "Int64", MemberKind.Struct, true);
-               system_int64_expr.Type = int64_type;
-               uint32_type   = CoreLookupType (ctx, "System", "UInt32", MemberKind.Struct, true);
-               system_uint32_expr.Type = uint32_type;
-               uint64_type   = CoreLookupType (ctx, "System", "UInt64", MemberKind.Struct, true);
-               system_uint64_expr.Type = uint64_type;
-               byte_type     = CoreLookupType (ctx, "System", "Byte", MemberKind.Struct, true);
-               system_byte_expr.Type = byte_type;
-               sbyte_type    = CoreLookupType (ctx, "System", "SByte", MemberKind.Struct, true);
-               system_sbyte_expr.Type = sbyte_type;
-               short_type    = CoreLookupType (ctx, "System", "Int16", MemberKind.Struct, true);
-               system_int16_expr.Type = short_type;
-               ushort_type   = CoreLookupType (ctx, "System", "UInt16", MemberKind.Struct, true);
-               system_uint16_expr.Type = ushort_type;
-
-               ienumerator_type     = CoreLookupType (ctx, "System.Collections", "IEnumerator", MemberKind.Interface, true);
-               ienumerable_type     = CoreLookupType (ctx, "System.Collections", "IEnumerable", MemberKind.Interface, true);
-               idisposable_type     = CoreLookupType (ctx, "System", "IDisposable", MemberKind.Interface, true);
-
-               // HACK: DefineType immediately resolves iterators (very wrong)
-               generic_ienumerator_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerator`1", MemberKind.Interface, false);
-
-               char_type     = CoreLookupType (ctx, "System", "Char", MemberKind.Struct, true);
-               system_char_expr.Type = char_type;
-               string_type   = CoreLookupType (ctx, "System", "String", MemberKind.Class, true);
-               system_string_expr.Type = string_type;
-               float_type    = CoreLookupType (ctx, "System", "Single", MemberKind.Struct, true);
-               system_single_expr.Type = float_type;
-               double_type   = CoreLookupType (ctx, "System", "Double", MemberKind.Struct, true);
-               system_double_expr.Type = double_type;
-               decimal_type  = CoreLookupType (ctx, "System", "Decimal", MemberKind.Struct, true);
-               system_decimal_expr.Type = decimal_type;
-               bool_type     = CoreLookupType (ctx, "System", "Boolean", MemberKind.Struct, true);
-               system_boolean_expr.Type = bool_type;
-               intptr_type = CoreLookupType (ctx, "System", "IntPtr", MemberKind.Struct, true);
-               system_intptr_expr.Type = intptr_type;
-               uintptr_type = CoreLookupType (ctx, "System", "UIntPtr", MemberKind.Struct, true);
-
-               multicast_delegate_type = CoreLookupType (ctx, "System", "MulticastDelegate", MemberKind.Class, true);
-               delegate_type           = CoreLookupType (ctx, "System", "Delegate", MemberKind.Class, true);
-
-               enum_type       = CoreLookupType (ctx, "System", "Enum", MemberKind.Class, true);
-               array_type      = CoreLookupType (ctx, "System", "Array", MemberKind.Class, true);
-               void_type       = CoreLookupType (ctx, "System", "Void", MemberKind.Struct, true);
-               system_void_expr.Type = void_type;
-               type_type       = CoreLookupType (ctx, "System", "Type", MemberKind.Class, true);
-               exception_type = CoreLookupType (ctx, "System", "Exception", MemberKind.Class, true);
-
-               runtime_field_handle_type = CoreLookupType (ctx, "System", "RuntimeFieldHandle", MemberKind.Struct, true);
-               runtime_handle_type = CoreLookupType (ctx, "System", "RuntimeTypeHandle", MemberKind.Struct, true);
+               foreach (var p in predefined) {
+                       var found = CoreLookupType (ctx, p.Namespace, p.Name, p.Kind, true);
+                       if (found == null || found == p)
+                               continue;
+
+                       if (!RootContext.StdLib) {
+                               var ns = GlobalRootNamespace.Instance.GetNamespace (p.Namespace, false);
+                               ns.ReplaceTypeWithPredefined (found, p);
+
+                               var tc = found.MemberDefinition as TypeContainer;
+                               tc.SetPredefinedSpec (p);
+                               p.SetDefinition (found);
+                       }
+               }
 
                PredefinedAttributes.Get.ParamArray.Initialize (ctx, false);
                PredefinedAttributes.Get.Out.Initialize (ctx, false);
@@ -994,9 +468,9 @@ namespace Mono.CSharp {
                //
                // These are only used for compare purposes
                //
-               null_type = typeof (NullLiteral);
-               
-               void_ptr_type = GetPointerType (void_type);
+               null_type = InternalType.Null;
+
+               void_ptr_type = PointerContainer.MakeType (void_type);
 
                //
                // Initialize InternalsVisibleTo as the very first optional type. Otherwise we would populate
@@ -1011,19 +485,11 @@ namespace Mono.CSharp {
                arg_iterator_type = CoreLookupType (ctx, "System", "ArgIterator", MemberKind.Struct, false);
                mbr_type = CoreLookupType (ctx, "System", "MarshalByRefObject", MemberKind.Class, false);
 
-               //
-               // Optional attributes, used for error reporting only
-               //
-               //if (PredefinedAttributes.Get.Obsolete.IsDefined) {
-               //    Class c = TypeManager.LookupClass (PredefinedAttributes.Get.Obsolete.Type);
-               //    if (c != null)
-               //        c.Define ();
-               //}
-
-               generic_ilist_type = CoreLookupType (ctx, "System.Collections.Generic", "IList`1", MemberKind.Interface, false);
-               generic_icollection_type = CoreLookupType (ctx, "System.Collections.Generic", "ICollection`1", MemberKind.Interface, false);
-               generic_ienumerable_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerable`1", MemberKind.Interface, false);
-               generic_nullable_type = CoreLookupType (ctx, "System", "Nullable`1", MemberKind.Struct, false);
+               generic_ienumerator_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerator", 1, MemberKind.Interface, false);
+               generic_ilist_type = CoreLookupType (ctx, "System.Collections.Generic", "IList", 1, MemberKind.Interface, false);
+               generic_icollection_type = CoreLookupType (ctx, "System.Collections.Generic", "ICollection", 1, MemberKind.Interface, false);
+               generic_ienumerable_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerable", 1, MemberKind.Interface, false);
+               generic_nullable_type = CoreLookupType (ctx, "System", "Nullable", 1, MemberKind.Struct, false);
 
                //
                // Optional types which are used as types and for member lookup
@@ -1032,324 +498,61 @@ namespace Mono.CSharp {
 
                // New in .NET 3.5
                // Note: extension_attribute_type is already loaded
-               expression_type = CoreLookupType (ctx, "System.Linq.Expressions", "Expression`1", MemberKind.Class, false);
+               expression_type = CoreLookupType (ctx, "System.Linq.Expressions", "Expression", 1, MemberKind.Class, false);
+       }
 
-               if (!RootContext.StdLib) {
-                       //
-                       // HACK: When building Mono corlib mcs uses loaded mscorlib which
-                       // has different predefined types and this method sets mscorlib types
-                       // to be same to avoid any type check errors.
-                       //
+       public static bool IsBuiltinType (TypeSpec t)
+       {
+               if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
+                   t == int64_type || t == uint64_type || t == float_type || t == double_type ||
+                   t == char_type || t == short_type || t == decimal_type || t == bool_type ||
+                   t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
+                       return true;
+               else
+                       return false;
+       }
 
-                       Type type = typeof (Type);
-                       Type [] system_4_type_arg = { type, type, type, type };
-                               
-                       MethodInfo set_corlib_type_builders = 
-                               typeof (System.Reflection.Emit.AssemblyBuilder).GetMethod (
-                               "SetCorlibTypeBuilders", BindingFlags.NonPublic | BindingFlags.Instance, null,
-                               system_4_type_arg, null);
-
-                       if (set_corlib_type_builders != null) {
-                               object[] args = new object [4];
-                               args [0] = object_type;
-                               args [1] = value_type;
-                               args [2] = enum_type;
-                               args [3] = void_type;
-                               
-                               set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
-                       } else {
-                               ctx.Report.Warning (-26, 3, "The compilation may fail due to missing `{0}.SetCorlibTypeBuilders({1})' method",
-                                       TypeManager.CSharpName (typeof (System.Reflection.Emit.AssemblyBuilder)),
-                                       TypeManager.CSharpName (system_4_type_arg));
-                       }
-               }
+       //
+       // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
+       // the pieces in the code where we use IsBuiltinType and special case decimal_type.
+       // 
+       public static bool IsPrimitiveType (TypeSpec t)
+       {
+               return (t == int32_type || t == uint32_type ||
+                   t == int64_type || t == uint64_type || t == float_type || t == double_type ||
+                   t == char_type || t == short_type || t == bool_type ||
+                   t == sbyte_type || t == byte_type || t == ushort_type);
        }
 
-       const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
+       // Obsolete
+       public static bool IsDelegateType (TypeSpec t)
+       {
+               return t.IsDelegate;
+       }
 
-       /// <remarks>
-       ///   This is the "old", non-cache based FindMembers() function.  We cannot use
-       ///   the cache here because there is no member name argument.
-       /// </remarks>
-       public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
-                                             MemberFilter filter, object criteria)
+       //
+       // When any element of the type is a dynamic type
+       //
+       // This method builds a transformation array for dynamic types
+       // used in places where DynamicAttribute cannot be applied to.
+       // It uses bool flag when type is of dynamic type and each
+       // section always starts with "false" for some reason.
+       //
+       // LAMESPEC: This should be part of C# specification !
+       // 
+       // Example: Func<dynamic, int, dynamic[]>
+       // Transformation: { false, true, false, false, true }
+       //
+       public static bool[] HasDynamicTypeUsed (TypeSpec t)
        {
-#if MS_COMPATIBLE
-               if (t.IsGenericType)
-                       t = t.GetGenericTypeDefinition ();
-#endif
+               var ac = t as ArrayContainer;
+               if (ac != null) {
+                       if (HasDynamicTypeUsed (ac.Element) != null)
+                               return new bool[] { false, true };
 
-               DeclSpace decl = LookupDeclSpace (t);
-
-               //
-               // `builder_to_declspace' contains all dynamic types.
-               //
-               if (decl != null) {
-                       MemberList list;
-                       Timer.StartTimer (TimerType.FindMembers);
-                       list = decl.FindMembers (mt, bf, filter, criteria);
-                       Timer.StopTimer (TimerType.FindMembers);
-                       return list;
-               }
-
-               //
-               // We have to take care of arrays specially, because GetType on
-               // a TypeBuilder array will return a Type, not a TypeBuilder,
-               // and we can not call FindMembers on this type.
-               //
-               if (
-#if MS_COMPATIBLE
-                       !t.IsGenericType &&
-#endif
-                       t.IsSubclassOf (TypeManager.array_type))
-                       return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria));
-
-               if (t is GenericTypeParameterBuilder) {
-                       TypeParameter tparam = builder_to_type_param [(GenericTypeParameterBuilder) t];
-
-                       Timer.StartTimer (TimerType.FindMembers);
-                       MemberList list = tparam.FindMembers (
-                               mt, bf | BindingFlags.DeclaredOnly, filter, criteria);
-                       Timer.StopTimer (TimerType.FindMembers);
-                       return list;
-               }
-
-               //
-               // Since FindMembers will not lookup both static and instance
-               // members, we emulate this behaviour here.
-               //
-               if ((bf & instance_and_static) == instance_and_static){
-                       MemberInfo [] i_members = t.FindMembers (
-                               mt, bf & ~BindingFlags.Static, filter, criteria);
-
-                       int i_len = i_members.Length;
-                       if (i_len == 1){
-                               MemberInfo one = i_members [0];
-
-                               //
-                               // If any of these are present, we are done!
-                               //
-                               if ((one is Type) || (one is EventInfo) || (one is FieldInfo))
-                                       return new MemberList (i_members);
-                       }
-                               
-                       MemberInfo [] s_members = t.FindMembers (
-                               mt, bf & ~BindingFlags.Instance, filter, criteria);
-
-                       int s_len = s_members.Length;
-                       if (i_len > 0 || s_len > 0)
-                               return new MemberList (i_members, s_members);
-                       else {
-                               if (i_len > 0)
-                                       return new MemberList (i_members);
-                               else
-                                       return new MemberList (s_members);
-                       }
-               }
-
-               return new MemberList (t.FindMembers (mt, bf, filter, criteria));
-       }
-
-
-       /// <summary>
-       ///   This method is only called from within MemberLookup.  It tries to use the member
-       ///   cache if possible and falls back to the normal FindMembers if not.  The `used_cache'
-       ///   flag tells the caller whether we used the cache or not.  If we used the cache, then
-       ///   our return value will already contain all inherited members and the caller don't need
-       ///   to check base classes and interfaces anymore.
-       /// </summary>
-       private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
-                                                              string name, out bool used_cache)
-       {
-               MemberCache cache;
-
-               //
-               // If this is a dynamic type, it's always in the `builder_to_declspace' hash table
-               // and we can ask the DeclSpace for the MemberCache.
-               //
-#if MS_COMPATIBLE
-               if (t.Assembly == CodeGen.Assembly.Builder) {
-                       if (t.IsGenericParameter) {
-                               TypeParameter tparam = builder_to_type_param [(GenericTypeParameterBuilder) t];
-
-                               used_cache = true;
-                               if (tparam.MemberCache == null)
-                                       return new MemberInfo[0];
-
-                               return tparam.MemberCache.FindMembers (
-                                       mt, bf, name, FilterWithClosure_delegate, null);
-                       }
-
-                       //
-                       // We have to take care of arrays specially, because GetType on
-                       // a TypeBuilder array will return a Type, not a TypeBuilder,
-                       // and we can not call FindMembers on this type.
-                       //
-                       if (t.IsArray) {
-                               used_cache = true;
-                               return TypeHandle.ArrayType.MemberCache.FindMembers (
-                                       mt, bf, name, FilterWithClosure_delegate, null);
-                       }
-
-                       if (t.IsGenericType && !t.IsGenericTypeDefinition)
-                               t = t.GetGenericTypeDefinition ();
-#else
-               if (t is TypeBuilder) {
-#endif
-                       DeclSpace decl = LookupDeclSpace (t);
-                       cache = decl.MemberCache;
-
-                       //
-                       // If this DeclSpace has a MemberCache, use it.
-                       //
-
-                       if (cache != null) {
-                               used_cache = true;
-                               return cache.FindMembers (
-                                       mt, bf, name, FilterWithClosure_delegate, null);
-                       }
-
-                       // If there is no MemberCache, we need to use the "normal" FindMembers.
-                       // Note, this is a VERY uncommon route!
-
-                       MemberList list;
-                       Timer.StartTimer (TimerType.FindMembers);
-                       list = decl.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
-                                                FilterWithClosure_delegate, name);
-                       Timer.StopTimer (TimerType.FindMembers);
-                       used_cache = false;
-                       return (MemberInfo []) list;
-               }
-
-               //
-               // We have to take care of arrays specially, because GetType on
-               // a TypeBuilder array will return a Type, not a TypeBuilder,
-               // and we can not call FindMembers on this type.
-               //
-               if (t.IsArray) {
-                       used_cache = true;
-                       return TypeHandle.ArrayType.MemberCache.FindMembers (
-                               mt, bf, name, FilterWithClosure_delegate, null);
-               }
-
-               if (t is GenericTypeParameterBuilder) {
-                       TypeParameter tparam = builder_to_type_param [(GenericTypeParameterBuilder) t];
-
-                       used_cache = true;
-                       if (tparam.MemberCache == null)
-                               return new MemberInfo [0];
-
-                       return tparam.MemberCache.FindMembers (
-                               mt, bf, name, FilterWithClosure_delegate, null);
-               }
-
-               if (IsGenericType (t) && (mt == MemberTypes.NestedType)) {
-                       //
-                       // This happens if we're resolving a class'es base class and interfaces
-                       // in TypeContainer.DefineType().  At this time, the types aren't
-                       // populated yet, so we can't use the cache.
-                       //
-                       MemberInfo[] info = t.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
-                                                          FilterWithClosure_delegate, name);
-                       used_cache = false;
-                       return info;
+                       return null;
                }
 
-               //
-               // This call will always succeed.  There is exactly one TypeHandle instance per
-               // type, TypeHandle.GetMemberCache() will, if necessary, create a new one, and return
-               // the corresponding MemberCache.
-               //
-               cache = TypeHandle.GetMemberCache (t);
-
-               used_cache = true;
-               return cache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null);
-       }
-
-       //
-       // Return true for SRE dynamic/unclosed members
-       //
-       public static bool IsBeingCompiled (MemberInfo mi)
-       {
-               return mi.Module.Assembly == CodeGen.Assembly.Builder;
-       }
-
-       public static bool IsBuiltinType (Type t)
-       {
-               t = TypeToCoreType (t);
-               if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
-                   t == int64_type || t == uint64_type || t == float_type || t == double_type ||
-                   t == char_type || t == short_type || t == decimal_type || t == bool_type ||
-                   t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
-                       return true;
-               else
-                       return false;
-       }
-
-       //
-       // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
-       // the pieces in the code where we use IsBuiltinType and special case decimal_type.
-       // 
-       public static bool IsPrimitiveType (Type t)
-       {
-               return (t == int32_type || t == uint32_type ||
-                   t == int64_type || t == uint64_type || t == float_type || t == double_type ||
-                   t == char_type || t == short_type || t == bool_type ||
-                   t == sbyte_type || t == byte_type || t == ushort_type);
-       }
-
-       public static bool IsDelegateType (Type t)
-       {
-               if (TypeManager.IsGenericParameter (t))
-                       return false;
-
-               if (t == TypeManager.delegate_type || t == TypeManager.multicast_delegate_type)
-                       return false;
-
-               t = DropGenericTypeArguments (t);
-               return IsSubclassOf (t, TypeManager.delegate_type);
-       }
-
-       //
-       // Is a type of dynamic type
-       //
-       public static bool IsDynamicType (Type t)
-       {
-               if (object.ReferenceEquals (InternalType.Dynamic, t))
-                       return true;
-
-               if (t != object_type)
-                       return false;
-
-               if (IsBeingCompiled (t))
-                       return false;
-
-               PredefinedAttribute pa = PredefinedAttributes.Get.Dynamic;
-               if (pa == null || IsBeingCompiled (pa.Type))
-                       return false;
-
-               object[] res = t.GetCustomAttributes (pa.Type, false);
-               return res != null && res.Length != 0;
-       }
-
-       //
-       // When any element of the type is a dynamic type
-       //
-       // This method builds a transformation array for dynamic types
-       // used in places where DynamicAttribute cannnot be applied to.
-       // It uses bool flag when type is of dynamic type and each
-       // section always starts with "false" for some reason.
-       //
-       // LAMESPEC: This should be part of C# specification !
-       // 
-       // Example: Func<dynamic, int, dynamic[]>
-       // Transformation: { false, true, false, false, true }
-       //
-       public static bool[] HasDynamicTypeUsed (Type t)
-       {
-               if (t is DynamicArrayType)
-                       return new bool[] { false, true };
-
                if (t == null)
                        return null;
 
@@ -1381,13 +584,13 @@ namespace Mono.CSharp {
                return null;
        }
        
-       public static bool IsEnumType (Type t)
+       // Obsolete
+       public static bool IsEnumType (TypeSpec t)
        {
-               t = DropGenericTypeArguments (t);
-               return t.BaseType == TypeManager.enum_type;
+               return t.IsEnum;
        }
 
-       public static bool IsBuiltinOrEnum (Type t)
+       public static bool IsBuiltinOrEnum (TypeSpec t)
        {
                if (IsBuiltinType (t))
                        return true;
@@ -1398,28 +601,19 @@ namespace Mono.CSharp {
                return false;
        }
 
-       public static bool IsAttributeType (Type t)
-       {
-               return t == attribute_type && t.BaseType != null || IsSubclassOf (t, attribute_type);
-       }
-       
        //
        // Whether a type is unmanaged.  This is used by the unsafe code (25.2)
        //
-       // mcs4: delete, DeclSpace.IsUnmanagedType is replacement
-       public static bool IsUnmanagedType (Type t)
+       public static bool IsUnmanagedType (TypeSpec t)
        {
-               DeclSpace ds = TypeManager.LookupDeclSpace (t);
+               var ds = t.MemberDefinition as DeclSpace;
                if (ds != null)
                        return ds.IsUnmanagedType ();
 
-               // builtins that are not unmanaged types
+               // some builtins that are not unmanaged types
                if (t == TypeManager.object_type || t == TypeManager.string_type)
                        return false;
 
-               if (IsGenericType (t) || IsGenericParameter (t))
-                       return false;
-
                if (IsBuiltinOrEnum (t))
                        return true;
 
@@ -1427,100 +621,43 @@ namespace Mono.CSharp {
                if (t.IsPointer)
                        return IsUnmanagedType (GetElementType (t));
 
-               // Arrays are disallowed, even if we mark them with [MarshalAs(UnmanagedType.ByValArray, ...)]
-               if (t.IsArray)
-                       return false;
-
                if (!IsValueType (t))
                        return false;
 
-               for (Type p = t.DeclaringType; p != null; p = p.DeclaringType) {
-                       if (IsGenericTypeDefinition (p))
-                               return false;
-               }
-
-               bool retval = true;
-               {
-                       FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
-                       
-                       foreach (FieldInfo f in fields){
-                               if (!IsUnmanagedType (f.FieldType)){
-                                       retval = false;
-                               }
-                       }
-               }
+               if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
+                       return false;
 
-               return retval;
+               return true;
        }
 
        //
        // Null is considered to be a reference type
        //                      
-       public static bool IsReferenceType (Type t)
+       public static bool IsReferenceType (TypeSpec t)
        {
-               if (TypeManager.IsGenericParameter (t)) {
-                       GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
-                       if (constraints == null)
-                               return false;
-
-                       return constraints.IsReferenceType;
-               }
+               if (t.IsGenericParameter)
+                       return ((TypeParameterSpec) t).IsReferenceType;
 
-               return !IsStruct (t) && !IsEnumType (t);
+               return !t.IsStruct && !IsEnumType (t);
        }                       
                
-       public static bool IsValueType (Type t)
+       public static bool IsValueType (TypeSpec t)
        {
-               if (TypeManager.IsGenericParameter (t)) {
-                       GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
-                       if (constraints == null)
-                               return false;
-
-                       return constraints.IsValueType;
-               }
+               if (t.IsGenericParameter)
+                       return ((TypeParameterSpec) t).IsValueType;
 
-               return IsStruct (t) || IsEnumType (t);
+               return t.IsStruct || IsEnumType (t);
        }
 
-       public static bool IsStruct (Type t)
+       public static bool IsStruct (TypeSpec t)
        {
-               return t.BaseType == value_type && t != enum_type && t.IsSealed;
-       }
-       
-       public static bool IsInterfaceType (Type t)
-       {
-               TypeContainer tc = LookupTypeContainer (t);
-               if (tc == null)
-                       return false;
-
-               return tc.Kind == MemberKind.Interface;
+               return t.IsStruct;
        }
 
-       public static bool IsSubclassOf (Type type, Type base_type)
+       public static bool IsSubclassOf (TypeSpec type, TypeSpec base_type)
        {
-               TypeParameter tparam = LookupTypeParameter (type);
-               TypeParameter pparam = LookupTypeParameter (base_type);
-
-               if ((tparam != null) && (pparam != null)) {
-                       if (tparam == pparam)
-                               return true;
-
-                       return tparam.IsSubclassOf (base_type);
-               }
-
-#if MS_COMPATIBLE
-               if (tparam != pparam)
-                       return false;
-
-               if (type.IsGenericType)
-                       type = type.GetGenericTypeDefinition ();
-#endif
-
-               if (type.IsSubclassOf (base_type))
-                       return true;
-
                do {
-                       if (IsEqual (type, base_type))
+                       if (type == base_type)
                                return true;
 
                        type = type.BaseType;
@@ -1529,27 +666,17 @@ namespace Mono.CSharp {
                return false;
        }
 
-       public static bool IsPrivateAccessible (Type type, Type parent)
-       {
-               if (type == null)
-                       return false;
-
-               if (type.Equals (parent))
-                       return true;
-
-               return DropGenericTypeArguments (type) == DropGenericTypeArguments (parent);
-       }
-
-       public static bool IsFamilyAccessible (Type type, Type parent)
+       public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
        {
-               TypeParameter tparam = LookupTypeParameter (type);
-               TypeParameter pparam = LookupTypeParameter (parent);
+//             TypeParameter tparam = LookupTypeParameter (type);
+//             TypeParameter pparam = LookupTypeParameter (parent);
 
-               if ((tparam != null) && (pparam != null)) {
-                       if (tparam == pparam)
+               if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
+                       if (type == parent)
                                return true;
 
-                       return tparam.IsSubclassOf (parent);
+                       throw new NotImplementedException ("net");
+//                     return tparam.IsSubclassOf (parent);
                }
 
                do {
@@ -1565,7 +692,7 @@ namespace Mono.CSharp {
        //
        // Checks whether `type' is a subclass or nested child of `base_type'.
        //
-       public static bool IsNestedFamilyAccessible (Type type, Type base_type)
+       public static bool IsNestedFamilyAccessible (TypeSpec type, TypeSpec base_type)
        {
                do {
                        if (IsFamilyAccessible (type, base_type))
@@ -1581,20 +708,20 @@ namespace Mono.CSharp {
        //
        // Checks whether `type' is a nested child of `parent'.
        //
-       public static bool IsNestedChildOf (Type type, Type parent)
+       public static bool IsNestedChildOf (TypeSpec type, TypeSpec parent)
        {
                if (type == null)
                        return false;
 
-               type = DropGenericTypeArguments (type);
-               parent = DropGenericTypeArguments (parent);
+               type = type.GetDefinition (); // DropGenericTypeArguments (type);
+               parent = parent.GetDefinition (); // DropGenericTypeArguments (parent);
 
                if (IsEqual (type, parent))
                        return false;
 
                type = type.DeclaringType;
                while (type != null) {
-                       if (IsEqual (type, parent))
+                       if (IsEqual (type.GetDefinition (), parent))
                                return true;
 
                        type = type.DeclaringType;
@@ -1603,7 +730,7 @@ namespace Mono.CSharp {
                return false;
        }
 
-       public static bool IsSpecialType (Type t)
+       public static bool IsSpecialType (TypeSpec t)
        {
                return t == arg_iterator_type || t == typed_reference_type;
        }
@@ -1630,15 +757,7 @@ namespace Mono.CSharp {
                if (assembly_internals_vis_attrs.TryGetValue (assembly, out value))
                        return value;
 
-               PredefinedAttribute pa = PredefinedAttributes.Get.InternalsVisibleTo;
-               // HACK: Do very early resolve of SRE type checking
-               if (pa.Type == null)
-                       pa.Resolve (true);
-
-               if (!pa.IsDefined)
-                       return false;
-               
-               object [] attrs = assembly.GetCustomAttributes (pa.Type, false);
+               object[] attrs = assembly.GetCustomAttributes (typeof (InternalsVisibleToAttribute), false);
                if (attrs.Length == 0) {
                        assembly_internals_vis_attrs.Add (assembly, false);
                        return false;
@@ -1647,6 +766,9 @@ namespace Mono.CSharp {
                bool is_friend = false;
 
                AssemblyName this_name = CodeGen.Assembly.Name;
+               if (this_name == null)
+                       return false;
+
                byte [] this_token = this_name.GetPublicKeyToken ();
                foreach (InternalsVisibleToAttribute attr in attrs) {
                        if (attr.AssemblyName == null || attr.AssemblyName.Length == 0)
@@ -1698,1247 +820,191 @@ namespace Mono.CSharp {
                        other_name, CodeGen.Assembly.Name.FullName);
        }
 
-        //
-        // Do the right thing when returning the element type of an
-        // array type based on whether we are compiling corlib or not
-        //
-        public static Type GetElementType (Type t)
-        {
-                if (RootContext.StdLib)
-                        return t.GetElementType ();
-                else
-                        return TypeToCoreType (t.GetElementType ());
-        }
+       public static TypeSpec GetElementType (TypeSpec t)
+       {
+               return ((ElementTypeSpec)t).Element;
+       }
 
        /// <summary>
        /// This method is not implemented by MS runtime for dynamic types
        /// </summary>
-       public static bool HasElementType (Type t)
+       public static bool HasElementType (TypeSpec t)
        {
-               return t.IsArray || t.IsPointer || t.IsByRef;
+               return t is ElementTypeSpec;
        }
 
-       public static Type GetEnumUnderlyingType (Type t)
+       static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
+
+       // This is a custom version of Convert.ChangeType() which works
+       // with the TypeBuilder defined types when compiling corlib.
+       public static object ChangeType (object value, TypeSpec targetType, out bool error)
        {
-               t = DropGenericTypeArguments (t);
-               Enum e = LookupTypeContainer (t) as Enum;
-               if (e != null)
-                       return e.UnderlyingType;
+               IConvertible convert_value = value as IConvertible;
+               
+               if (convert_value == null){
+                       error = true;
+                       return null;
+               }
+               
+               //
+               // We cannot rely on build-in type conversions as they are
+               // more limited than what C# supports.
+               // See char -> float/decimal/double conversion
+               //
+               error = false;
+               try {
+                       if (targetType == TypeManager.bool_type)
+                               return convert_value.ToBoolean (nf_provider);
+                       if (targetType == TypeManager.byte_type)
+                               return convert_value.ToByte (nf_provider);
+                       if (targetType == TypeManager.char_type)
+                               return convert_value.ToChar (nf_provider);
+                       if (targetType == TypeManager.short_type)
+                               return convert_value.ToInt16 (nf_provider);
+                       if (targetType == TypeManager.int32_type)
+                               return convert_value.ToInt32 (nf_provider);
+                       if (targetType == TypeManager.int64_type)
+                               return convert_value.ToInt64 (nf_provider);
+                       if (targetType == TypeManager.sbyte_type)
+                               return convert_value.ToSByte (nf_provider);
+
+                       if (targetType == TypeManager.decimal_type) {
+                               if (convert_value.GetType () == typeof (char))
+                                       return (decimal) convert_value.ToInt32 (nf_provider);
+                               return convert_value.ToDecimal (nf_provider);
+                       }
+
+                       if (targetType == TypeManager.double_type) {
+                               if (convert_value.GetType () == typeof (char))
+                                       return (double) convert_value.ToInt32 (nf_provider);
+                               return convert_value.ToDouble (nf_provider);
+                       }
+
+                       if (targetType == TypeManager.float_type) {
+                               if (convert_value.GetType () == typeof (char))
+                                       return (float)convert_value.ToInt32 (nf_provider);
+                               return convert_value.ToSingle (nf_provider);
+                       }
 
-               // TODO: cache it ?
-               FieldInfo fi = GetPredefinedField (t, Enum.UnderlyingValueField, Location.Null, Type.EmptyTypes);
-               if (fi == null)
-                       return TypeManager.int32_type;
+                       if (targetType == TypeManager.string_type)
+                               return convert_value.ToString (nf_provider);
+                       if (targetType == TypeManager.ushort_type)
+                               return convert_value.ToUInt16 (nf_provider);
+                       if (targetType == TypeManager.uint32_type)
+                               return convert_value.ToUInt32 (nf_provider);
+                       if (targetType == TypeManager.uint64_type)
+                               return convert_value.ToUInt64 (nf_provider);
+                       if (targetType == TypeManager.object_type)
+                               return value;
 
-               return TypeToCoreType (fi.FieldType);
+                       error = true;
+               } catch {
+                       error = true;
+               }
+               return null;
        }
-       
+
        /// <summary>
-       ///   Gigantic work around for missing features in System.Reflection.Emit follows.
+       ///   Utility function that can be used to probe whether a type
+       ///   is managed or not.  
        /// </summary>
-       ///
-       /// <remarks>
-       ///   Since System.Reflection.Emit can not return MethodBase.GetParameters
-       ///   for anything which is dynamic, and we need this in a number of places,
-       ///   we register this information here, and use it afterwards.
-       /// </remarks>
-       static public void RegisterMethod (MethodBase mb, AParametersCollection ip)
+       public static bool VerifyUnmanaged (CompilerContext ctx, TypeSpec t, Location loc)
        {
-               method_params.Add (mb, ip);
-       }
+               while (t.IsPointer)
+                       t = GetElementType (t);
 
-       static public void RegisterIndexer (PropertyBuilder pb, AParametersCollection p)
-       {
-               method_params.Add (pb, p);
+               if (IsUnmanagedType (t))
+                       return true;
+
+               ctx.Report.SymbolRelatedToPreviousError (t);
+               ctx.Report.Error (208, loc,
+                       "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
+                       CSharpName (t));
+
+               return false;   
        }
        
-       static public AParametersCollection GetParameterData (MethodBase mb)
+       //
+       // Returns whether the array of memberinfos contains the given method
+       //
+       public static bool ArrayContainsMethod (List<MemberSpec> array, MethodSpec new_method, bool ignoreDeclType)
        {
-               AParametersCollection pd;
-               if (!method_params.TryGetValue (mb, out pd)) {
-#if MS_COMPATIBLE
-                       if (mb.IsGenericMethod && !mb.IsGenericMethodDefinition) {
-                               MethodInfo mi = ((MethodInfo) mb).GetGenericMethodDefinition ();
-                               pd = GetParameterData (mi);
-                               /*
-                               if (mi.IsGenericMethod)
-                                       pd = pd.InflateTypes (mi.GetGenericArguments (), mb.GetGenericArguments ());
-                               else
-                                       pd = pd.InflateTypes (mi.DeclaringType.GetGenericArguments (), mb.GetGenericArguments ());
-                               */
-                               method_params.Add (mb, pd);
-                               return pd;
-                       }
+               AParametersCollection new_args = new_method.Parameters;
 
-                       if (mb.DeclaringType.Assembly == CodeGen.Assembly.Builder) {
-                               throw new InternalErrorException ("Parameters are not registered for method `{0}'",
-                                       TypeManager.CSharpName (mb.DeclaringType) + "." + mb.Name);
-                       }
+               foreach (MethodSpec method in array) {
+                       if (!ignoreDeclType && method.DeclaringType != new_method.DeclaringType)
+                               continue;
 
-                       pd = ParametersImported.Create (mb);
-#else
-                       MethodBase generic = TypeManager.DropGenericMethodArguments (mb);
-                       if (generic != mb) {
-                               pd = TypeManager.GetParameterData (generic);
-                               pd = ParametersImported.Create (pd, mb);
-                       } else {
-                               pd = ParametersImported.Create (mb);
-                       }
-#endif
-                       method_params.Add (mb, pd);
-               }
-               return pd;
-       }
+                       if (method.Name != new_method.Name)
+                               continue;
 
-       public static AParametersCollection GetParameterData (PropertyInfo pi)
-       {
-               AParametersCollection pd;
-               if (!method_params.TryGetValue (pi, out pd)) {
-                       if (pi is PropertyBuilder)
-                               return ParametersCompiled.EmptyReadOnlyParameters;
+                       if (!TypeSpecComparer.Override.IsEqual (method.ReturnType, new_method.ReturnType))
+                               continue;
 
-                       ParameterInfo [] p = pi.GetIndexParameters ();
-                       if (p == null)
-                               return ParametersCompiled.EmptyReadOnlyParameters;
+                       AParametersCollection old_args = method.Parameters;
+                       int old_count = old_args.Count;
+                       int i;
+
+                       if (new_args.Count != old_count)
+                               continue;
+
+                       for (i = 0; i < old_count; i++) {
+                               if (!TypeSpecComparer.Override.IsEqual (old_args.Types[i], new_args.Types[i]))
+                                       break;
+                       }
+                       if (i != old_count)
+                               continue;
 
-                       pd = ParametersImported.Create (p, null);
-                       method_params.Add (pi, pd);
+                       return true;
                }
 
-               return pd;
+               return false;
        }
-
-       public static AParametersCollection GetDelegateParameters (ResolveContext ec, Type t)
+#region Generics
+       // This method always return false for non-generic compiler,
+       // while Type.IsGenericParameter is returned if it is supported.
+       public static bool IsGenericParameter (TypeSpec type)
        {
-               Delegate d = LookupDelegate (t);
-               if (d != null)
-                       return d.Parameters;
-
-               var invoke_mb = Delegate.GetInvokeMethod (ec.Compiler, t, t);
-               return invoke_mb.Parameters;
+               return type.IsGenericParameter;
        }
 
-       static public void RegisterOverride (MethodBase override_method, MethodBase base_method)
+       public static bool IsGenericType (TypeSpec type)
        {
-               if (!method_overrides.ContainsKey (override_method))
-                       method_overrides [override_method] = base_method;
-               if (method_overrides [override_method] != base_method)
-                       throw new InternalErrorException ("Override mismatch: " + override_method);
+               return type.IsGeneric;
        }
 
-       static public bool IsOverride (MethodSpec ms)
+       // TODO: Implement correctly
+       public static bool ContainsGenericParameters (TypeSpec type)
        {
-               MethodBase m = ms.MetaInfo;
-               m = DropGenericMethodArguments (m);
-
-               return m.IsVirtual &&
-                       (m.Attributes & MethodAttributes.NewSlot) == 0 &&
-                       (m is MethodBuilder || method_overrides.ContainsKey (m));
+               return type.GetMetaInfo ().ContainsGenericParameters;
        }
 
-       static public MethodBase TryGetBaseDefinition (MethodBase m)
+       public static bool IsEqual (TypeSpec a, TypeSpec b)
        {
-               m = DropGenericMethodArguments (m);
-               MethodBase mb;
-               if (method_overrides.TryGetValue (m, out mb))
-                       return mb;
+               return a == b && !(a is InternalType);
+       }
 
-               return null;
+       public static TypeSpec[] GetTypeArguments (TypeSpec t)
+       {
+               // TODO: return empty array !!
+               return t.TypeArguments;
        }
 
-       public static void RegisterConstant (FieldInfo fb, ConstSpec ic)
+       /// <summary>
+       ///   Check whether `type' and `parent' are both instantiations of the same
+       ///   generic type.  Note that we do not check the type parameters here.
+       /// </summary>
+       public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
        {
-               fields.Add (fb, ic);
+               return type == parent || type.MemberDefinition == parent.MemberDefinition;
        }
 
-       public static ConstSpec GetConstant (FieldInfo fb)
+       public static bool IsNullableType (TypeSpec t)
        {
-               if (fb == null)
-                       return null;
-
-               ConstSpec ic;
-               if (fields.TryGetValue (fb, out ic))
-                       return ic;
-
-               return null;
-       }
-
-       public static void RegisterProperty (PropertyInfo pi, PropertyBase pb)
-       {
-               propertybuilder_to_property.Add (pi, pb);
-       }
-
-       public static PropertyBase GetProperty (PropertyInfo pi)
-       {
-               PropertyBase pb;
-               if (propertybuilder_to_property.TryGetValue (pi, out pb))
-                       return pb;
-
-               return null;
-       }
-
-       static public void RegisterFieldBase (FieldBuilder fb, FieldBase f)
-       {
-               fieldbuilders_to_fields.Add (fb, f);
-       }
-
-       //
-       // The return value can be null;  This will be the case for
-       // auxiliary FieldBuilders created by the compiler that have no
-       // real field being declared on the source code
-       //
-       static public FieldBase GetField (FieldInfo fb)
-       {
-               return GetFieldCore (GetGenericFieldDefinition (fb));
-       }
-
-       static public FieldBase GetFieldCore (FieldInfo fb)
-       {
-               FieldBase f;
-               if (fieldbuilders_to_fields.TryGetValue (fb, out f))
-                       return f;
-
-               return null;
-       }
-
-       static public MethodInfo GetAddMethod (EventInfo ei)
-       {
-               if (ei is MyEventBuilder) {
-                       return ((MyEventBuilder)ei).GetAddMethod (true);
-               }
-               return ei.GetAddMethod (true);
-       }
-
-       static public MethodInfo GetRemoveMethod (EventInfo ei)
-       {
-               if (ei is MyEventBuilder) {
-                       return ((MyEventBuilder)ei).GetRemoveMethod (true);
-               }
-               return ei.GetRemoveMethod (true);
-       }
-
-       static public void RegisterEventField (EventInfo einfo, EventSpec e)
-       {
-               if (events == null)
-                       events = new Dictionary<EventInfo, EventSpec> (ReferenceEquality<EventInfo>.Default);
-
-               events.Add (einfo, e);
-       }
-
-       static public EventSpec GetEventField (EventInfo ei)
-       {
-               if (events == null)
-                       return null;
-
-               EventSpec value;
-               if (events.TryGetValue (ei, out value))
-                       return value;
-
-               return null;
-       }
-
-       public static bool CheckStructCycles (TypeContainer tc, Dictionary<TypeContainer, object> seen)
-       {
-               var hash = new Dictionary<TypeContainer, object> ();
-               return CheckStructCycles (tc, seen, hash);
-       }
-
-       public static bool CheckStructCycles (TypeContainer tc, Dictionary<TypeContainer, object> seen,
-                                                 Dictionary<TypeContainer, object> hash)
-       {
-               if ((tc.Kind != MemberKind.Struct) || IsBuiltinType (tc.TypeBuilder))
-                       return true;
-
-               //
-               // `seen' contains all types we've already visited.
-               //
-               if (seen.ContainsKey (tc))
-                       return true;
-               seen.Add (tc, null);
-
-               if (tc.Fields == null)
-                       return true;
-
-               foreach (FieldBase field in tc.Fields) {
-                       if (field.Spec == null || field.Spec.IsStatic)
-                               continue;
-
-                       Type ftype = field.Spec.FieldType;
-                       TypeContainer ftc = LookupTypeContainer (ftype);
-                       if (ftc == null)
-                               continue;
-
-                       if (hash.ContainsKey (ftc)) {
-                               tc.Compiler.Report.Error (523, tc.Location,
-                                             "Struct member `{0}.{1}' of type `{2}' " +
-                                             "causes a cycle in the struct layout",
-                                             tc.Name, field.Name, ftc.Name);
-                               return false;
-                       }
-
-                       //
-                       // `hash' contains all types in the current path.
-                       //
-                       hash.Add (tc, null);
-
-                       bool ok = CheckStructCycles (ftc, seen, hash);
-
-                       hash.Remove (tc);
-
-                       if (!ok)
-                               return false;
-
-                       if (!seen.ContainsKey (ftc))
-                               seen.Add (ftc, null);
-               }
-
-               return true;
-       }
-
-       /// <summary>
-       ///   Given an array of interface types, expand and eliminate repeated ocurrences
-       ///   of an interface.  
-       /// </summary>
-       ///
-       /// <remarks>
-       ///   This expands in context like: IA; IB : IA; IC : IA, IB; the interface "IC" to
-       ///   be IA, IB, IC.
-       /// </remarks>
-       public static Type[] ExpandInterfaces (TypeExpr [] base_interfaces)
-       {
-               var new_ifaces = new List<Type> ();
-
-               foreach (TypeExpr iface in base_interfaces){
-                       Type itype = iface.Type;
-
-                       if (new_ifaces.Contains (itype))
-                               continue;
-
-                       new_ifaces.Add (itype);
-                       
-                       Type [] implementing = GetInterfaces (itype);
-
-                       foreach (Type imp in implementing){
-                               if (!new_ifaces.Contains (imp))
-                                       new_ifaces.Add (imp);
-                       }
-               }
-
-               return new_ifaces.ToArray ();
-       }
-
-       public static Type[] ExpandInterfaces (Type [] base_interfaces)
-       {
-               var new_ifaces = new List<Type> ();
-
-               foreach (Type itype in base_interfaces){
-                       if (new_ifaces.Contains (itype))
-                               continue;
-
-                       new_ifaces.Add (itype);
-                       
-                       Type [] implementing = GetInterfaces (itype);
-
-                       foreach (Type imp in implementing){
-                               if (!new_ifaces.Contains (imp))
-                                       new_ifaces.Add (imp);
-                       }
-               }
-
-               return new_ifaces.ToArray ();
-       }
-               
-       /// <summary>
-       ///   This function returns the interfaces in the type `t'.  Works with
-       ///   both types and TypeBuilders.
-       /// </summary>
-       public static Type [] GetInterfaces (Type t)
-       {
-               Type [] cached;
-               if (iface_cache.TryGetValue (t, out cached))
-               if (cached != null)
-                       return cached;
-               
-               //
-               // The reason for catching the Array case is that Reflection.Emit
-               // will not return a TypeBuilder for Array types of TypeBuilder types,
-               // but will still throw an exception if we try to call GetInterfaces
-               // on the type.
-               //
-               // Since the array interfaces are always constant, we return those for
-               // the System.Array
-               //
-               
-               if (t.IsArray)
-                       t = TypeManager.array_type;
-               
-               if ((t is TypeBuilder) || IsGenericType (t)) {
-                       Type [] base_ifaces;
-                       
-                       if (t.BaseType == null)
-                               base_ifaces = Type.EmptyTypes;
-                       else
-                               base_ifaces = GetInterfaces (t.BaseType);
-                       Type[] type_ifaces;
-                       if (IsGenericType (t))
-#if MS_COMPATIBLE
-                               type_ifaces = t.GetGenericTypeDefinition().GetInterfaces ();
-#else
-                               type_ifaces = t.GetInterfaces ();
-#endif
-                       else
-                               type_ifaces = GetExplicitInterfaces (t);
-                       if (type_ifaces == null || type_ifaces.Length == 0)
-                               type_ifaces = Type.EmptyTypes;
-
-                       int base_count = base_ifaces.Length;
-                       Type [] result = new Type [base_count + type_ifaces.Length];
-                       base_ifaces.CopyTo (result, 0);
-                       type_ifaces.CopyTo (result, base_count);
-
-                       iface_cache [t] = result;
-                       return result;
-               } else if (t is GenericTypeParameterBuilder){
-                       Type[] type_ifaces = GetExplicitInterfaces (t);
-                       if (type_ifaces == null || type_ifaces.Length == 0)
-                               type_ifaces = Type.EmptyTypes;
-
-                       iface_cache [t] = type_ifaces;
-                       return type_ifaces;
-               } else {
-                       Type[] ifaces = t.GetInterfaces ();
-                       iface_cache [t] = ifaces;
-                       return ifaces;
-               }
-       }
-       
-       //
-       // gets the interfaces that are declared explicitly on t
-       //
-       public static Type[] GetExplicitInterfaces (Type t)
-       {
-               Type[] ifaces;
-               if (builder_to_ifaces.TryGetValue (t, out ifaces))
-                       return ifaces;
-
-               return null;
-       }
-       
-       /// <remarks>
-       ///  The following is used to check if a given type implements an interface.
-       ///  The cache helps us reduce the expense of hitting Type.GetInterfaces everytime.
-       /// </remarks>
-       public static bool ImplementsInterface (Type t, Type iface)
-       {
-               Type [] interfaces;
-
-               //
-               // FIXME OPTIMIZATION:
-               // as soon as we hit a non-TypeBuiler in the interface
-               // chain, we could return, as the `Type.GetInterfaces'
-               // will return all the interfaces implement by the type
-               // or its bases.
-               //
-               do {
-                       interfaces = GetInterfaces (t);
-
-                       if (interfaces != null){
-                               foreach (Type i in interfaces){
-                                       if (i == iface || IsVariantOf (i, iface))
-                                               return true;
-                               }
-                       }
-                       
-                       t = t.BaseType;
-               } while (t != null);
-               
-               return false;
-       }
-
-       static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
-
-       // This is a custom version of Convert.ChangeType() which works
-       // with the TypeBuilder defined types when compiling corlib.
-       public static object ChangeType (object value, Type conversionType, out bool error)
-       {
-               IConvertible convert_value = value as IConvertible;
-               
-               if (convert_value == null){
-                       error = true;
-                       return null;
-               }
-               
-               //
-               // NOTE 1:
-               // We must use Type.Equals() here since `conversionType' is
-               // the TypeBuilder created version of a system type and not
-               // the system type itself.  You cannot use Type.GetTypeCode()
-               // on such a type - it'd always return TypeCode.Object.
-               //
-               // NOTE 2:
-               // We cannot rely on build-in type conversions as they are
-               // more limited than what C# supports.
-               // See char -> float/decimal/double conversion
-               //
-
-               error = false;
-               try {
-                       if (conversionType.Equals (typeof (Boolean)))
-                               return (object)(convert_value.ToBoolean (nf_provider));
-                       if (conversionType.Equals (typeof (Byte)))
-                               return (object)(convert_value.ToByte (nf_provider));
-                       if (conversionType.Equals (typeof (Char)))
-                               return (object)(convert_value.ToChar (nf_provider));
-                       if (conversionType.Equals (typeof (DateTime)))
-                               return (object)(convert_value.ToDateTime (nf_provider));
-
-                       if (conversionType.Equals (decimal_type)) {
-                               if (convert_value.GetType () == TypeManager.char_type)
-                                       return (decimal)convert_value.ToInt32 (nf_provider);
-                               return convert_value.ToDecimal (nf_provider);
-                       }
-
-                       if (conversionType.Equals (typeof (Double))) {
-                               if (convert_value.GetType () == TypeManager.char_type)
-                                       return (double)convert_value.ToInt32 (nf_provider);
-                               return convert_value.ToDouble (nf_provider);
-                       }
-
-                       if (conversionType.Equals (typeof (Int16)))
-                               return (object)(convert_value.ToInt16 (nf_provider));
-                       if (conversionType.Equals (int32_type))
-                               return (object)(convert_value.ToInt32 (nf_provider));
-                       if (conversionType.Equals (int64_type))
-                               return (object)(convert_value.ToInt64 (nf_provider));
-                       if (conversionType.Equals (typeof (SByte)))
-                               return (object)(convert_value.ToSByte (nf_provider));
-
-                       if (conversionType.Equals (typeof (Single))) {
-                               if (convert_value.GetType () == TypeManager.char_type)
-                                       return (float)convert_value.ToInt32 (nf_provider);
-                               return convert_value.ToSingle (nf_provider);
-                       }
-
-                       if (conversionType.Equals (typeof (String)))
-                               return (object)(convert_value.ToString (nf_provider));
-                       if (conversionType.Equals (typeof (UInt16)))
-                               return (object)(convert_value.ToUInt16 (nf_provider));
-                       if (conversionType.Equals (typeof (UInt32)))
-                               return (object)(convert_value.ToUInt32 (nf_provider));
-                       if (conversionType.Equals (typeof (UInt64)))
-                               return (object)(convert_value.ToUInt64 (nf_provider));
-                       if (conversionType.Equals (typeof (Object)))
-                               return (object)(value);
-                       else 
-                               error = true;
-               } catch {
-                       error = true;
-               }
-               return null;
-       }
-
-       //
-       // When compiling with -nostdlib and the type is imported from an external assembly
-       // SRE uses "wrong" type and we have to convert it to the right compiler instance.
-       //
-       public static Type TypeToCoreType (Type t)
-       {
-               if (RootContext.StdLib || t.Module != typeof (object).Module)
-                       return t;
-                       
-               // TODO: GetTypeCode returns underlying type for enums !!
-               TypeCode tc = Type.GetTypeCode (t);
-
-               switch (tc){
-               case TypeCode.Boolean:
-                       return TypeManager.bool_type;
-               case TypeCode.Byte:
-                       return TypeManager.byte_type;
-               case TypeCode.SByte:
-                       return TypeManager.sbyte_type;
-               case TypeCode.Char:
-                       return TypeManager.char_type;
-               case TypeCode.Int16:
-                       return TypeManager.short_type;
-               case TypeCode.UInt16:
-                       return TypeManager.ushort_type;
-               case TypeCode.Int32:
-                       return TypeManager.int32_type;
-               case TypeCode.UInt32:
-                       return TypeManager.uint32_type;
-               case TypeCode.Int64:
-                       return TypeManager.int64_type;
-               case TypeCode.UInt64:
-                       return TypeManager.uint64_type;
-               case TypeCode.Single:
-                       return TypeManager.float_type;
-               case TypeCode.Double:
-                       return TypeManager.double_type;
-               case TypeCode.String:
-                       return TypeManager.string_type;
-               case TypeCode.Decimal:
-                       return TypeManager.decimal_type;
-               }
-
-               if (t == typeof (void))
-                       return TypeManager.void_type;
-               if (t == typeof (object))
-                       return TypeManager.object_type;
-               if (t == typeof (System.Type))
-                       return TypeManager.type_type;
-               if (t == typeof (System.IntPtr))
-                       return TypeManager.intptr_type;
-               if (t == typeof (System.UIntPtr))
-                       return TypeManager.uintptr_type;
-
-               if (t.IsArray) {
-                       int dim = t.GetArrayRank ();
-                       t = GetElementType (t);
-                       return t.MakeArrayType (dim);
-               }
-               if (t.IsByRef) {
-                       t = GetElementType (t);
-                       return t.MakeByRefType ();
-               }
-               if (t.IsPointer) {
-                       t = GetElementType (t);
-                       return t.MakePointerType ();
-               }
-
-               return t;
-       }
-
-       //
-       // Converts any type to reflection supported type
-       //
-       public static Type TypeToReflectionType (Type type)
-       {
-               // TODO: Very lame and painful, GetReference () is enough for mcs-cecil
-               if (IsDynamicType (type))
-                       return object_type;
-
-               if (type is DynamicArrayType)
-                       return type.UnderlyingSystemType;
-
-               return type;
-       }
-
-       /// <summary>
-       ///   Utility function that can be used to probe whether a type
-       ///   is managed or not.  
-       /// </summary>
-       public static bool VerifyUnmanaged (CompilerContext ctx, Type t, Location loc)
-       {
-               if (IsUnmanagedType (t))
-                       return true;
-
-               while (t.IsPointer)
-                       t = GetElementType (t);
-
-               ctx.Report.SymbolRelatedToPreviousError (t);
-               ctx.Report.Error (208, loc,
-                       "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
-                       CSharpName (t));
-
-               return false;   
-       }
-       
-       /// <summary>
-       ///   Returns the name of the indexer in a given type.
-       /// </summary>
-       /// <remarks>
-       ///   The default is not always `Item'.  The user can change this behaviour by
-       ///   using the IndexerNameAttribute in the container.
-       ///   For example, the String class indexer is named `Chars' not `Item' 
-       /// </remarks>
-       public static string IndexerPropertyName (Type t)
-       {
-               t = DropGenericTypeArguments (t);
-               if (t is TypeBuilder) {
-                       TypeContainer tc = t.IsInterface ? LookupInterface (t) : LookupTypeContainer (t);
-                       return tc == null ? TypeContainer.DefaultIndexerName : tc.IndexerName;
-               }
-
-               PredefinedAttribute pa = PredefinedAttributes.Get.DefaultMember;
-               if (pa.IsDefined) {
-                       System.Attribute attr = System.Attribute.GetCustomAttribute (
-                               t, pa.Type);
-                       if (attr != null) {
-                               DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;
-                               return dma.MemberName;
-                       }
-               }
-
-               return TypeContainer.DefaultIndexerName;
-       }
-
-       private static bool IsSignatureEqual (Type a, Type b)
-       {
-               ///
-               /// Consider the following example (bug #77674):
-               ///
-               ///     public abstract class A
-               ///     {
-               ///        public abstract T Foo<T> ();
-               ///     }
-               ///
-               ///     public abstract class B : A
-               ///     {
-               ///        public override U Foo<T> ()
-               ///        { return default (U); }
-               ///     }
-               ///
-               /// Here, `T' and `U' are method type parameters from different methods
-               /// (A.Foo and B.Foo), so both `==' and Equals() will fail.
-               ///
-               /// However, since we're determining whether B.Foo() overrides A.Foo(),
-               /// we need to do a signature based comparision and consider them equal.
-
-               if (a == b)
-                       return true;
-
-               if (a.IsGenericParameter && b.IsGenericParameter &&
-                   (a.DeclaringMethod != null) && (b.DeclaringMethod != null)) {
-                       return a.GenericParameterPosition == b.GenericParameterPosition;
-               }
-
-               if (a.IsArray && b.IsArray) {
-                       if (a.GetArrayRank () != b.GetArrayRank ())
-                               return false;
-
-                       return IsSignatureEqual (GetElementType (a), GetElementType (b));
-               }
-
-               if (a.IsByRef && b.IsByRef)
-                       return IsSignatureEqual (GetElementType (a), GetElementType (b));
-
-               if (IsGenericType (a) && IsGenericType (b)) {
-                       if (DropGenericTypeArguments (a) != DropGenericTypeArguments (b))
-                               return false;
-
-                       Type[] aargs = GetTypeArguments (a);
-                       Type[] bargs = GetTypeArguments (b);
-
-                       if (aargs.Length != bargs.Length)
-                               return false;
-
-                       for (int i = 0; i < aargs.Length; i++) {
-                               if (!IsSignatureEqual (aargs [i], bargs [i]))
-                                       return false;
-                       }
-
-                       return true;
-               }
-
-               return false;
-       }
-
-       //
-       // Returns whether the array of memberinfos contains the given method
-       //
-       public static bool ArrayContainsMethod (MethodBase [] array, MethodBase new_method, bool ignoreDeclType)
-       {
-               Type [] new_args = TypeManager.GetParameterData (new_method).Types;
-               
-               foreach (MethodBase method in array) {
-                       if (!ignoreDeclType && method.DeclaringType != new_method.DeclaringType)
-                               continue;
-               
-                       if (method.Name != new_method.Name)
-                               continue;
-
-                       if (method is MethodInfo && new_method is MethodInfo &&
-                               !IsSignatureEqual (
-                                       TypeToCoreType (((MethodInfo) method).ReturnType),
-                                       TypeToCoreType (((MethodInfo) new_method).ReturnType)))
-                               continue;
-                        
-                       Type [] old_args = TypeManager.GetParameterData (method).Types;
-                       int old_count = old_args.Length;
-                       int i;
-                       
-                       if (new_args.Length != old_count)
-                               continue;
-                       
-                       for (i = 0; i < old_count; i++){
-                               if (!IsSignatureEqual (old_args [i], new_args [i]))
-                                       break;
-                       }
-                       if (i != old_count)
-                               continue;
-
-                       return true;
-               }
-                
-               return false;
-       }
-       
-       //
-       // We copy methods from `new_members' into `target_list' if the signature
-       // for the method from in the new list does not exist in the target_list
-       //
-       // The name is assumed to be the same.
-       //
-       public static List<MethodBase> CopyNewMethods (List<MethodBase> target_list, IList<MemberInfo> new_members)
-       {
-               if (target_list == null){
-                       target_list = new List<MethodBase> ();
-
-                       foreach (MemberInfo mi in new_members){
-                               if (mi is MethodBase)
-                                       target_list.Add ((MethodBase) mi);
-                       }
-                       return target_list;
-               }
-
-               MethodBase[] target_array = new MethodBase[target_list.Count];
-               target_list.CopyTo (target_array, 0);
-               
-               foreach (MemberInfo mi in new_members){
-                       MethodBase new_method = (MethodBase) mi;
-                       
-                       if (!ArrayContainsMethod (target_array, new_method, true))
-                               target_list.Add (new_method);
-               }
-               return target_list;
-       }
-
-#region Generics
-       // <remarks>
-       //   Tracks the generic parameters.
-       // </remarks>
-
-       public static void AddTypeParameter (GenericTypeParameterBuilder t, TypeParameter tparam)
-       {
-               builder_to_type_param [t] = tparam;
-       }
-
-       public static TypeParameter LookupTypeParameter (Type t)
-       {
-               TypeParameter tp;
-               var gtp = t as GenericTypeParameterBuilder;
-               if (gtp != null && builder_to_type_param.TryGetValue (gtp, out tp))
-                       return tp;
-
-               return null;
-       }
-
-       // This method always return false for non-generic compiler,
-       // while Type.IsGenericParameter is returned if it is supported.
-       public static bool IsGenericParameter (Type type)
-       {
-               return type.IsGenericParameter;
-       }
-
-       public static int GenericParameterPosition (Type type)
-       {
-               return type.GenericParameterPosition;
-       }
-
-       public static bool IsGenericType (Type type)
-       {
-               return type.IsGenericType;
-       }
-
-       public static bool IsGenericTypeDefinition (Type type)
-       {
-               return type.IsGenericTypeDefinition;
-       }
-
-       public static bool ContainsGenericParameters (Type type)
-       {
-               return type.ContainsGenericParameters;
-       }
-
-       public static FieldInfo GetGenericFieldDefinition (FieldInfo fi)
-       {
-               if (fi.DeclaringType.IsGenericTypeDefinition ||
-                   !fi.DeclaringType.IsGenericType)
-                       return fi;
-
-               Type t = fi.DeclaringType.GetGenericTypeDefinition ();
-               BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
-                       BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-
-               // TODO: use CodeGen.Module.Builder.ResolveField (fi.MetadataToken);
-               foreach (FieldInfo f in t.GetFields (bf))
-                       if (f.MetadataToken == fi.MetadataToken)
-                               return f;
-
-               return fi;
-       }
-
-       public static bool IsEqual (Type a, Type b)
-       {
-               if (a.Equals (b)) {
-                       // MS BCL returns true even if enum types are different
-                       if (a.BaseType == TypeManager.enum_type || b.BaseType == TypeManager.enum_type)
-                               return a.FullName == b.FullName;
-
-                       // Some types are never equal
-                       if (a == TypeManager.null_type || a == InternalType.AnonymousMethod)
-                               return false;
-
-                       return true;
-               }
-
-               if (IsGenericParameter (a) && IsGenericParameter (b)) {
-                       // TODO: needs more testing before cleaning up
-                       //if (a.DeclaringMethod != b.DeclaringMethod &&
-                       //    (a.DeclaringMethod == null || b.DeclaringMethod == null))
-                       //      return false;
-                       return a.GenericParameterPosition == b.GenericParameterPosition;
-               }
-
-               if (a.IsArray && b.IsArray) {
-                       if (a.GetArrayRank () != b.GetArrayRank ())
-                               return false;
-                       return IsEqual (GetElementType (a), GetElementType (b));
-               }
-
-               if (a.IsByRef && b.IsByRef)
-                       return IsEqual (a.GetElementType (), b.GetElementType ());
-
-               if (IsGenericType (a) && IsGenericType (b)) {
-                       Type adef = DropGenericTypeArguments (a);
-                       Type bdef = DropGenericTypeArguments (b);
-
-                       if (adef != bdef)
-                               return false;
-
-                       if (adef.IsEnum && bdef.IsEnum)
-                               return true;
-
-                       Type[] aargs = GetTypeArguments (a);
-                       Type[] bargs = GetTypeArguments (b);
-
-                       if (aargs.Length != bargs.Length)
-                               return false;
-
-                       for (int i = 0; i < aargs.Length; i++) {
-                               if (!IsEqual (aargs [i], bargs [i]))
-                                       return false;
-                       }
-
-                       return true;
-               }
-
-               return false;
-       }
-
-       public static bool IsEqual (Type[] a, Type[] b)
-       {
-               if (a == null || b == null || a.Length != b.Length)
-                       return false;
-
-               for (int i = 0; i < a.Length; ++i) {
-                       if (a [i] == null || b [i] == null) {
-                               if (a [i] == b [i])
-                                       continue;
-
-                               return false;
-                       }
-               
-                       if (!IsEqual (a [i], b [i]))
-                               return false;
-               }
-
-               return true;
-       }
-
-       public static Type DropGenericTypeArguments (Type t)
-       {
-               if (!t.IsGenericType)
-                       return t;
-               // Micro-optimization: a generic typebuilder is always a generic type definition
-               if (t is TypeBuilder)
-                       return t;
-               return t.GetGenericTypeDefinition ();
-       }
-
-       public static MethodBase DropGenericMethodArguments (MethodSpec m)
-       {
-               return DropGenericMethodArguments (m.MetaInfo);
-       }
-
-       public static MethodBase DropGenericMethodArguments (MethodBase m)
-       {
-               if (m.IsGenericMethod)
-                 m = ((MethodInfo) m).GetGenericMethodDefinition ();
-
-               Type t = m.DeclaringType;
-               if (!t.IsGenericType || t.IsGenericTypeDefinition)
-                       return m;
-
-               t = t.GetGenericTypeDefinition ();
-               BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
-                       BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-
-#if MS_COMPATIBLE
-               // TODO: use CodeGen.Module.Builder.ResolveMethod ()
-               return m;
-#endif
-
-               if (m is ConstructorInfo) {
-                       foreach (ConstructorInfo c in t.GetConstructors (bf))
-                               if (c.MetadataToken == m.MetadataToken)
-                                       return c;
-               } else {
-                       foreach (MethodBase mb in t.GetMethods (bf))
-                               if (mb.MetadataToken == m.MetadataToken)
-                                       return mb;
-               }
-
-               return m;
-       }
-
-       public static Type[] GetGenericArguments (MethodBase mi)
-       {
-               return mi.GetGenericArguments () ?? Type.EmptyTypes;
-       }
-
-       public static Type[] GetTypeArguments (Type t)
-       {
-               DeclSpace tc = LookupDeclSpace (t);
-               if (tc != null) {
-                       if (!tc.IsGeneric)
-                               return Type.EmptyTypes;
-
-                       TypeParameter[] tparam = tc.TypeParameters;
-                       Type[] ret = new Type [tparam.Length];
-                       for (int i = 0; i < tparam.Length; i++) {
-                               ret [i] = tparam [i].Type;
-                               if (ret [i] == null)
-                                       throw new InternalErrorException ();
-                       }
-
-                       return ret;
-               } else
-                       return t.GetGenericArguments ();
-       }
-                       
-       public static GenericConstraints GetTypeParameterConstraints (Type t)
-       {
-               if (!t.IsGenericParameter)
-                       throw new InvalidOperationException ();
-
-               TypeParameter tparam = LookupTypeParameter (t);
-               if (tparam != null)
-                       return tparam.GenericConstraints;
-
-               return ReflectionConstraints.GetConstraints (t);
-       }
-
-       public static bool HasGenericArguments (Type t)
-       {
-               return GetNumberOfTypeArguments (t) > 0;
-       }
-
-       public static int GetNumberOfTypeArguments (Type t)
-       {
-               if (t.IsGenericParameter)
-                       return 0;
-               DeclSpace tc = LookupDeclSpace (t);
-               if (tc != null)
-                       return tc.IsGeneric ? tc.CountTypeParameters : 0;
-               else
-                       return t.IsGenericType ? t.GetGenericArguments ().Length : 0;
-       }
-
-       /// <summary>
-       ///   Check whether `type' and `parent' are both instantiations of the same
-       ///   generic type.  Note that we do not check the type parameters here.
-       /// </summary>
-       public static bool IsInstantiationOfSameGenericType (Type type, Type parent)
-       {
-               int tcount = GetNumberOfTypeArguments (type);
-               int pcount = GetNumberOfTypeArguments (parent);
-
-               if (tcount != pcount)
-                       return false;
-
-               type = DropGenericTypeArguments (type);
-               parent = DropGenericTypeArguments (parent);
-
-               return type.Equals (parent);
-       }
-
-       /// <summary>
-       ///   Whether `mb' is a generic method definition.
-       /// </summary>
-       public static bool IsGenericMethodDefinition (MethodBase mb)
-       {
-               if (mb.DeclaringType is TypeBuilder) {
-                       IMethodData method = GetMethod (mb);
-                       if (method == null)
-                               return false;
-
-                       return method.GenericMethod != null;
-               }
-
-               return mb.IsGenericMethodDefinition;
-       }
-
-       /// <summary>
-       ///   Whether `mb' is a generic method.
-       /// </summary>
-       public static bool IsGenericMethod (MethodBase mb)
-       {
-               return mb.IsGenericMethod;
-       }
-
-       public static bool IsNullableType (Type t)
-       {
-               return generic_nullable_type == DropGenericTypeArguments (t);
-       }
-
-       public static MethodInfo MakeGenericMethod (MethodInfo gmd, Type[] methodArguments) 
-       {
-               if (!gmd.IsGenericMethodDefinition)
-                       gmd = gmd.GetGenericMethodDefinition ();
-               return gmd.MakeGenericMethod (methodArguments);         
+               return generic_nullable_type == t.GetDefinition ();
        }
 #endregion
 
-#region MemberLookup implementation
-       
-       //
-       // Whether we allow private members in the result (since FindMembers
-       // uses NonPublic for both protected and private), we need to distinguish.
-       //
-
-       internal class Closure {
-               internal bool     private_ok;
-
-               // Who is invoking us and which type is being queried currently.
-               internal Type     invocation_type;
-               internal Type     qualifier_type;
-
-               // The assembly that defines the type is that is calling us
-               internal Assembly invocation_assembly;
-               internal IList<MemberInfo> almost_match;
-
-               private bool CheckValidFamilyAccess (bool is_static, MemberInfo m)
-               {
-                       if (invocation_type == null)
-                               return false;
-
-                       if (is_static && qualifier_type == null)
-                               // It resolved from a simple name, so it should be visible.
-                               return true;
-
-                       if (IsNestedChildOf (invocation_type, m.DeclaringType))
-                               return true;
-
-                       for (Type t = invocation_type; t != null; t = t.DeclaringType) {
-                               if (!IsFamilyAccessible (t, m.DeclaringType))
-                                       continue;
-
-                               // Although a derived class can access protected members of its base class
-                               // it cannot do so through an instance of the base class (CS1540).
-                               // => Ancestry should be: declaring_type ->* invocation_type ->*  qualified_type
-                               if (is_static || qualifier_type == null ||
-                                   IsInstantiationOfSameGenericType (t, qualifier_type) ||
-                                   IsFamilyAccessible (qualifier_type, t))
-                                       return true;
-                       }
-
-                       if (almost_match != null)
-                               almost_match.Add (m);
-
-                       return false;
-               }
-               
-               //
-               // This filter filters by name + whether it is ok to include private
-               // members in the search
-               //
-               internal bool Filter (MemberInfo m, object filter_criteria)
-               {
-                       //
-                       // Hack: we know that the filter criteria will always be in the
-                       // `closure' // fields. 
-                       //
-
-                       if ((filter_criteria != null) && (m.Name != (string) filter_criteria))
-                               return false;
-
-                       if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
-                           (invocation_type != null) &&
-                           IsPrivateAccessible (m.DeclaringType, invocation_type))
-                               return true;
-
-                       //
-                       // Ugly: we need to find out the type of `m', and depending
-                       // on this, tell whether we accept or not
-                       //
-                       if (m is MethodBase){
-                               MethodBase mb = (MethodBase) m;
-                               MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
-
-                               if (ma == MethodAttributes.Public)
-                                       return true;
-
-                               if (ma == MethodAttributes.PrivateScope)
-                                       return false;
-
-                               if (ma == MethodAttributes.Private)
-                                       return private_ok ||
-                                               IsPrivateAccessible (invocation_type, m.DeclaringType) ||
-                                               IsNestedChildOf (invocation_type, m.DeclaringType);
-
-                               if (TypeManager.IsThisOrFriendAssembly (invocation_assembly, mb.DeclaringType.Assembly)) {
-                                       if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
-                                               return true;
-                               } else {
-                                       if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamANDAssem)
-                                               return false;
-                               }
-
-                               // Family, FamORAssem or FamANDAssem
-                               return CheckValidFamilyAccess (mb.IsStatic, m);
-                       }
-                       
-                       if (m is FieldInfo){
-                               FieldInfo fi = (FieldInfo) m;
-                               FieldAttributes fa = fi.Attributes & FieldAttributes.FieldAccessMask;
-
-                               if (fa == FieldAttributes.Public)
-                                       return true;
-
-                               if (fa == FieldAttributes.PrivateScope)
-                                       return false;
-
-                               if (fa == FieldAttributes.Private)
-                                       return private_ok ||
-                                               IsPrivateAccessible (invocation_type, m.DeclaringType) ||
-                                               IsNestedChildOf (invocation_type, m.DeclaringType);
-
-                               if (TypeManager.IsThisOrFriendAssembly (invocation_assembly, fi.DeclaringType.Assembly)) {
-                                       if ((fa == FieldAttributes.Assembly) ||
-                                           (fa == FieldAttributes.FamORAssem))
-                                               return true;
-                               } else {
-                                       if ((fa == FieldAttributes.Assembly) ||
-                                           (fa == FieldAttributes.FamANDAssem))
-                                               return false;
-                               }
-
-                               // Family, FamORAssem or FamANDAssem
-                               return CheckValidFamilyAccess (fi.IsStatic, m);
-                       }
-
-                       //
-                       // EventInfos and PropertyInfos, return true because they lack
-                       // permission information, so we need to check later on the methods.
-                       //
-                       return true;
-               }
-       }
-
-       static Closure closure;
-       static MemberFilter FilterWithClosure_delegate;
-
        //
        // Looks up a member called `name' in the `queried_type'.  This lookup
        // is done by code that is contained in the definition for `invocation_type'
@@ -2969,485 +1035,31 @@ namespace Mono.CSharp {
        // Returns an array of a single element for everything but Methods/Constructors
        // that might return multiple matches.
        //
-       public static MemberInfo [] MemberLookup (Type invocation_type, Type qualifier_type,
-                                                 Type queried_type, MemberTypes mt,
-                                                 BindingFlags original_bf, string name, IList<MemberInfo> almost_match)
+       public static IList<MemberSpec> MemberLookup (TypeSpec invocation_type, TypeSpec qualifier_type,
+                                                 TypeSpec queried_type, MemberKind mt,
+                                                 BindingRestriction opt, string name, int arity, IList<MemberSpec> almost_match)
        {
                Timer.StartTimer (TimerType.MemberLookup);
 
-               MemberInfo[] retval = RealMemberLookup (invocation_type, qualifier_type,
-                                                       queried_type, mt, original_bf, name, almost_match);
+               var retval = RealMemberLookup (invocation_type, qualifier_type,
+                                                       queried_type, mt, opt, name, arity, almost_match);
 
                Timer.StopTimer (TimerType.MemberLookup);
 
                return retval;
        }
 
-       static MemberInfo [] RealMemberLookup (Type invocation_type, Type qualifier_type,
-                                              Type queried_type, MemberTypes mt,
-                                              BindingFlags original_bf, string name, IList<MemberInfo> almost_match)
-       {
-               BindingFlags bf = original_bf;
-               
-               List<MethodBase> method_list = null;
-               Type current_type = queried_type;
-               bool searching = (original_bf & BindingFlags.DeclaredOnly) == 0;
-               bool skip_iface_check = true, used_cache = false;
-               bool always_ok_flag = invocation_type != null && IsNestedChildOf (invocation_type, queried_type);
-
-               closure.invocation_type = invocation_type;
-               closure.invocation_assembly = invocation_type != null ? invocation_type.Assembly : null;
-               closure.qualifier_type = qualifier_type;
-               closure.almost_match = almost_match;
-
-               // This is from the first time we find a method
-               // in most cases, we do not actually find a method in the base class
-               // so we can just ignore it, and save the arraylist allocation
-               MemberInfo [] first_members_list = null;
-               bool use_first_members_list = false;
-               
-               do {
-                       MemberInfo [] list;
-
-                       //
-                       // `NonPublic' is lame, because it includes both protected and
-                       // private methods, so we need to control this behavior by
-                       // explicitly tracking if a private method is ok or not.
-                       //
-                       // The possible cases are:
-                       //    public, private and protected (internal does not come into the
-                       //    equation)
-                       //
-                       if ((invocation_type != null) &&
-                           ((invocation_type == current_type) ||
-                            IsNestedChildOf (invocation_type, current_type)) ||
-                           always_ok_flag)
-                               bf = original_bf | BindingFlags.NonPublic;
-                       else
-                               bf = original_bf;
-
-                       closure.private_ok = (original_bf & BindingFlags.NonPublic) != 0;
-
-                       Timer.StopTimer (TimerType.MemberLookup);
-
-                       list = MemberLookup_FindMembers (current_type, mt, bf, name, out used_cache);
-
-                       Timer.StartTimer (TimerType.MemberLookup);
-
-                       //
-                       // When queried for an interface type, the cache will automatically check all
-                       // inherited members, so we don't need to do this here.  However, this only
-                       // works if we already used the cache in the first iteration of this loop.
-                       //
-                       // If we used the cache in any further iteration, we can still terminate the
-                       // loop since the cache always looks in all base classes.
-                       //
-
-                       if (used_cache)
-                               searching = false;
-                       else
-                               skip_iface_check = false;
-
-                       if (current_type == TypeManager.object_type)
-                               searching = false;
-                       else {
-                               current_type = current_type.BaseType;
-                               
-                               //
-                               // This happens with interfaces, they have a null
-                               // basetype.  Look members up in the Object class.
-                               //
-                               if (current_type == null) {
-                                       current_type = TypeManager.object_type;
-                                       searching = true;
-                               }
-                       }
-                       
-                       if (list.Length == 0)
-                               continue;
-
-                       //
-                       // Events and types are returned by both `static' and `instance'
-                       // searches, which means that our above FindMembers will
-                       // return two copies of the same.
-                       //
-                       if (list.Length == 1 && !(list [0] is MethodBase)){
-                               return list;
-                       }
-
-                       //
-                       // Multiple properties: we query those just to find out the indexer
-                       // name
-                       //
-                       if (list [0] is PropertyInfo)
-                               return list;
-
-                       //
-                       // We found an event: the cache lookup returns both the event and
-                       // its private field.
-                       //
-                       if (list [0] is EventInfo) {
-                               if ((list.Length == 2) && (list [1] is FieldInfo))
-                                       return new MemberInfo [] { list [0] };
-
-                               return list;
-                       }
-
-                       //
-                       // We found methods, turn the search into "method scan"
-                       // mode.
-                       //
-
-                       if (first_members_list != null) {
-                               if (use_first_members_list) {
-                                       method_list = CopyNewMethods (method_list, first_members_list);
-                                       use_first_members_list = false;
-                               }
-                               
-                               method_list = CopyNewMethods (method_list, list);
-                       } else {
-                               first_members_list = list;
-                               use_first_members_list = true;
-                               mt &= (MemberTypes.Method | MemberTypes.Constructor);
-                       }
-               } while (searching);
-
-               if (use_first_members_list)
-                       return first_members_list;
-
-               if (method_list != null && method_list.Count > 0) {
-                       return method_list.ToArray ();
-               }
-               //
-               // This happens if we already used the cache in the first iteration, in this case
-               // the cache already looked in all interfaces.
-               //
-               if (skip_iface_check)
-                       return null;
-
-               //
-               // Interfaces do not list members they inherit, so we have to
-               // scan those.
-               // 
-               if (!queried_type.IsInterface)
-                       return null;
-
-               if (queried_type.IsArray)
-                       queried_type = TypeManager.array_type;
-               
-               Type [] ifaces = GetInterfaces (queried_type);
-               if (ifaces == null)
-                       return null;
-               
-               foreach (Type itype in ifaces){
-                       MemberInfo [] x;
-
-                       x = MemberLookup (null, null, itype, mt, bf, name, null);
-                       if (x != null)
-                               return x;
-               }
-                                       
-               return null;
-       }
-
-       public const BindingFlags AllMembers = BindingFlags.Public | BindingFlags.NonPublic |
-                                                                       BindingFlags.Static | BindingFlags.Instance | 
-                                                                       BindingFlags.DeclaredOnly;
-
-       // Currently is designed to work with external types only
-       public static PropertyInfo GetPropertyFromAccessor (MethodBase mb)
-       {
-               if (!mb.IsSpecialName)
-                       return null;
-
-               string name = mb.Name;
-               if (name.Length < 5)
-                       return null;
-
-               if (name [3] != '_')
-                       return null;
-
-               if (name.StartsWith ("get") || name.StartsWith ("set")) {
-                       MemberInfo[] pi = mb.DeclaringType.FindMembers (MemberTypes.Property, AllMembers,
-                               Type.FilterName, name.Substring (4));
-
-                       if (pi == null)
-                               return null;
-
-                       // This can happen when property is indexer (it can have same name but different parameters)
-                       foreach (PropertyInfo p in pi) {
-                               foreach (MethodInfo p_mi in p.GetAccessors (true)) {
-                                       if (p_mi == mb || TypeManager.GetParameterData (p_mi).Equals (TypeManager.GetParameterData (mb)))
-                                               return p;
-                               }
-                       }
-               }
-
-               return null;
-       }
-
-       // Currently is designed to work with external types only
-       public static MemberInfo GetEventFromAccessor (MethodBase mb)
-       {
-               if (!mb.IsSpecialName)
-                       return null;
-
-               string name = mb.Name;
-               if (name.Length < 5)
-                       return null;
-
-               if (name.StartsWith ("add_"))
-                       return mb.DeclaringType.GetEvent (name.Substring (4), AllMembers);
-
-               if (name.StartsWith ("remove_"))
-                       return mb.DeclaringType.GetEvent (name.Substring (7), AllMembers);
-
-               return null;
-       }
-
-       // Tests whether external method is really special
-       public static bool IsSpecialMethod (MethodBase mb)
-       {
-               if (!mb.IsSpecialName)
-                       return false;
-
-               IMethodData md = TypeManager.GetMethod (mb);
-               if (md != null) 
-                       return (md is AbstractPropertyEventMethod || md is Operator);
-
-               PropertyInfo pi = GetPropertyFromAccessor (mb);
-               if (pi != null)
-                       return IsValidProperty (pi);
-                               
-               if (GetEventFromAccessor (mb) != null)
-                       return true;
-
-               string name = mb.Name;
-               if (name.StartsWith ("op_"))
-                       return Operator.GetName (name) != null;
-
-               return false;
-       }
-
-       // Tests whether imported property is valid C# property.
-       // TODO: It seems to me that we should do a lot of sanity tests before
-       // we accept property as C# property
-       static bool IsValidProperty (PropertyInfo pi)
+       static IList<MemberSpec> RealMemberLookup (TypeSpec invocation_type, TypeSpec qualifier_type,
+                                                  TypeSpec queried_type, MemberKind mt,
+                                                  BindingRestriction bf, string name, int arity, IList<MemberSpec> almost_match)
        {
-               MethodInfo get_method = pi.GetGetMethod (true);
-               MethodInfo set_method = pi.GetSetMethod (true);
-               int g_count = 0;
-               int s_count = 0;
-               if (get_method != null && set_method != null) {
-                       g_count = get_method.GetParameters ().Length;
-                       s_count = set_method.GetParameters ().Length;
-                       if (g_count + 1 != s_count)
-                               return false;
-               } else if (get_method != null) {
-                       g_count = get_method.GetParameters ().Length;
-               } else if (set_method != null) {
-                       s_count = set_method.GetParameters ().Length;
-               }
-
-               //
-               // DefaultMemberName and indexer name has to match to identify valid C# indexer
-               //
-               PredefinedAttribute pa = PredefinedAttributes.Get.DefaultMember;
-               if ((s_count > 1 || g_count > 0) && pa.IsDefined) {
-                       object[] o = pi.DeclaringType.GetCustomAttributes (pa.Type, false);
-                       if (o.Length == 0)
-                               return false;
-                       
-                       DefaultMemberAttribute dma = (DefaultMemberAttribute) o [0];
-                       if (dma.MemberName != pi.Name)
-                               return false;
-                       if (get_method != null && "get_" + dma.MemberName != get_method.Name)
-                               return false;
-                       if (set_method != null && "set_" + dma.MemberName != set_method.Name)
-                               return false;
+               MemberFilter filter = new MemberFilter (name, arity, mt, null, null);
+               if ((bf & BindingRestriction.AccessibleOnly) != 0) {
+                       filter.InvocationType = invocation_type ?? InternalType.FakeInternalType;
                }
 
-               return true;
-       }
-
-#endregion
-       
+               return MemberCache.FindMembers (queried_type, filter, bf);
+       }       
 }
 
-       class InternalType
-       {
-               public static readonly Type AnonymousMethod = typeof (AnonymousMethodBody);
-               public static readonly Type Arglist = typeof (ArglistAccess);
-               public static readonly Type Dynamic = new DynamicType ();
-               public static readonly Type MethodGroup = typeof (MethodGroupExpr);
-       }
-
-/// <summary>
-///   There is exactly one instance of this class per type.
-/// </summary>
-sealed class TypeHandle : IMemberContainer {
-       public readonly IMemberContainer BaseType;
-
-       readonly int id = ++next_id;
-       static int next_id = 0;
-
-       static TypeHandle ()
-       {
-               Reset ();
-       }
-
-       /// <summary>
-       ///   Lookup a TypeHandle instance for the given type.  If the type doesn't have
-       ///   a TypeHandle yet, a new instance of it is created.  This static method
-       ///   ensures that we'll only have one TypeHandle instance per type.
-       /// </summary>
-       private static TypeHandle GetTypeHandle (Type t)
-       {
-               TypeHandle handle;
-               if (type_hash.TryGetValue (t, out handle))
-                       return handle;
-
-               handle = new TypeHandle (t);
-               type_hash.Add (t, handle);
-               return handle;
-       }
-
-       public static MemberCache GetMemberCache (Type t)
-       {
-               return GetTypeHandle (t).MemberCache;
-       }
-       
-       public static void CleanUp ()
-       {
-               type_hash = null;
-       }
-
-       public static void Reset ()
-       {
-               type_hash = new Dictionary<Type, TypeHandle> (ReferenceEquality<Type>.Default);
-       }
-
-       /// <summary>
-       ///   Returns the TypeHandle for TypeManager.object_type.
-       /// </summary>
-       public static IMemberContainer ObjectType {
-               get {
-                       if (object_type != null)
-                               return object_type;
-
-                       object_type = GetTypeHandle (TypeManager.object_type);
-
-                       return object_type;
-               }
-       }
-
-       /// <summary>
-       ///   Returns the TypeHandle for TypeManager.array_type.
-       /// </summary>
-       public static TypeHandle ArrayType {
-               get {
-                       if (array_type != null)
-                               return array_type;
-
-                       array_type = GetTypeHandle (TypeManager.array_type);
-
-                       return array_type;
-               }
-       }
-
-       static Dictionary<Type, TypeHandle> type_hash;
-
-       private static TypeHandle object_type;
-       private static TypeHandle array_type;
-
-       private Type type;
-       private string full_name;
-       private bool is_interface;
-       private MemberCache member_cache;
-       private MemberCache base_cache;
-
-       private TypeHandle (Type type)
-       {
-               this.type = type;
-               full_name = type.FullName != null ? type.FullName : type.Name;
-               if (type.BaseType != null) {
-                       base_cache = TypeManager.LookupMemberCache (type.BaseType);
-                       BaseType = base_cache.Container;
-               } else if (type.IsInterface)
-                       base_cache = TypeManager.LookupBaseInterfacesCache (type);
-               this.is_interface = type.IsInterface || TypeManager.IsGenericParameter (type);
-               this.member_cache = new MemberCache (this);
-       }
-
-       // IMemberContainer methods
-
-       public string Name {
-               get {
-                       return full_name;
-               }
-       }
-
-       public Type Type {
-               get {
-                       return type;
-               }
-       }
-
-       public MemberCache BaseCache {
-               get {
-                       return base_cache;
-               }
-       }
-
-       public bool IsInterface {
-               get {
-                       return is_interface;
-               }
-       }
-
-       public MemberList GetMembers (MemberTypes mt, BindingFlags bf)
-       {
-               MemberInfo [] members;
-
-               if (type is GenericTypeParameterBuilder)
-                       return MemberList.Empty;
-
-#if MS_COMPATIBLE
-               type = TypeManager.DropGenericTypeArguments (type);
-#endif
-               if (mt == MemberTypes.Event)
-                       members = type.GetEvents (bf | BindingFlags.DeclaredOnly);
-               else
-                       members = type.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
-                                                                               null, null);
-
-               if (members.Length == 0)
-                       return MemberList.Empty;
-
-               Array.Reverse (members);
-               return new MemberList (members);
-       }
-
-       // IMemberFinder methods
-
-       public MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name,
-                                      MemberFilter filter, object criteria)
-       {
-               return new MemberList (member_cache.FindMembers (mt, bf, name, filter, criteria));
-       }
-
-       public MemberCache MemberCache {
-               get {
-                       return member_cache;
-               }
-       }
-
-       public override string ToString ()
-       {
-               if (BaseType != null)
-                       return "TypeHandle (" + id + "," + Name + " : " + BaseType + ")";
-               else
-                       return "TypeHandle (" + id + "," + Name + ")";
-       }
-}
 }
index 641e37707edcfd092597ffc06913e1c588590e55..2a4b8a06bad466ffe48cbad1d1739a31263082b3 100644 (file)
 
 using System;
 using System.Collections.Generic;
+using System.Text;
+using System.Linq;
 
 namespace Mono.CSharp
 {
        public class TypeSpec : MemberSpec
        {
-               Type info;
+               protected Type info;
                protected MemberCache cache;
+               protected IList<TypeSpec> ifaces;
+               TypeSpec base_type;
 
-               public TypeSpec (MemberKind kind, ITypeDefinition definition, Type info, string name, Modifiers modifiers)
-                       : base (kind, definition, name, modifiers)
+               Dictionary<TypeSpec[], InflatedTypeSpec> inflated_instances;
+
+               public static readonly TypeSpec[] EmptyTypes = new TypeSpec[0];
+
+               // Reflection Emit hacking
+               static Type TypeBuilder;
+               static Type GenericTypeBuilder;
+
+               static TypeSpec ()
+               {
+                       var assembly = typeof (object).Assembly;
+                       TypeBuilder = assembly.GetType ("System.Reflection.Emit.TypeBuilder");
+                       GenericTypeBuilder = assembly.GetType ("System.Reflection.MonoGenericClass");
+                       if (GenericTypeBuilder == null)
+                               GenericTypeBuilder = assembly.GetType ("System.Reflection.Emit.TypeBuilderInstantiation");
+               }
+
+               public TypeSpec (MemberKind kind, TypeSpec declaringType, ITypeDefinition definition, Type info, Modifiers modifiers)
+                       : base (kind, declaringType, definition, modifiers)
                {
+                       this.declaringType = declaringType;
                        this.info = info;
+
+                       if (definition != null && definition.TypeParametersCount > 0)
+                               state |= StateFlags.IsGeneric;
+               }
+
+               #region Properties
+
+               public override int Arity {
+                       get {
+                               return MemberDefinition.TypeParametersCount;
+                       }
+               }
+
+               public virtual TypeSpec BaseType {
+                       get {
+                               return base_type;
+                       }
+                       set {
+                               base_type = value;
+                       }
+               }
+
+               public virtual IList<TypeSpec> Interfaces {
+                       get {
+                               return ifaces;
+                       }
+                       set {
+                               ifaces = value;
+                       }
+               }
+
+               public bool IsArray {
+                       get { return this is ArrayContainer; }
+               }
+
+               public bool IsAttribute {
+                       get {
+                               if (!IsClass)
+                                       return false;
+
+                               var type = this;
+                               do {
+                                       if (type.IsGeneric)
+                                               return false;
+
+                                       if (type == TypeManager.attribute_type)
+                                               return true;
+                                       
+                                       type = type.base_type;
+                               } while (type != null);
+
+                               return false;
+                       }
+               }
+
+               public bool IsInterface {
+                       get {
+                               return Kind == MemberKind.Interface;
+                       }
+               }
+
+               public bool IsClass {
+                       get {
+                               return Kind == MemberKind.Class;
+                       }
+               }
+
+               public bool IsConstantCompatible {
+                       get {
+                               if ((Kind & (MemberKind.Enum | MemberKind.Class | MemberKind.Interface | MemberKind.Delegate)) != 0)
+                                       return true;
+
+                               return TypeManager.IsPrimitiveType (this) || this == TypeManager.decimal_type || this == InternalType.Dynamic;
+                       }
+               }
+
+               public bool IsDelegate {
+                       get {
+                               return Kind == MemberKind.Delegate;
+                       }
                }
 
-               public TypeSpec BaseType { get; set; }
+               public bool IsEnum {
+                       get { return Kind == MemberKind.Enum; }
+               }
+
+               // TODO: Should probably do
+               // IsGenericType -- recursive
+               // HasTypeParameter -- non-recursive
+               public bool IsGenericOrParentIsGeneric {
+                       get {
+                               var ts = this;
+                               do {
+                                       if (ts.IsGeneric)
+                                               return true;
+                                       ts = ts.declaringType;
+                               } while (ts != null);
+
+                               return false;
+                       }
+               }
+
+               public bool IsGenericParameter {
+                       get { return Kind == MemberKind.TypeParameter; }
+               }
+
+               public bool IsNested {
+                       get { return declaringType != null && Kind != MemberKind.TypeParameter; }
+               }
+
+               public bool IsPointer {
+                       get {
+                               return Kind == MemberKind.PointerType;
+                       }
+               }
+
+               public bool IsSealed {
+                       get { return (Modifiers & Modifiers.SEALED) != 0; }
+               }
 
-               public override Type DeclaringType {
-                       get { return info.DeclaringType; }
+               public bool IsStruct {
+                       get { 
+                               return Kind == MemberKind.Struct;
+                       }
                }
 
-               public Type MetaInfo {
-                       get { return info; }
+               public bool IsTypeBuilder {
+                       get {
+                               var meta = GetMetaInfo().GetType ();
+                               return meta == TypeBuilder || meta == GenericTypeBuilder;
+                       }
                }
 
                public MemberCache MemberCache {
                        get {
-                               if (cache == null) {
-//                                     cache = new MemberCache (BaseType);
+                               if (cache == null || (state & StateFlags.PendingMemberCacheMembers) != 0)
+                                       InitializeMemberCache (false);
+
+                               return cache;
+                       }
+                       set {
+                               if (cache != null)
+                                       throw new InternalErrorException ("Membercache reset");
+
+                               cache = value;
+                       }
+               }
+
+               public virtual MemberCache MemberCacheTypes {
+                       get {
+                               return MemberCache;
+                       }
+               }       
+
+               public new ITypeDefinition MemberDefinition {
+                       get {
+                               return (ITypeDefinition) definition;
+                       }
+               }
+
+               // TODO: Wouldn't be better to rely on cast to InflatedTypeSpec and
+               // remove the property, YES IT WOULD !!!
+               public virtual TypeSpec[] TypeArguments {
+                       get { return TypeSpec.EmptyTypes; }
+               }
+
+               #endregion
+
+               public bool AddInterface (TypeSpec iface)
+               {
+                       if ((state & StateFlags.InterfacesExpanded) != 0)
+                               throw new InternalErrorException ("Modifying expanded interface list");
+
+                       if (ifaces == null) {
+                               ifaces = new List<TypeSpec> () { iface };
+                               return true;
+                       }
+
+                       if (!ifaces.Contains (iface)) {
+                               ifaces.Add (iface);
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
+               {
+                       if (Kind != MemberKind.Class)
+                               throw new InternalErrorException ();
+
+                       if (!pa.IsDefined)
+                               return Attribute.DefaultUsageAttribute;
+
+                       var aua = MemberDefinition.GetAttributeUsage (pa);
+                       return aua ?? Attribute.DefaultUsageAttribute;
+               }
 
-//                                     ((ITypeDefinition) definition).LoadMembers (cache);
+               public virtual Type GetMetaInfo ()
+               {
+                       return info;
+               }
+
+               public virtual TypeSpec GetDefinition ()
+               {
+                       return this;
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       string s;
+
+                       if (IsNested) {
+                               s = DeclaringType.GetSignatureForError ();
+                       } else {
+                               s = MemberDefinition.Namespace;
+                       }
+
+                       if (!string.IsNullOrEmpty (s))
+                               s += ".";
+
+                       return s + Name + GetTypeNameSignature ();
+               }
+
+               protected virtual string GetTypeNameSignature ()
+               {
+                       if (!IsGeneric)
+                               return null;
+
+                       return "<" + TypeManager.CSharpName (MemberDefinition.TypeParameters) + ">";
+               }
+
+               public bool ImplementsInterface (TypeSpec iface)
+               {
+                       var t = this;
+                       do {
+                               if (t.Interfaces != null) {     // TODO: Try t.iface
+                                       foreach (TypeSpec i in t.Interfaces) {
+                                               if (i == iface || TypeSpecComparer.Variant.IsEqual (i, iface))
+                                                       return true;
+                                       }
                                }
 
-                               return cache;
+                               t = t.BaseType;
+                       } while (t != null);
+
+                       return false;
+               }
+
+               protected virtual void InitializeMemberCache (bool onlyTypes)
+               {
+                       //
+                       // Not interested in members of nested private types
+                       //
+                       if (IsPrivate) {
+                               cache = new MemberCache (0);
+                       } else {
+                               cache = MemberDefinition.LoadMembers (this);
+                       }
+               }
+
+               public override MemberSpec InflateMember (TypeParameterInflator inflator)
+               {
+                       var targs = IsGeneric ? MemberDefinition.TypeParameters : TypeSpec.EmptyTypes;
+
+                       //
+                       // When inflating nested type from inside the type instance will be same
+                       // because type parameters are same for all nested types
+                       //
+                       if (DeclaringType == inflator.TypeInstance)
+                               return MakeGenericType (targs);
+
+                       return new InflatedTypeSpec (this, inflator.TypeInstance, targs);
+               }
+
+               public InflatedTypeSpec MakeGenericType (TypeSpec[] targs)
+               {
+                       if (targs.Length == 0 && !IsNested)
+                               throw new ArgumentException ("Empty type arguments");
+
+                       InflatedTypeSpec instance;
+
+                       if (inflated_instances == null)
+                               inflated_instances = new Dictionary<TypeSpec[], InflatedTypeSpec> (TypeSpecComparer.Default);
+
+                       if (!inflated_instances.TryGetValue (targs, out instance)) {
+                               if (GetDefinition () != this && !IsNested)
+                                       throw new InternalErrorException ("Only type definition or nested non-inflated types can be used to call MakeGenericType");
+
+                               instance = new InflatedTypeSpec (this, declaringType, targs);
+                               inflated_instances.Add (targs, instance);
+                       }
+
+                       return instance;
+               }
+
+               public virtual TypeSpec Mutate (TypeParameterMutator mutator)
+               {
+                       return this;
+               }
+
+               public void SetMetaInfo (Type info)
+               {
+                       if (this.info != null)
+                               throw new InternalErrorException ("MetaInfo reset");
+
+                       this.info = info;
+               }
+
+               public void SetExtensionMethodContainer ()
+               {
+                       modifiers |= Modifiers.METHOD_EXTENSION;
+               }
+       }
+
+       public class PredefinedTypeSpec : TypeSpec
+       {
+               string name;
+               string ns;
+
+               public PredefinedTypeSpec (MemberKind kind, string ns, string name)
+                       : base (kind, null, null, null, Modifiers.PUBLIC)
+               {
+                       this.name = name;
+                       this.ns = ns;
+               }
+
+               public override int Arity {
+                       get {
+                               return 0;
+                       }
+               }
+
+               public override string Name {
+                       get {
+                               return name;
+                       }
+               }
+
+               public string Namespace {
+                       get {
+                               return ns;
+                       }
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       switch (name) {
+                       case "Int32": return "int";
+                       case "Int64": return "long";
+                       case "String": return "string";
+                       case "Boolean": return "bool";
+                       case "Void": return "void";
+                       case "Object": return "object";
+                       case "UInt32": return "uint";
+                       case "Int16": return "short";
+                       case "UInt16": return "ushort";
+                       case "UInt64": return "ulong";
+                       case "Single": return "float";
+                       case "Double": return "double";
+                       case "Decimal": return "decimal";
+                       case "Char": return "char";
+                       case "Byte": return "byte";
+                       case "SByte": return "sbyte";
+                       }
+
+                       return ns + "." + name;
+               }
+
+               public void SetDefinition (ITypeDefinition td, Type type)
+               {
+                       this.definition = td;
+                       this.info = type;
+               }
+
+               public void SetDefinition (TypeSpec ts)
+               {
+                       this.definition = ts.MemberDefinition;
+                       this.info = ts.GetMetaInfo ();
+                       this.BaseType = ts.BaseType;
+                       this.Interfaces = ts.Interfaces;
+               }
+       }
+
+       static class TypeSpecComparer
+       {
+               //
+               // Default reference comparison
+               //
+               public static readonly DefaultImpl Default = new DefaultImpl ();
+
+               public class DefaultImpl : IEqualityComparer<TypeSpec[]>, IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>
+               {
+                       #region IEqualityComparer<TypeSpec[]> Members
+
+                       public bool Equals (TypeSpec[] x, TypeSpec[] y)
+                       {
+                               if (x.Length != y.Length)
+                                       return false;
+
+                               if (x == y)
+                                       return true;
+
+                               for (int i = 0; i < x.Length; ++i)
+                                       if (x[i] != y[i])
+                                               return false;
+
+                               return true;
+                       }
+
+                       public int GetHashCode (TypeSpec[] obj)
+                       {
+                               int hash = 0;
+                               for (int i = 0; i < obj.Length; ++i)
+                                       hash = (hash << 5) - hash + obj[i].GetHashCode ();
+
+                               return hash;
+                       }
+
+                       #endregion
+
+                       #region IEqualityComparer<Tuple<TypeSpec,TypeSpec[]>> Members
+
+                       bool IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>.Equals (Tuple<TypeSpec, TypeSpec[]> x, Tuple<TypeSpec, TypeSpec[]> y)
+                       {
+                               return Equals (x.Item2, y.Item2) && x.Item1 == y.Item1;
+                       }
+
+                       int IEqualityComparer<Tuple<TypeSpec, TypeSpec[]>>.GetHashCode (Tuple<TypeSpec, TypeSpec[]> obj)
+                       {
+                               return GetHashCode (obj.Item2) ^ obj.Item1.GetHashCode ();
+                       }
+
+                       #endregion
+               }
+
+               //
+               // When comparing type signature of overrides or overloads
+               // this version tolerates different MVARs at same position
+               //
+               public static class Override
+               {
+                       public static bool IsEqual (TypeSpec a, TypeSpec b)
+                       {
+                               if (a == b)
+                                       return true;
+
+                               //
+                               // Consider the following example:
+                               //
+                               //     public abstract class A
+                               //     {
+                               //        public abstract T Foo<T>();
+                               //     }
+                               //
+                               //     public class B : A
+                               //     {
+                               //        public override U Foo<T>() { return default (U); }
+                               //     }
+                               //
+                               // Here, `T' and `U' are method type parameters from different methods
+                               // (A.Foo and B.Foo), so both `==' and Equals() will fail.
+                               //
+                               // However, since we're determining whether B.Foo() overrides A.Foo(),
+                               // we need to do a signature based comparision and consider them equal.
+                               //
+
+                               var tp_a = a as TypeParameterSpec;
+                               if (tp_a != null) {
+                                       var tp_b = b as TypeParameterSpec;
+                                       return tp_b != null && tp_a.IsMethodOwned == tp_b.IsMethodOwned && tp_a.DeclaredPosition == tp_b.DeclaredPosition;
+                               }
+
+                               if (a.TypeArguments.Length != b.TypeArguments.Length)
+                                       return false;
+
+                               if (a.TypeArguments.Length != 0) {
+                                       if (a.MemberDefinition != b.MemberDefinition)
+                                               return false;
+
+                                       for (int i = 0; i < a.TypeArguments.Length; ++i) {
+                                               if (!IsEqual (a.TypeArguments[i], b.TypeArguments[i]))
+                                                       return false;
+                                       }
+
+                                       return true;
+                               }
+
+                               var ac_a = a as ArrayContainer;
+                               if (ac_a != null) {
+                                       var ac_b = b as ArrayContainer;
+                                       return ac_b != null && ac_a.Rank == ac_b.Rank && IsEqual (ac_a.Element, ac_b.Element);
+                               }
+
+                               if (a == InternalType.Dynamic || b == InternalType.Dynamic)
+                                       return b == TypeManager.object_type || a == TypeManager.object_type;
+
+                               return false;
+                       }
+
+                       //
+                       // Compares unordered arrays
+                       //
+                       public static bool IsSame (TypeSpec[] a, TypeSpec[] b)
+                       {
+                               if (a == b)
+                                       return true;
+
+                               if (a == null || b == null || a.Length != b.Length)
+                                       return false;
+
+                               for (int ai = 0; ai < a.Length; ++ai) {
+                                       bool found = false;
+                                       for (int bi = 0; bi < b.Length; ++bi) {
+                                               if (IsEqual (a[ai], b[bi])) {
+                                                       found = true;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (!found)
+                                               return false;
+                               }
+
+                               return true;
+                       }
+
+                       public static bool IsEqual (AParametersCollection a, AParametersCollection b)
+                       {
+                               if (a == b)
+                                       return true;
+
+                               if (a.Count != b.Count)
+                                       return false;
+
+                               for (int i = 0; i < a.Count; ++i) {
+                                       if (!IsEqual (a.Types[i], b.Types[i]))
+                                               return false;
+
+                                       const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
+                                       if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
+                                               return false;
+                               }
+
+                               return true;
+                       }
+               }
+
+               //
+               // Type variance equality comparison
+               //
+               public static class Variant
+               {
+                       public static bool IsEqual (TypeSpec type1, TypeSpec type2)
+                       {
+                               if (!type1.IsGeneric || !type2.IsGeneric)
+                                       return false;
+
+                               var target_type_def = type2.MemberDefinition;
+                               if (type1.MemberDefinition != target_type_def)
+                                       return false;
+
+                               if (!type1.IsInterface && !type1.IsDelegate)
+                                       return false;
+
+                               var t1_targs = type1.TypeArguments;
+                               var t2_targs = type2.TypeArguments;
+                               var targs_definition = target_type_def.TypeParameters;
+                               for (int i = 0; i < targs_definition.Length; ++i) {
+                                       Variance v = targs_definition[i].Variance;
+                                       if (v == Variance.None) {
+                                               if (t1_targs[i] == t2_targs[i])
+                                                       continue;
+                                               return false;
+                                       }
+
+                                       if (v == Variance.Covariant) {
+                                               if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t1_targs[i]), t2_targs[i]))
+                                                       return false;
+                                       } else if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t2_targs[i]), t1_targs[i])) {
+                                               return false;
+                                       }
+                               }
+
+                               return true;
+                       }
+               }
+
+               //
+               // Checks whether two generic instances may become equal for some
+               // particular instantiation (26.3.1).
+               //
+               public static class Unify
+               {
+                       //
+                       // Either @a or @b must be generic type
+                       //
+                       public static bool IsEqual (TypeSpec a, TypeSpec b)
+                       {
+                               if (a.MemberDefinition != b.MemberDefinition)
+                                       return false;
+
+                               var ta = a.TypeArguments;
+                               var tb = b.TypeArguments;
+                               for (int i = 0; i < ta.Length; i++) {
+                                       if (!MayBecomeEqualGenericTypes (ta[i], tb[i]))
+                                               return false;
+                               }
+
+                               return true;
+                       }
+
+                       /// <summary>
+                       ///   Check whether `a' and `b' may become equal generic types.
+                       ///   The algorithm to do that is a little bit complicated.
+                       /// </summary>
+                       static bool MayBecomeEqualGenericTypes (TypeSpec a, TypeSpec b)
+                       {
+                               if (a.IsGenericParameter) {
+                                       //
+                                       // If a is an array of a's type, they may never
+                                       // become equal.
+                                       //
+                                       if (b.IsArray)
+                                               return false;
+
+                                       //
+                                       // If b is a generic parameter or an actual type,
+                                       // they may become equal:
+                                       //
+                                       //    class X<T,U> : I<T>, I<U>
+                                       //    class X<T> : I<T>, I<float>
+                                       // 
+                                       if (b.IsGenericParameter)
+                                               return a.DeclaringType == b.DeclaringType;
+
+                                       //
+                                       // We're now comparing a type parameter with a
+                                       // generic instance.  They may become equal unless
+                                       // the type parameter appears anywhere in the
+                                       // generic instance:
+                                       //
+                                       //    class X<T,U> : I<T>, I<X<U>>
+                                       //        -> error because you could instanciate it as
+                                       //           X<X<int>,int>
+                                       //
+                                       //    class X<T> : I<T>, I<X<T>> -> ok
+                                       //
+
+                                       TypeSpec[] bargs = b.TypeArguments;
+                                       for (int i = 0; i < bargs.Length; i++) {
+                                               if (a.Equals (bargs[i]))
+                                                       return false;
+                                       }
+
+                                       return true;
+                               }
+
+                               if (b.IsGenericParameter)
+                                       return MayBecomeEqualGenericTypes (b, a);
+
+                               //
+                               // At this point, neither a nor b are a type parameter.
+                               //
+                               // If one of them is a generic instance, compare them (if the
+                               // other one is not a generic instance, they can never
+                               // become equal).
+                               //
+                               if (TypeManager.IsGenericType (a) || TypeManager.IsGenericType (b))
+                                       return IsEqual (a, b);
+
+                               //
+                               // If both of them are arrays.
+                               //
+                               var a_ac = a as ArrayContainer;
+                               if (a_ac != null) {
+                                       var b_ac = b as ArrayContainer;
+                                       if (b_ac == null || a_ac.Rank != b_ac.Rank)
+                                               return false;
+
+                                       return MayBecomeEqualGenericTypes (a_ac.Element, b_ac.Element);
+                               }
+
+                               //
+                               // Ok, two ordinary types.
+                               //
+                               return false;
                        }
                }
        }
 
        public interface ITypeDefinition : IMemberDefinition
        {
-               void LoadMembers (MemberCache cache);
+               string Namespace { get; }
+               int TypeParametersCount { get; }
+               TypeParameterSpec[] TypeParameters { get; }
+
+               TypeSpec GetAttributeCoClass ();
+               string GetAttributeDefaultMember ();
+               AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa);
+               MemberCache LoadMembers (TypeSpec declaringType);
        }
-/*
+
        class InternalType : TypeSpec
        {
+               private class DynamicType : InternalType
+               {
+                       public DynamicType ()
+                               : base ("dynamic")
+                       {
+                       }
+
+                       public override Type GetMetaInfo ()
+                       {
+                               return typeof (object);
+                       }
+               }
+
                public static readonly TypeSpec AnonymousMethod = new InternalType ("anonymous method");
                public static readonly TypeSpec Arglist = new InternalType ("__arglist");
-//             public static readonly TypeSpec Dynamic = new DynamicType ();
+               public static readonly TypeSpec Dynamic = new DynamicType ();
                public static readonly TypeSpec MethodGroup = new InternalType ("method group");
+               public static readonly TypeSpec Null = new InternalType ("null");
+               public static readonly TypeSpec FakeInternalType = new InternalType ("<fake$type>");
+
+               readonly string name;
 
                protected InternalType (string name)
-                       : base (null, null, name, Modifiers.PUBLIC)
+                       : base (MemberKind.InternalCompilerType, null, null, null, Modifiers.PUBLIC)
+               {
+                       this.name = name;
+                       cache = MemberCache.Empty;
+
+                       // Make all internal types CLS-compliant, non-obsolete
+                       state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant;
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       return name;
+               }
+       }
+
+       public abstract class ElementTypeSpec : TypeSpec
+       {
+               protected ElementTypeSpec (MemberKind kind, TypeSpec element, Type info)
+                       : base (kind, element.DeclaringType, element.MemberDefinition, info, element.Modifiers)
+               {
+                       this.Element = element;
+                       cache = MemberCache.Empty;
+               }
+
+               #region Properties
+
+               public TypeSpec Element { get; private set; }
+
+               public override string Name {
+                       get {
+                               throw new NotSupportedException ();
+                       }
+               }
+
+               #endregion
+
+               public override ObsoleteAttribute GetAttributeObsolete ()
+               {
+                       return Element.GetAttributeObsolete ();
+               }
+
+               protected virtual string GetPostfixSignature ()
+               {
+                       return null;
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       return Element.GetSignatureForError () + GetPostfixSignature ();
+               }
+
+               public override TypeSpec Mutate (TypeParameterMutator mutator)
+               {
+                       var me = Element.Mutate (mutator);
+                       if (me == Element)
+                               return this;
+
+                       var mutated = (ElementTypeSpec) MemberwiseClone ();
+                       mutated.Element = me;
+                       mutated.info = null;
+                       return mutated;
+               }
+       }
+
+       public class ArrayContainer : ElementTypeSpec
+       {
+               readonly int rank;
+               static Dictionary<Tuple<TypeSpec, int>, ArrayContainer> instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
+
+               private ArrayContainer (TypeSpec element, int rank)
+                       : base (MemberKind.Class, element, null)
+               {
+                       this.rank = rank;
+               }
+
+               public int Rank {
+                       get {
+                               return rank;
+                       }
+               }
+
+               public System.Reflection.MethodInfo GetConstructor ()
+               {
+                       var mb = RootContext.ToplevelTypes.Builder;
+
+                       var arg_types = new Type[rank];
+                       for (int i = 0; i < rank; i++)
+                               arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+
+                       var ctor = mb.GetArrayMethod (
+                               GetMetaInfo (), ".ctor",
+                               System.Reflection.CallingConventions.HasThis,
+                               null, arg_types);
+
+                       return ctor;
+               }
+
+               public System.Reflection.MethodInfo GetGetMethod ()
+               {
+                       var mb = RootContext.ToplevelTypes.Builder;
+
+                       var arg_types = new Type[rank];
+                       for (int i = 0; i < rank; i++)
+                               arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+
+                       var get = mb.GetArrayMethod (
+                               GetMetaInfo (), "Get",
+                               System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
+                               Element.GetMetaInfo (), arg_types);
+
+                       return get;
+               }
+
+               public System.Reflection.MethodInfo GetSetMethod ()
+               {
+                       var mb = RootContext.ToplevelTypes.Builder;
+
+                       var arg_types = new Type[rank + 1];
+                       for (int i = 0; i < rank; i++)
+                               arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+
+                       arg_types[rank] = Element.GetMetaInfo ();
+
+                       var set = mb.GetArrayMethod (
+                               GetMetaInfo (), "Set",
+                               System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
+                               TypeManager.void_type.GetMetaInfo (), arg_types);
+
+                       return set;
+               }
+
+               public override Type GetMetaInfo ()
+               {
+                       if (info == null) {
+                               if (rank == 1)
+                                       info = Element.GetMetaInfo ().MakeArrayType ();
+                               else
+                                       info = Element.GetMetaInfo ().MakeArrayType (rank);
+                       }
+
+                       return info;
+               }
+
+               protected override string GetPostfixSignature()
+               {
+                       StringBuilder sb = new StringBuilder ();
+                       sb.Append ("[");
+                       for (int i = 1; i < rank; i++) {
+                               sb.Append (",");
+                       }
+                       sb.Append ("]");
+
+                       return sb.ToString ();
+               }
+
+               public static ArrayContainer MakeType (TypeSpec element)
+               {
+                       return MakeType (element, 1);
+               }
+
+               public static ArrayContainer MakeType (TypeSpec element, int rank)
+               {
+                       ArrayContainer ac;
+                       var key = Tuple.Create (element, rank);
+                       if (!instances.TryGetValue (key, out ac)) {
+                               ac = new ArrayContainer (element, rank) {
+                                       BaseType = TypeManager.array_type
+                               };
+
+                               instances.Add (key, ac);
+                       }
+
+                       return ac;
+               }
+
+               public static void Reset ()
+               {
+                       instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
+               }
+       }
+
+       class ReferenceContainer : ElementTypeSpec
+       {
+               static Dictionary<TypeSpec, ReferenceContainer> instances = new Dictionary<TypeSpec, ReferenceContainer> ();
+
+               private ReferenceContainer (TypeSpec element)
+                       : base (MemberKind.Class, element, null)        // TODO: Kind.Class is most likely wrong
+               {
+               }
+
+               public override Type GetMetaInfo ()
+               {
+                       if (info == null) {
+                               info = Element.GetMetaInfo ().MakeByRefType ();
+                       }
+
+                       return info;
+               }
+
+               public static ReferenceContainer MakeType (TypeSpec element)
+               {
+                       ReferenceContainer pc;
+                       if (!instances.TryGetValue (element, out pc)) {
+                               pc = new ReferenceContainer (element);
+                               instances.Add (element, pc);
+                       }
+
+                       return pc;
+               }
+
+               public static void Reset ()
+               {
+                       instances = new Dictionary<TypeSpec, ReferenceContainer> ();
+               }
+       }
+
+       class PointerContainer : ElementTypeSpec
+       {
+               static Dictionary<TypeSpec, PointerContainer> instances = new Dictionary<TypeSpec, PointerContainer> ();
+
+               private PointerContainer (TypeSpec element)
+                       : base (MemberKind.PointerType, element, null)
+               {
+                       // It's never CLS-Compliant
+                       state &= ~StateFlags.CLSCompliant_Undetected;
+               }
+
+               public override Type GetMetaInfo ()
+               {
+                       if (info == null) {
+                               info = Element.GetMetaInfo ().MakePointerType ();
+                       }
+
+                       return info;
+               }
+
+               protected override string GetPostfixSignature()
+               {
+                       return "*";
+               }
+
+               public static PointerContainer MakeType (TypeSpec element)
+               {
+                       PointerContainer pc;
+                       if (!instances.TryGetValue (element, out pc)) {
+                               pc = new PointerContainer (element);
+                               instances.Add (element, pc);
+                       }
+
+                       return pc;
+               }
+
+               public static void Reset ()
                {
-//                     cache = MemberCache.Empty;
+                       instances = new Dictionary<TypeSpec, PointerContainer> ();
                }
        }
-*/ 
 }