**** Merged r40732-r40872 from MCS ****
authorMartin Baulig <martin@novell.com>
Tue, 22 Mar 2005 10:12:21 +0000 (10:12 -0000)
committerMartin Baulig <martin@novell.com>
Tue, 22 Mar 2005 10:12:21 +0000 (10:12 -0000)
svn path=/trunk/mcs/; revision=42082

1  2 
mcs/gmcs/ChangeLog
mcs/gmcs/OPTIMIZE
mcs/gmcs/attribute.cs
mcs/gmcs/class.cs
mcs/gmcs/constant.cs
mcs/gmcs/driver.cs
mcs/gmcs/ecore.cs
mcs/gmcs/expression.cs
mcs/gmcs/iterators.cs
mcs/gmcs/literal.cs
mcs/gmcs/rootcontext.cs

diff --combined mcs/gmcs/ChangeLog
index bce9deb7b2a47cdc4c3abb805d8d1d0d76a09b26,973569a3d2ba6efb3bea69bdce29d287b59fbbc6..8457cd836766cb61a9c5ff50db380ebab615af27
++2005-02-18  Marek Safar  <marek.safar@seznam.cz>
++
++      * class.cs (EmitFieldInitializers): Don't emit field initializer
++      for default values when optimilization is on.
++      
++      * constant.cs (Constant.IsDefaultValue): New property.
++      
++      * driver.cs: Add /optimize handling.
++      
++      * constant.cs,
++      * ecore.cs,
++      * literal.cs: Implement new IsDefaultValue property.
++      
++      * rootcontext.cs (Optimize): New field, holds /optimize option.
++
++2005-02-18  Raja R Harinath  <rharinath@novell.com>
++
++      Fix crasher in re-opened #72347.
++      * namespace.cs (Namespace.Lookup): Return null if
++      DeclSpace.DefineType returns null.
++
++      Fix #72678.
++      * expression.cs (Argument.Resolve): Handle a case of CS0120 here.
++
++2005-02-18  Raja R Harinath  <rharinath@novell.com>
++
++      Fix remainder of #63202.  Change semantics of DoResolveLValue: it
++      now returns null if it cannot resolve to an lvalue.
++      * ecore.cs (Expression.DoResolveLValue): Return 'null' by default.
++      (Expression.ResolveLValue): Emit CS0131 error if DoResolveLValue
++      returned null.  Remove check for SimpleName.
++      (EventExpr.DoResolveLValue): New.
++      * iterators.cs (Iterator.FieldExpression.DoResolveLValue): New.
++      * expression.cs (Argument.Error_LValueRequired): New.  Move CS1510
++      error from ...
++      (Argument.Resolve): ... here.  Use it.  Use DoResolveLValue to
++      avoid CS0131 error.
++      (Unary.ResolveOperator): Move CS0211 check ...
++      (Unary.DoResolve): ... here.  Use DoResolveLValue to avoid
++      CS0131 error.
++      (Unary.DoResolveLValue): Simplify.
++      (AddressOf.DoResolveLValue): New.
++      (ArrayAccess.DoResolveLValue): New.
++
++2005-02-16  Marek Safar  <marek.safar@seznam.cz>
++
++      * attribute.cs (Attribute.Resolve): Add arguments casting for
++      when types doesn't match ctor arguments.
++
++2005-02-16  Raja R Harinath  <rharinath@novell.com>
++
++      Fix parts of #63202.
++      * expression.cs (UnaryMutator.ResolveOperator): Remove redundant
++      lookup of operator in base type.  Ensure that all checks happen
++      when the operator resolves to an "op_..." method.
++
 +2005-02-15  Raja R Harinath  <rharinath@novell.com>
 +
 +      Fix #71992.
 +      * namespace.cs (NamespaceEntry.LookupNamespaceOrType): Add
 +      'ignore_cs0104' parameter.  Pass it to ...
 +      (NamespaceEntry.Lookup): ... this.
 +      * decl.cs (DeclSpace.LookupType): Add 'ignore_cs0104' parameter.
 +      * ecore.cs (SimpleName.ResolveAsTypeStep): Update.
 +      (TypeLookupExpression.DoResolveAsTypeStep): Update.
 +      * expression.cs (MemberAccess.IdenticalNameAndTypeName):
 +      Update.  Request that cs0104 errors be ignored.
 +      (ComposedCast.ResolveAsTypeStep): Update.
 +
 +2005-02-14  Raja R Harinath  <rharinath@novell.com>
 +
 +      Fix #59209.
 +      * expression.cs (Invocation.BetterFunction): Remove support for
 +      comparing virtual functions and their overrides.
 +      (Invocation.IsOverride): New.
 +      (Invocation.OverloadResolve): Don't consider 'override' functions
 +      during candidate selection.  Store them in a lookaside list.
 +      If the selected method is a 'virtual' function, use the list to
 +      find any overrides that are closer to the LHS type.
 +
 +2005-02-14  Marek Safar  <marek.safar@seznam.cz>
 +
 +      * expression.cs (New.DoResolve): Add complex core type reduction.
 +      (New.Constantify): Converts complex core type syntax like 'new int ()'
 +      to simple constant.
 +      
 +2005-02-14  Raja R Harinath  <rharinath@novell.com>
 +
 +      * decl.cs (EntryType.EntryType): New constructor to create an
 +      updated copy of a cache entry.
 +      (MemberCache.AddMethods): Use it.
 +      (MemberCache.ClearDeclaredOnly): Remove.
 +      (MemberCache.MemberCache): Update.
 +
 +2005-02-11  Miguel de Icaza  <miguel@novell.com>
 +
 +      * codegen.cs (EmitContext): Introduce the `MethodIsStatic'
 +      variable.  This one is represents the actual low-level declaration
 +      of the method, as opposed to the semantic level `IsStatic'.   
 +
 +      An anonymous method which is hosted into a static method might be
 +      actually an instance method.  IsStatic would reflect the
 +      container, while MethodIsStatic represents the actual code
 +      generated.
 +
 +      * expression.cs (ParameterReference): Use the new MethodIsStatic
 +      instead of IsStatic.
 +
 +      * anonymous.cs (AnonymousMethod.Compatible): Pass the
 +      Modifiers.STATIC to the Anonymous' Method EmitContext if static is
 +      set on the current EmitContext. 
 +
 +      * expression.cs (Cast): Overload DoResolveLValue so we can pass
 +      resolve our casted expression as an LValue.  This triggers the
 +      proper LValue processing that is later required by Assign.
 +
 +      This fixes 72347.
 +
 +      * cs-tokenizer.cs (pp_and): recurse on pp_and, fixes #61903.
 +
 +2005-02-11  Marek Safar  <marek.safar@seznam.cz>
 +
 +      C# 2.0 Fixed buffer implementation
 +
 +      * anonymous.cs: Update after RegisterHelperClass renaming.
 +
 +      * attribute.cs (AttributeTester.fixed_buffer_cache):
 +      Cache of external fixed buffers.
 +      (AttributeTester.GetFixedBuffer): Returns IFixedBuffer
 +      implementation if field is fixed buffer else null.
 +
 +      * class.cs
 +      (TypeContainer.AddField): Accept FieldMember instead of Field.
 +      (FieldBase.IsFieldClsCompliant): Extracted code from
 +      VerifyClsCompliance descendant customization.
 +      (FixedField): New class handles fixed buffer fields.
 +      (FixedFieldExternal): Keeps information about imported fixed
 +      buffer.
 +      (IFixedField): Make access to internal or external fixed buffer
 +      same.
 +
 +      * cs-parser.jay: Add fixed buffer parsing.
 +
 +      * ecore.cs (FieldExpr.Emit): Add special emit case for fixed
 +      buffer.
 +
 +      * expression.cs (Indirection): Extended implementation to accept
 +      fixed buffer field.
 +      (PointerArithmetic.Emit): Get element from fixed buffer as well.
 +      (ElementAccess.MakePointerAccess): Get type as parameter.
 +      (DoResolve): Add fixed buffer field expression conversion.
 +      (DoResolveLValue): Ditto.
 +      (FixedBufferPtr): New class. Moved most of original ArrayPtr.
 +      (ArrayPtr): Derives from FixedBufferPtr.
 +      (ArrayPtr.Emit): Add extra emit for array elements.
 +
 +      * flowanalysis.cs.cs (StructInfo): Use FieldMember.
 +
 +      * rootcontext.cs (CloseTypes): Emit CompilerGenerated attribute
 +      for compiler generated types.
 +      (RegisterCompilerGeneratedType): Renamed from RegisterHelperClass.
 +
 +      * statement.cs (Fixed): Refactored to be easier add fixed buffer
 +      and consume less memory.
 +      (Fixed.Resolve): Add fixed buffer case.
 +
 +      * typemanager.cs (compiler_generated_attr_ctor,
 +      fixed_buffer_attr_ctor): Add new 2.0 compiler attributes.
 +      (HasElementType): Add our own implementation to work on every
 +      runtime.
 +
 +2005-02-11  Miguel de Icaza  <miguel@novell.com>
 +
 +      * anonymous.cs (CaptureContext): Track whether `this' has been
 +      referenced.   
 +
 +      * expression.cs (This.ResolveBase): Call CaptureThis.  Before we
 +      only captured `this' if it was implicitly done (instance
 +      methods/variables were used). 
 +
 +      * codegen.cs (EmitContext.CaptureThis): New method to flag that
 +      `this' must be captured.
 +
 +2005-01-30  Miguel de Icaza  <miguel@novell.com>
 + 
 +      * anonymous.cs (CreateMethodHost): If there Scope.ScopeTypeBuilder
 +      is null it means that there has been no need to capture anything,
 +      so we just create a sibling.
 +
 +      Renamed `EmitHelperClasses' to `EmitAnonymousHelperClasses'
 +
 +      Just a partial fix.  The other half is fairly elusive.
 +      
 +2005-02-10  Raja R Harinath  <rharinath@novell.com>
 +
 +      Fix #52586, cs0121-4.cs.
 +      * decl.cs (MemberCache.DeepCopy): Rename from SetupCache.  Take
 +      and return a hashtable.
 +      (MemberCache.ClearDeclaredOnly): New.
 +      (MemberCache.MemberCache): Update to change.  Make a deep copy of
 +      the method_hash of a base type too.
 +      (MemberCache.AddMethods): Adapt to having a deep copy of the base
 +      type methods.  Overwrite entries with the same MethodHandle so
 +      that the ReflectedType is correct.  The process leaves in base
 +      virtual functions and their overrides as distinct entries.
 +      (CacheEntry): Now a class instead of a struct.  It shouldn't alter
 +      matters since it was boxed in a ArrayList before.
 +      (CacheEntry.Member, CacheEntry.EntryType): Remove 'readonly'
 +      modifier.
 +      * expression.cs (Invocation.BetterFunction): Simplify.  Handle the
 +      case of a virtual function and its override (choose the overload
 +      as better).
 +      (Invocation.OverloadResolve): Avoid 'override' members during
 +      'applicable_type' calculation.
 +
 +2005-02-09  Raja R Harinath  <rharinath@novell.com>
 +
 +      Combine two near-redundant caches.
 +      * typemanager.cs (method_params): Rename from method_internal_params.
 +      (TypeManager.GetParameterData): New.  Replace
 +      Invocation.GetParameterData.
 +      (TypeManager.LookupParametersByBuilder): Remove.
 +      * expression.cs (Invocation.method_parameter_cache): Remove.
 +      (Invocation.GetParameterData): Remove.
 +      Update to changes.
 +      * anonymous.cs, attribute.cs, convert.cs, delegate.cs:
 +      Update to changes.
 +
 +2005-02-08  Raja R Harinath  <rharinath@novell.com>
 +
 +      Fix #72015.
 +      * delegate.cs (Delegate.DefineType): When bootstrapping corlib, if
 +      TypeManager.multicast_delegate_type is null, resolve it by looking
 +      up "System.MulticastDelegate".
 +      * rootcontext.cs (RootContext.ResolveCore): Simplify.
 +
 +2005-02-07  Abin Thomas (NOSIP)  <projectmonokochi@rediffmail.com>
 +          Anoob V.E (NOSIP)  <projectmonokochi@rediffmail.com>
 +          Harilal P.R (NOSIP)  <projectmonokochi@rediffmail.com>
 +
 +      Fix cs0164.cs.
 +      * statement.cs (LabeledStatement.Resolve): Don't set 'referenced'.
 +      (LabeledStatement.AddReference): New.  Set 'referenced'.
 +      (Goto.Resolve): Use it.
 +
 +2005-02-05  John Luke  <john.luke@gmail.com>
 +
 +      * driver.cs: remove duplicate -doc line in Usage ()
 +
 +2005-02-04  Raja R Harinath  <rharinath@novell.com>
 +
 +      * location.cs (Location.AddFile): Fix CS2002 error report.
 +
 +2005-02-02  Martin Baulig  <martin@ximian.com>
 +
 +      * delegate.cs (Delegate.DefineType): Report an internal error if
 +      TypeManager.multicast_delegate_type is null.  See bug #72015 for
 +      details.        
 +
 +2005-02-02  Raja R Harinath  <rharinath@novell.com>
 +
 +      Fix a crasher in a variant of #31984.
 +      * const.cs (Constant.CheckBase): New override that defers the
 +      new-or-override check in case the base type hasn't been populated
 +      yet.
 +      (Constant.Define): Ensure the new-or-override check is performed.
 +
 +2005-02-01  Duncan Mak  <duncan@ximian.com>
 +
 +      * const.cs (LookupConstantValue): Check that `ce' is not null
 +      before calling GetValue ().
 +
 +2005-02-01  Raja R Harinath  <rharinath@novell.com>
 +
 +      Fix test-334.cs (#69519).
 +      * cs-parser.jay (using_alias_directive): Pass in an expression to
 +      NamespaceEntry.UsingAlias.
 +      (using_namespace_directive): Pass in an expression to
 +      NamespaceEntry.Using.
 +      (namespace_name): Don't flatten to a string.
 +      * namespace.cs (NamespaceEntry.AliasEntry): Store an expression.
 +      (NamespaceEntry.AliasEntry.Resolve): Lookup using
 +      ResolveAsTypeStep.
 +      (NamespaceEntry.UsingEntry): Likewise.
 +      (NamespaceEntry.Using,NamespaceEntry.UsingAlias): Update to
 +      changes.
 +      (NamespaceEntry.LookupForUsing): Remove.
 +      (NamespaceEntry.LookupNamespaceOrType): Add support for dotted
 +      names.
 +      (NamespaceEntry.Lookup): Remove support for dotted names.
 +
 +2005-02-01  Raja R Harinath  <rharinath@novell.com>
 +
 +      * namespace.cs (NamespaceEntry.NamespaceEntry): Simplify, and
 +      split into two.
 +      (NamespaceEntry.ImplicitParent): Compute on demand.
 +      (NamespaceEntry.Doppelganger): New implicit namespace-entry that
 +      parallels the current.
 +      (NamespaceEntry.LookupForUsing): Use it.
 +      (NamespaceEntry.Lookup): If the current namespace-entry is
 +      implicit, don't search aliases and using tables.
 +
 +2005-02-01  Raja R Harinath  <rharinath@novell.com>
 +
 +      Fix #31984.
 +      * class.cs (TypeContainer.DoDefineMembers): Don't initialize
 +      BaseCache here.
 +      (TypeContainer.BaseCache): Compute on demand.
 +      (TypeContainer.FindMembers): Define constants and types if they're
 +      not already created.
 +      (FieldMember.Define): Move resetting of ec.InUnsafe before error
 +      check.
 +      * const.cs (Constant.Define): Make idempotent.
 +
 +2005-01-29  Miguel de Icaza  <miguel@novell.com>
 +
 +      * pending.cs: Produce better code (no nops produced by using Ldarg
 +      + value).
 +      
 +      * pending.cs (PendingImplementation.DefineProxy): It was not `arg
 +      i - 1' it should be arg + 1.
 +
 +      Fixes bug #71819.
 +
 +2005-01-28  Raja R Harinath  <rharinath@novell.com>
 +
 +      * attribute.cs (Attribute.CheckAttributeType): Make private
 +      non-virtual.
 +      (Attribute.ResolveType): Make virtual.
 +      (GlobalAttribute.ResolveType,GlobalAttribute.Resolve): Simplify
 +      handling of RootContext.Tree.Types.
 +
 +2005-01-27  Raja R Harinath  <rharinath@novell.com>
 +
 +      Update attribute-handling to use the SimpleName/MemberAccess
 +      mechanisms.
 +      * cs-parser.jay (attribute): Pass in an expression to the
 +      constructors of Attribute and GlobalAttribute.
 +      * attribute.cs (Attribute): Take an expression for the name.
 +      (Attribute.ResolvePossibleAttributeTypes): New.  Resolves the
 +      passed in attribute name expression.
 +      (Attribute.CheckAttributeType): Use it.
 +      * ecore.cs (FullNamedExpression.ResolveAsTypeStep): New.
 +      * expression.cs (MemberAccess.ResolveAsTypeStep): Move body to ...
 +      (MemberAccess.ResolveNamespaceOrType): ... here.  Add 'silent'
 +      argument to prevent error messages if the lookup fails.
 +
 +2005-01-27  Marek Safar  <marek.safar@seznam.cz>
 +
 +      * expression.cs (Indirection): Implemented IVariable interface
 +      to support indirection in AddressOf operator.
 +      (PointerArithmetic.Emit): Add optimalization for case where
 +      result can be precomputed.
 +
 +2005-01-26  Martin Baulig  <martin@ximian.com>
 +
 +      * class.cs (TypeContainer.AttributeTargets): Return the correct
 +      AttributeTargets depending on our `Kind' instead of throwing an
 +      exception; fixes #71632.
 +
 +2005-01-26  Marek Safar  <marek.safar@seznam.cz>
 +
 +      Fix #71257
 +      * expression.cs (MemberAccess.ResolveMemberAccess): Add CS0176 test for
 +      constant members.
 +
 +2005-03-17  Martin Baulig  <martin@ximian.com>
 +
 +      * anonymous.cs (AnonymousMethod.method_modifiers): Change default
 +      from `Modifiers.INTERNAL' to `Modifiers.PRIVATE'.  Fixes #73260.
 +
 +2005-03-17  Martin Baulig  <martin@ximian.com>
 +
 +      * anonymous.cs (AnonymousMethod.EmitMethod): Changed return type
 +      to bool so we can return an error condition.
 +      (AnonymousDelegate.Emit): Check whether AnonymousMethod.EmitMethod()
 +      returned an error.
 +
 +2005-03-17  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (TypeMananager.IsIEnumerable): New public method.
 +
 +      * convert.cs (Convert.ImplicitReferenceConversion(Exists)): Allow
 +      converting from an array-type of T to `IEnumerable<T>'.
 +
 +2005-03-16  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (Nullable.Unwrap): Implement IAssignMethod.
 +      (Nullable.LiftedUnaryMutator): New public class.
 +
 +      * expression.cs (UnaryMutator.DoResolve): Added support for
 +      Nullable Types.
 +
 +2005-03-14  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (Nullable.NullCoalescingOperator): Implemented.
 +
 +2005-03-14  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (Nullable.LiftedBinaryOperator): Added support for
 +      the comparision operators `<', `>', `<=' and `>='.
 +
 +2005-03-13  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs
 +      (Nullable.NullLiteral): Renamed to `Nullable.NullableLiteral' to
 +      avoid confusion with the `NullLiteral'.
 +      (Nullable.LiftedBinaryOperator): Correctly implement `==' and '!='.
 +
 +2005-03-13  Martin Baulig  <martin@ximian.com>
 +
 +      * expression.cs (Binary.ResolveOperator): For `==' and `!=', allow
 +      comparing arbitrary types with the null literal.
 +
 +2005-03-13  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (Nullable.LiftedBinaryOperator): Add support for the
 +      boolean operators '&&', '||', '&' and '|'.
 +      (Nullable.OperatorTrueOrFalse): New public class.
 +
 +      * ecore.cs (Expression.GetOperatorTrue/False): Return an `Expression'
 +      instead of a `StaticCallExpr'; added support for nullables.
 +
 +2005-03-10  Martin Baulig  <martin@ximian.com>
 +
 +      * expression.cs
 +      (ArrayAccess.EmitDynamicInitializers): Use `etype.IsValueType'
 +      rather than `etype.IsSubclassOf (TypeManager.value_type)'.      
 +
 +2005-03-07  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (Nullable.Unwrap): Implement IMemoryLocation and make
 +      it work if `expr' is not an IMemoryLocation.
 +      (Nullable.Lifted): Implement IMemoryLocation.
 +      (Nullable.LiftedConversion.ResolveUnderlying): Use the correct
 +      target type.
 +
 +2005-03-05  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (Nullable.Unwrap, Wrap): New protected classes.
 +      (Nullable.Lifted): New abstract class; rewrote the lifted conversions.
 +      (Nullable): Added support for lifted unary and binary operators.
 +
 +      * expression.cs (Unary.DoResolve): Added support for nullable types.
 +      (Binary.DoResolve): Likewise.
 +      (Conditional.DoResolve): Likewise.
 +
 +2005-03-02  Martin Baulig  <martin@ximian.com>
 +
 +      * decl.cs (DeclSpace.SetParameterInfo): Make this virtual.
 +
 +      * class.cs (ClassPart.SetParameterInfo): Override this.
 +      (PartialContainer.SetParameterInfo): Override this.
 +      (TypeContainer.CheckConstraints): New protected method.
 +      (PartialContainer.CheckConstraints): Override this and check
 +      whether the same contraints were specified in all parts of a
 +      partial generic type definition.
 +      (PartialContainer.UpdateConstraints): New public method.
 +
 +      * generic.cs (TypeParameter.UpdateConstraints): New public method.
 +
 +2005-03-02  Martin Baulig  <martin@ximian.com>
 +
 +      Committing a patch from Carlos Alberto Cortez to fix #72887.
 +
 +      * convert.cs (Convert.ExplicitReferenceConversionExists): Allow
 +      casts from `T []' to `int []'.
 +
 +2005-03-02  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (TypeManager.IsEqual): Make this symmetric.
 +
 +      * expression.cs (Binary.ResolveOperator): When resolving a
 +      BinaryDelegate, use `TypeManager.IsEqual (l, r)' rather than just
 +      `=='.  Fixes #71866.  See gen-127.cs.
 +
 +2005-03-02  Martin Baulig  <martin@ximian.com>
 +
 +      * class.cs (TypeContainer.DoDefineMembers): We also need a default
 +      static constructor in static classes.
 +
 +2005-03-02  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs
 +      (NullableType.Name, NullableType.FullName): Add a "?" to the name.
 +      (Nullable.LiftedConversion): Added support for user-defined
 +      conversions.
 +
 +      * cs-tokenizer.cs (Tokenizer.PutbackCloseParens): New public method.
 +
 +      * cs-parser.jay: Use ComposedCast everywhere instead of
 +      NullableType, so we don't need to check for NullableType
 +      everywhere.
 +      (conditional_expression): Added `INTERR CLOSE_PARENS' rule for the
 +      case where we'll be resolved into a `parenthesized_expression_0'
 +      afterwards.
 +
 +      * convert.cs
 +      (Convert.UserDefinedConversion): Added nullable conversions.
 +
 +2005-02-28  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (TypeManager.IsNullableType): New static method.
 +      (Nullable): New abstract class.
 +      (Nullable.NullLiteral): New public class.
 +      (Nullable.LiftedConversion): New public class.
 +
 +      * cs-parser.jay (non_expression_type): Changed `builtin_types' to
 +      `builtin_types opt_nullable'.
 +
 +      * convert.cs
 +      (Convert.ImplicitConversionStandard): Added nullable conversions.
 +      (Convert.ExplicitConversionStandard): Likewise.
 +      (Convert.ExplicitConversion): Likewise.
 +
 +2005-02-26  Martin Baulig  <martin@ximian.com>
 +
 +      * expression.cs (ComposedCast.DoResolveAsTypeStep): Allow `dim' to
 +      begin with a "?", for instance "?[]".  Don't do a type lookup if
 +      `dim' is empty.
 +
 +2005-02-25  Martin Baulig  <martin@ximian.com>
 +
 +      The first part of Nullable Types :-)
 +
 +      * generic.cs (NullableType): New public class.
 +      (NullCoalescingOperator): New public class.
 +      (TypeArguments.Resolve): Add a CS0306 check.
 +
 +      * cs-parser.jay (opt_error_modifier): Removed, this was unused.
 +      (opt_nullable): New rule.
 +      (type): Added `opt_nullable' to `namespace_or_type_name',
 +      `builtin_types' and `pointer_type'.
 +      (array_type): Added `opt_nullable'.
 +      (opt_rank_specifier_or_nullable): New rule; this is the
 +      combination of `opt_rank_specifier' and `opt_nullable'.
 +      (opt_error): New rule; catch errors here.
 +      (nullable_type_or_conditional): New rule; we use this to check for
 +      nullable and still detect the conditional operator.
 +      (local_variable_type): Use `opt_rank_specifier_or_nullable'
 +      instead `opt_rank_specifier'.
 +
 +      * expression.cs (ComposedCast.DoResolveAsTypeStep): Added support
 +      for nullables.
 +
 +2005-02-24  Martin Baulig  <martin@ximian.com>
 +
 +      * README, README.Changes: Removed; they're old and obsolete.
 +
 +2005-02-22  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs (TypeParameter.Resolve): If resolving the constraints
 +      returned an error, set `constraints' to null to avoid a crash
 +      later on.
 +      (TypeParameter.ResolveType): Likewise.
 +
 +2005-02-22  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs
 +      (Constraints.ResolveTypes): Protect against being called twice.
 +      (Constraints.CheckInterfaceMethod): Don't call ResolveTypes().
 +      (TypeParameter.ResolveType): New public method; calls
 +      constraints.ResolveTypes().
 +      (TypeParameter.DefineType): Moved constraints.ResolveType() out
 +      into the new ResolveType().
 +      (GenericMethod.Define): Call ResolveType() on all our
 +      TypeParameter's.        
 +
 +2005-02-21  Martin Baulig  <martin@ximian.com>
 +
 +      * generic.cs
 +      (TypeManager.generic_nullable_type): New static public field.
 +      (TypeManager.InitGenericCoreType): Lookup "System.Nullable`1".
 +
 +      * rootcontext.cs
 +      (RootContext.ResolveCore): Resolve "System.Nullable`1".
 +
  2005-02-15  Martin Baulig  <martin@ximian.com>
  
        * generic.cs (ConstructedType.Constraints): Correctly check
diff --combined mcs/gmcs/OPTIMIZE
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6fa1e31e9477610de21b983da451900d5b07ddec
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,26 @@@
++This document describes all code optimalizations performed by Mono C# compiler
++when optimalizations are enabled via /optimize+ option.
++
++Optimalizations:
++
++* Instance field initializer to default value
++---------------------------------------------
++
++Code to optimize:
++
++class C
++{
++    enum E
++    {
++      Test
++    }
++    
++    int i = 0;  // Field will not be redundantly assigned
++    int i2 = new int (); // This will be also completely optimized out
++    
++    E e = E.Test; // Even this will go out.
++    
++}
++
++
++
diff --combined mcs/gmcs/attribute.cs
index 0451f60cb2b1c882cba36dc3f6a8a4dfac65c086,30d6a61dcced525a185d747c6f7662f4d3588d41..1e6a5e7137de37b6d05da6e358f8c85cbe364144
@@@ -72,9 -72,6 +72,9 @@@ namespace Mono.CSharp 
                public AttributeTargets Target;
  
                public readonly string    Name;
 +              public readonly Expression LeftExpr;
 +              public readonly string Identifier;
 +
                public readonly ArrayList Arguments;
  
                public readonly Location Location;
  
                static PtrHashtable usage_attr_cache = new PtrHashtable ();
                
 -              public Attribute (string target, string name, ArrayList args, Location loc)
 +              public Attribute (string target, Expression left_expr, string identifier, ArrayList args, Location loc)
                {
 -                      Name = name;
 +                      LeftExpr = left_expr;
 +                      Identifier = identifier;
 +                      Name = LeftExpr == null ? identifier : LeftExpr + "." + identifier;
                        Arguments = args;
                        Location = loc;
                        ExplicitTarget = target;
                {
                        Report.Error (617, Location, "Invalid attribute argument: '{0}'.  Argument must be fields " +
                                      "fields which are not readonly, static or const;  or read-write instance properties.",
 -                                    Name);
 +                                    name);
                }
  
                static void Error_AttributeArgumentNotValid (string extra, Location loc)
                                        "Could not find a constructor for this argument list.");
                }
  
 +              void ResolvePossibleAttributeTypes (EmitContext ec, out Type t1, out Type t2)
 +              {
 +                      t1 = null;
 +                      t2 = null;
 +
 +                      FullNamedExpression n1 = null;
 +                      FullNamedExpression n2 = null;
 +                      string IdentifierAttribute = Identifier + "Attribute";
 +                      if (LeftExpr == null) {
 +                              n1 = new SimpleName (Identifier, Location).ResolveAsTypeStep (ec);
 +
 +                              // FIXME: Shouldn't do this for quoted attributes: [@A]
 +                              n2 = new SimpleName (IdentifierAttribute, Location).ResolveAsTypeStep (ec);
 +                      } else {
 +                              FullNamedExpression l = LeftExpr.ResolveAsTypeStep (ec);
 +                              if (l == null) {
 +                                      Report.Error (246, Location, "Couldn't find namespace or type '{0}'", LeftExpr);
 +                                      return;
 +                              }
 +                              n1 = new MemberAccess (l, Identifier, Location).ResolveNamespaceOrType (ec, true);
 +
 +                              // FIXME: Shouldn't do this for quoted attributes: [X.@A]
 +                              n2 = new MemberAccess (l, IdentifierAttribute, Location).ResolveNamespaceOrType (ec, true);
 +                      }
 +
 +                      TypeExpr te1 = n1 == null ? null : n1 as TypeExpr;
 +                      TypeExpr te2 = n2 == null ? null : n2 as TypeExpr;                      
 +
 +                      if (te1 != null)
 +                              t1 = te1.ResolveType (ec);
 +                      if (te2 != null)
 +                              t2 = te2.ResolveType (ec);
 +              }
 +
                /// <summary>
                  ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
                  /// </summary>
 -              protected virtual Type CheckAttributeType (EmitContext ec)
 +              Type CheckAttributeType (EmitContext ec)
                {
 -                      string NameAttribute = Name + "Attribute";
 -                      FullNamedExpression n1 = ec.ResolvingTypeTree
 -                              ? ec.DeclSpace.FindType (Location, Name)
 -                              : ec.DeclSpace.LookupType (Name, true, Location);
 -
 -                      // FIXME: Shouldn't do this for quoted attributes: [@A]
 -                      FullNamedExpression n2 = ec.ResolvingTypeTree
 -                              ? ec.DeclSpace.FindType (Location, NameAttribute)
 -                              : ec.DeclSpace.LookupType (NameAttribute, true, Location);
 -
 -                      TypeExpr e1 = n1 == null ? null : n1 as TypeExpr;
 -                      TypeExpr e2 = n2 == null ? null : n2 as TypeExpr;                       
 +                      Type t1, t2;
 +                      ResolvePossibleAttributeTypes (ec, out t1, out t2);
  
 -                      Type t1 = e1 == null ? null : e1.ResolveType (ec);
 -                      Type t2 = e2 == null ? null : e2.ResolveType (ec);
 +                      string NameAttribute = Name + "Attribute";
  
                        String err0616 = null;
                        if (t1 != null && ! t1.IsSubclassOf (TypeManager.attribute_type)) {
                        return null;
                }
  
 -              public Type ResolveType (EmitContext ec)
 +              public virtual Type ResolveType (EmitContext ec)
                {
                        if (Type == null)
                                Type = CheckAttributeType (ec);
                        // of type object
                        //
  
 -                      ParameterData pd = Invocation.GetParameterData (constructor);
 +                      ParameterData pd = TypeManager.GetParameterData (constructor);
  
                        int last_real_param = pd.Count;
                        if (pd.HasParams) {
                                        return null;
                                }
  
++                              object value = pos_values [j];
++                              if (value != null && a.Type != value.GetType () && a.Type.IsPrimitive) {
++                                      bool fail;
++                                      pos_values [j] = TypeManager.ChangeType (value, a.Type, out fail);
++                                      if (fail) {
++                                              // TODO: Can failed ?
++                                              throw new NotImplementedException ();
++                                      }
++                              }
++
                                if (j < last_real_param)
                                        continue;
                                
        {
                public readonly NamespaceEntry ns;
  
 -              public GlobalAttribute (TypeContainer container, string target, string name, ArrayList args, Location loc):
 -                      base (target, name, args, loc)
 +              public GlobalAttribute (TypeContainer container, string target, 
 +                                      Expression left_expr, string identifier, ArrayList args, Location loc):
 +                      base (target, left_expr, identifier, args, loc)
                {
                        ns = container.NamespaceEntry;
                }
  
 -              protected override Type CheckAttributeType (EmitContext ec)
 +              void Enter ()
                {
                        // RootContext.Tree.Types has a single NamespaceEntry which gets overwritten
                        // each time a new file is parsed.  However, we need to use the NamespaceEntry
                        // in effect where the attribute was used.  Since code elsewhere cannot assume
                        // that the NamespaceEntry is right, just overwrite it.
                        //
 -                      // Precondition: RootContext.Tree.Types == null || RootContext.Tree.Types == ns.
 -                      //               The second case happens when we are recursively invoked from inside Emit.
 -
 -                      NamespaceEntry old = null;
 -                      if (ec.DeclSpace == RootContext.Tree.Types) {
 -                              old = ec.DeclSpace.NamespaceEntry;
 -                              ec.DeclSpace.NamespaceEntry = ns;
 -                              if (old != null && old != ns)
 -                                      throw new InternalErrorException (Location + " non-null NamespaceEntry " + old);
 -                      }
 +                      // Precondition: RootContext.Tree.Types == null
 +
 +                      if (RootContext.Tree.Types.NamespaceEntry != null)
 +                              throw new InternalErrorException (Location + " non-null NamespaceEntry");
  
 -                      Type retval = base.CheckAttributeType (ec);
 +                      RootContext.Tree.Types.NamespaceEntry = ns;
 +              }
  
 -                      if (ec.DeclSpace == RootContext.Tree.Types)
 -                              ec.DeclSpace.NamespaceEntry = old;
 +              void Leave ()
 +              {
 +                      RootContext.Tree.Types.NamespaceEntry = null;
 +              }
  
 +              public override Type ResolveType (EmitContext ec)
 +              {
 +                      Enter ();
 +                      Type retval = base.ResolveType (ec);
 +                      Leave ();
                        return retval;
                }
  
                public override CustomAttributeBuilder Resolve (EmitContext ec)
                {
 -                      if (ec.DeclSpace == RootContext.Tree.Types) {
 -                              NamespaceEntry old = ec.DeclSpace.NamespaceEntry;
 -                              ec.DeclSpace.NamespaceEntry = ns;
 -                              if (old != null)
 -                                      throw new InternalErrorException (Location + " non-null NamespaceEntry " + old);
 -                      }
 -
 +                      Enter ();
                        CustomAttributeBuilder retval = base.Resolve (ec);
 -
 -                      if (ec.DeclSpace == RootContext.Tree.Types)
 -                              ec.DeclSpace.NamespaceEntry = null;
 -
 +                      Leave ();
                        return retval;
                }
        }
                static PtrHashtable analyzed_types_obsolete = new PtrHashtable ();
                static PtrHashtable analyzed_member_obsolete = new PtrHashtable ();
                static PtrHashtable analyzed_method_excluded = new PtrHashtable ();
 +              static PtrHashtable fixed_buffer_cache = new PtrHashtable ();
 +
 +              static object TRUE = new object ();
 +              static object FALSE = new object ();
  
                private AttributeTester ()
                {
                        }
                        analyzed_types.Add (type, result ? TRUE : FALSE);
                        return result;
 -              }                
 +              }        
 +        
 +              /// <summary>
 +              /// Returns IFixedBuffer implementation if field is fixed buffer else null.
 +              /// </summary>
 +              public static IFixedBuffer GetFixedBuffer (FieldInfo fi)
 +              {
 +                      FieldBase fb = TypeManager.GetField (fi);
 +                      if (fb != null) {
 +                              return fb as IFixedBuffer;
 +                      }
  
 -              static object TRUE = new object ();
 -              static object FALSE = new object ();
 +#if NET_2_0
 +                      object o = fixed_buffer_cache [fi];
 +                      if (o == null) {
 +                              if (System.Attribute.GetCustomAttribute (fi, TypeManager.fixed_buffer_attr_type) == null) {
 +                                      fixed_buffer_cache.Add (fi, FALSE);
 +                                      return null;
 +                              }
 +                              
 +                              IFixedBuffer iff = new FixedFieldExternal (fi);
 +                              fixed_buffer_cache.Add (fi, iff);
 +                              return iff;
 +                      }
 +
 +                      if (o == FALSE)
 +                              return null;
 +
 +                      return (IFixedBuffer)o;
 +#else
 +                      return null;
 +#endif
 +              }
  
                public static void VerifyModulesClsCompliance ()
                {
diff --combined mcs/gmcs/class.cs
index 6027fe321f6e7e56c76e966cf4bf08f0f079ce55,4162d78065bf9d763a790e028271cc3e087aa921..568fe966540b13b7a4cb02e3f7b72e9a2108d128
@@@ -581,7 -581,7 +581,7 @@@ namespace Mono.CSharp 
                        interfaces.Add (iface);
                }
  
 -              public void AddField (Field field)
 +              public void AddField (FieldMember field)
                {
                        if (!AddToMemberContainer (field))
                                return;
                                if (a == null)
                                        return false;
  
++                              if (RootContext.Optimize) {
++                                      Constant c = e as Constant;
++                                      if (c != null) {
++                                              if (c.IsDefaultValue)
++                                                      continue;
++                                      }
++                              }
++
                                a.EmitStatement (ec);
                        }
  
                                        CurrentTypeParameters [i - offset].DefineConstraints ();
  
                                current_type = new ConstructedType (Name, TypeParameters, Location);
 -                      }
  
 -                      if (IsGeneric) {
 -                              foreach (TypeParameter type_param in TypeParameters)
 +                              foreach (TypeParameter type_param in TypeParameters) {
                                        if (!type_param.DefineType (ec)) {
                                                error = true;
                                                return null;
                                        }
 +                              }
 +
 +                              if (!CheckConstraints (ec)) {
 +                                      error = true;
 +                                      return null;
 +                              }
                        }
  
                        if ((Kind == Kind.Struct) && TypeManager.value_type == null)
                        return TypeBuilder;
                }
  
 +              protected virtual bool CheckConstraints (EmitContext ec)
 +              {
 +                      return true;
 +              }
 +
                protected virtual bool DefineNestedTypes ()
                {
                        if (Interfaces != null) {
  
                protected virtual bool DoDefineMembers ()
                {
 -                      //
 -                      // We need to be able to use the member cache while we are checking/defining
 -                      //
 -                      if (TypeBuilder.BaseType != null)
 -                              base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
 -
 -                      if (TypeBuilder.IsInterface)
 -                              base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
 -
                        if (IsTopLevel) {
                                if ((ModFlags & Modifiers.NEW) != 0)
                                        Error_KeywordNotAllowed (Location);
                        DefineContainerMembers (constants);
                        DefineContainerMembers (fields);
  
 -                      if ((Kind == Kind.Class) && !(this is ClassPart) && !(this is StaticClass)){
 +                      if ((Kind == Kind.Class) && !(this is ClassPart)){
                                if ((instance_constructors == null) &&
                                    !(this is StaticClass)) {
                                        if (default_constructor == null)
                                if (fields != null) {
                                        int len = fields.Count;
                                        for (int i = 0; i < len; i++) {
 -                                              Field f = (Field) fields [i];
 +                                              FieldMember f = (FieldMember) fields [i];
                                                
                                                if ((f.ModFlags & modflags) == 0)
                                                        continue;
                                                        continue;
  
                                                FieldBuilder fb = con.FieldBuilder;
 +                                              if (fb == null) {
 +                                                      if (con.Define ())
 +                                                              fb = con.FieldBuilder;
 +                                              }
                                                if (fb != null && filter (fb, criteria) == true) {
                                                        if (members == null)
                                                                members = new ArrayList ();
                                                        continue;
  
                                                TypeBuilder tb = t.TypeBuilder;
 +                                              if (tb == null)
 +                                                      tb = t.DefineType ();
 +
                                                if (tb != null && (filter (tb, criteria) == true)) {
                                                        if (members == null)
                                                                members = new ArrayList ();
                        }
                        
                        if (fields != null)
 -                              foreach (Field f in fields)
 +                              foreach (FieldMember f in fields)
                                        f.Emit ();
  
                        if (events != null){
  
                public virtual 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;
                        }
                }
                                        return null;
                                }
  
 +                              if (pc.IsGeneric) {
 +                                      if (pc.CountTypeParameters != member_name.CountTypeArguments) {
 +                                              Report.Error (
 +                                                      264, loc, "Partial declarations of `{0}' " +
 +                                                      "must have the same type parameter names in " +
 +                                                      "the same order", member_name.GetTypeName ());
 +                                              return null;
 +                                      }
 +
 +                                      string[] pc_names = pc.MemberName.TypeArguments.GetDeclarations ();
 +                                      string[] names = member_name.TypeArguments.GetDeclarations ();
 +
 +                                      for (int i = 0; i < pc.CountTypeParameters; i++) {
 +                                              if (pc_names [i] == names [i])
 +                                                      continue;
 +
 +                                              Report.Error (
 +                                                      264, loc, "Partial declarations of `{0}' " +
 +                                                      "must have the same type parameter names in " +
 +                                                      "the same order", member_name.GetTypeName ());
 +                                              return null;
 +                                      }
 +                              }
 +
                                return pc;
                        }
  
                        RootContext.Tree.RecordDecl (full_name, pc);
                        parent.AddType (pc);
                        pc.Register ();
 +                      // This is needed to define our type parameters; we define the constraints later.
 +                      pc.SetParameterInfo (null);
                        return pc;
                }
  
                        return PendingImplementation.GetPendingImplementations (this);
                }
  
 +              ArrayList constraints_lists;
 +
 +              public void UpdateConstraints (ArrayList constraints_list)
 +              {
 +                      //
 +                      // This is called for each ClassPart in a partial generic type declaration.
 +                      //
 +                      // If no constraints were specified for the part, just return.
 +                      // Otherwise, if we're called with constraints for the first time, they become
 +                      // the type's constraint.  If we're called with constraints again, we just
 +                      // store them somewhere so we can later check whether there are no conflicts.
 +                      //
 +                      if (constraints_list == null)
 +                              return;
 +
 +                      if (constraints_lists != null) {
 +                              constraints_lists.Add (constraints_list);
 +                              return;
 +                      }
 +
 +                      DoUpdateConstraints (null, constraints_list, false);
 +
 +                      constraints_lists = new ArrayList ();
 +              }
 +
 +              protected bool DoUpdateConstraints (EmitContext ec, ArrayList constraints_list, bool check)
 +              {
 +                      for (int i = 0; i < TypeParameters.Length; i++) {
 +                              string name = TypeParameters [i].Name;
 +
 +                              Constraints constraints = null;
 +                              if (constraints_list != null) {
 +                                      foreach (Constraints constraint in constraints_list) {
 +                                              if (constraint.TypeParameter == name) {
 +                                                      constraints = constraint;
 +                                                      break;
 +                                              }
 +                                      }
 +                              }
 +
 +                              if (!TypeParameters [i].UpdateConstraints (ec, constraints, check)) {
 +                                      Report.Error (265, Location, "Partial declarations of `{0}' have " +
 +                                                    "inconsistent constraints for type parameter `{1}'.",
 +                                                    MemberName.GetTypeName (), name);
 +                                      return false;
 +                              }
 +                      }
 +
 +                      return true;
 +              }
 +
 +              protected override bool CheckConstraints (EmitContext ec)
 +              {
 +                      if (constraints_lists == null)
 +                              return true;
 +
 +                      //
 +                      // If constraints were specified in more than one part of a
 +                      // partial generic type definition, they must be identical.
 +                      //
 +                      // Note that we must resolve them and then compute the fully
 +                      // resolved types since different parts may have different
 +                      // `using' aliases.  See gen-129.cs for an example.
 +
 +                      foreach (ArrayList constraints_list in constraints_lists) {
 +                              if (!DoUpdateConstraints (ec, constraints_list, true))
 +                                      return false;
 +                      }
 +
 +                      return true;
 +              }
 +
                public ClassPart AddPart (NamespaceEntry ns, int mod, Attributes attrs,
                                          Location l)
                {
                                interface_type, full, name, loc);
                }
  
 +              public override void SetParameterInfo (ArrayList constraints_list)
 +              {
 +                      PartialContainer.UpdateConstraints (constraints_list);
 +              }
 +
                public override MemberCache BaseCache {
                        get {
                                return PartialContainer.BaseCache;
  
                protected override bool CheckGenericOverride (MethodInfo method, string name)
                {
 -                      ParameterData pd = Invocation.GetParameterData (method);
 +                      ParameterData pd = TypeManager.GetParameterData (method);
  
                        for (int i = 0; i < ParameterTypes.Length; i++) {
                                GenericConstraints ogc = pd.GenericConstraints (i);
                        }
  
                        if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
 -                              Report.SymbolRelatedToPreviousError (conflict_symbol);
 -                              Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
 -                      }
 +                              Report.SymbolRelatedToPreviousError (conflict_symbol);
 +                              Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
 +                      }
  
                        return true;
                }
                        return TypeManager.GetFullNameSignature (FieldBuilder);
                }
  
 +              protected virtual bool IsFieldClsCompliant {
 +                      get {
 +                              if (FieldBuilder == null)
 +                                      return true;
 +
 +                              return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
 +                      }
 +              }
 +
                public override string[] ValidAttributeTargets {
                        get {
                                return attribute_targets;
                        if (!base.VerifyClsCompliance (ds))
                                return false;
  
 -                      if (FieldBuilder == null) {
 -                              return true;
 -                      }
 -
 -                      if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
 +                      if (!IsFieldClsCompliant) {
                                Report.Error (3003, Location, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
                        }
                        return true;
                        
                        MemberType = texpr.Type;
  
 +                      ec.InUnsafe = old_unsafe;
 +
                        if (MemberType == TypeManager.void_type) {
                                Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
                                return false;
                        }
  
 -                      ec.InUnsafe = old_unsafe;
 -
                        if (!CheckBase ())
                                return false;
                        
  
                public override void Emit ()
                {
 +                      if (OptAttributes != null) {
 +                              EmitContext ec = new EmitContext (Parent, Location, null, FieldBuilder.FieldType, ModFlags);
 +                              OptAttributes.Emit (ec, this);
 +                      }
 +
                        if (Parent.HasExplicitLayout && ((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0) {
                                Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
                        }
                }
        }
  
 +      interface IFixedBuffer
 +      {
 +              FieldInfo Element { get; }
 +              Type ElementType { get; }
 +      }
 +
 +      public class FixedFieldExternal: IFixedBuffer
 +      {
 +              FieldInfo element_field;
 +
 +              public FixedFieldExternal (FieldInfo fi)
 +              {
 +                      element_field = fi.FieldType.GetField (FixedField.FixedElementName);
 +              }
 +
 +              #region IFixedField Members
 +
 +              public FieldInfo Element {
 +                      get {
 +                              return element_field;
 +                      }
 +              }
 +
 +              public Type ElementType {
 +                      get {
 +                              return element_field.FieldType;
 +                      }
 +              }
 +
 +              #endregion
 +      }
 +
 +      /// <summary>
 +      /// Fixed buffer implementation
 +      /// </summary>
 +      public class FixedField: FieldMember, IFixedBuffer
 +      {
 +              public const string FixedElementName = "FixedElementField";
 +              static int GlobalCounter = 0;
 +              static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
 +              static FieldInfo[] fi;
 +
 +              TypeBuilder fixed_buffer_type;
 +              FieldBuilder element;
 +              Expression size_expr;
 +              int buffer_size;
 +
 +              const int AllowedModifiers =
 +                      Modifiers.NEW |
 +                      Modifiers.PUBLIC |
 +                      Modifiers.PROTECTED |
 +                      Modifiers.INTERNAL |
 +                      Modifiers.PRIVATE;
 +
 +              public FixedField (TypeContainer parent, Expression type, int mod, string name,
 +                      Expression size_expr, Attributes attrs, Location loc):
 +                      base (parent, type, mod, AllowedModifiers, new MemberName (name), null, attrs, loc)
 +              {
 +                      if (RootContext.Version == LanguageVersion.ISO_1)
 +                              Report.FeatureIsNotStandardized (loc, "fixed sized buffers");
 +
 +                      this.size_expr = size_expr;
 +              }
 +
 +              public override bool Define()
 +              {
 +#if !NET_2_0
 +                      if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
 +                              Report.Warning (-23, Location, "Only not private or internal fixed sized buffers are supported by .NET 1.x");
 +#endif
 +
 +                      if (Parent.Kind != Kind.Struct) {
 +                              Report.Error (1642, Location, "Fixed buffer fields may only be members of structs");
 +                              return false;
 +                      }
 +
 +                      if (!base.Define ())
 +                              return false;
 +
 +                      if (!MemberType.IsPrimitive) {
 +                              Report.Error (1663, Location, "Fixed sized buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double");
 +                              return false;
 +                      }
 +
 +                      Expression e = size_expr.Resolve (Parent.EmitContext);
 +                      if (e == null)
 +                              return false;
 +
 +                      Constant c = e as Constant;
 +                      if (c == null) {
 +                              Report.Error (133, Location, "The expression being assigned to '{0}' must be constant", GetSignatureForError ());
 +                              return false;
 +                      }
 +
 +                      buffer_size = (int)c.GetValue ();
 +                      if (buffer_size <= 0) {
 +                              Report.Error (1665, Location, "Fixed sized buffer '{0}' must have a length greater than zero", GetSignatureForError ());
 +                              return false;
 +                      }
 +                      buffer_size *= Expression.GetTypeSize (MemberType);
 +
 +                      // Define nested
 +                      string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
 +
 +                      fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
 +                              TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
 +                      element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
 +                      RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
 +
 +                      FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
 +                      TypeManager.RegisterFieldBase (FieldBuilder, this);
 +
 +                      return true;
 +              }
 +
 +              public override void Emit()
 +              {
 +                      if (fi == null)
 +                              fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
 +
 +                      object[] fi_val = new object[1];
 +                      fi_val [0] = buffer_size;
 +
 +                      CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
 +                              ctor_args, fi, fi_val);
 +                      fixed_buffer_type.SetCustomAttribute (cab);
 +
 +#if NET_2_0
 +                      cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
 +                      FieldBuilder.SetCustomAttribute (cab);
 +#endif
 +                      base.Emit ();
 +              }
 +
 +              protected override bool IsFieldClsCompliant {
 +                      get {
 +                              return false;
 +                      }
 +              }
 +
 +              #region IFixedField Members
 +
 +              public FieldInfo Element {
 +                      get {
 +                              return element;
 +                      }
 +              }
 +
 +              public Type ElementType {
 +                      get {
 +                              return MemberType;
 +                      }
 +              }
 +
 +              #endregion
 +      }
 +
        //
        // The Field class is used to represents class/struct fields during parsing.
        //
  
                        return true;
                }
 -
 -              public override void Emit ()
 -              {
 -                      if (OptAttributes != null) {
 -                              EmitContext ec = new EmitContext (
 -                                      Parent, Location, null, FieldBuilder.FieldType,
 -                                      ModFlags);
 -                              OptAttributes.Emit (ec, this);
 -              }
 -
 -                      base.Emit ();
 -              }
        }
  
        //
diff --combined mcs/gmcs/constant.cs
index 73de93f06f273af931fca1d08ccc103eaea55966,73de93f06f273af931fca1d08ccc103eaea55966..576c18a3b8f468b31ce02459bcd0f851ae980653
@@@ -162,6 -162,6 +162,10 @@@ namespace Mono.CSharp 
                        return null;
                }
                
++              public abstract bool IsDefaultValue {
++                      get;
++              }
++
                public abstract bool IsNegative {
                        get;
                }
                                ec.ig.Emit (OpCodes.Ldc_I4_0);
                }
                
++              public override bool IsDefaultValue {
++                      get {
++                              return !Value;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return false;
                        return new IntConstant (Value);
                }
                
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return false;
                        return new IntConstant (Value);
                }
                
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return false;
                        return new IntConstant (Value);
                }
                
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return Value < 0;
                {
                        return new IntConstant (Value);
                }
++
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
                
                public override bool IsZeroInteger {
                        get { return Value == 0; }
                        return new IntConstant (Value);
                }
                
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return false;
                {
                        return this;
                }
++
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
                
                public override bool IsNegative {
                        get {
                        return null;
                }
                
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return false;
                        return null;
                }
                
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return Value < 0;
                        return null;
                }
                
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return false;
                        return null;
                }
  
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return Value < 0;
                        return null;
                }
  
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return Value < 0;
                        ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
                }
  
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == 0;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return Value < 0;
                                ec.ig.Emit (OpCodes.Ldstr, Value);
                }
  
++              public override bool IsDefaultValue {
++                      get {
++                              return Value == null;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return false;
diff --combined mcs/gmcs/driver.cs
index 3d915575128ac0d0eb03816332aff8465d5b48d9,02f218d5e5e946da36bdda9137915c0708689059..4d74fe1cddae5ed9814fb48b9de6ac95a1f6eb9c
@@@ -220,7 -220,8 +220,8 @@@ namespace Mono.CShar
                                "   -noconfig[+|-]     Disables implicit references to assemblies\n" +
                                "   -nostdlib[+|-]     Does not load core libraries\n" +
                                "   -nowarn:W1[,W2]    Disables one or more warnings\n" + 
++                              "   -optimize[+|-]     Enables code optimalizations" + Environment.NewLine +
                                "   -out:FNAME         Specifies output file\n" +
 -                              "   -doc:XMLFILE         Generates xml documentation into specified file\n" +
                                "   -pkg:P1[,Pn]       References packages P1..Pn\n" + 
                                "   --expect-error X   Expect that error X will be encountered\n" +
                                "   -recurse:SPEC      Recursively compiles the files in SPEC ([dir]/file)\n" + 
                                "For more information on Mono, visit the project Web site\n" +
                                "   http://www.go-mono.com\n\n" +
  
 -                              "The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig and Marek Safar");
 +                              "The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig, Marek Safar, Raja R Harinath");
                        Environment.Exit (0);
                }
  
  
                        case "/optimize":
                        case "/optimize+":
++                              RootContext.Optimize = true;
++                              return true;
++
                        case "/optimize-":
++                              RootContext.Optimize = false;
++                              return true;
++
                        case "/incremental":
                        case "/incremental+":
                        case "/incremental-":
diff --combined mcs/gmcs/ecore.cs
index a0eba82f5500dfbf09e3cff7ffffac6d842b4f6e,4fb48ea2434a804d5654c938b07583b720961938..baf528bffae03ddaec3782e7ac4c4bb39085d332
@@@ -299,7 -299,7 +299,7 @@@ namespace Mono.CSharp 
  
                public virtual Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
--                      return DoResolve (ec);
++                      return null;
                }
  
                //
                /// </remarks>
                public Expression ResolveLValue (EmitContext ec, Expression right_side)
                {
++                      int errors = Report.Errors;
                        Expression e = DoResolveLValue (ec, right_side);
  
--                      if (e != null){
--                              if (e is SimpleName){
--                                      SimpleName s = (SimpleName) e;
--                                      MemberLookupFailed (ec, null, ec.ContainerType, s.Name,
--                                                          ec.DeclSpace.Name, loc);
--                                      return null;
--                              }
++                      if (e == null) {
++                              if (errors == Report.Errors)
++                                      Report.Error (131, Location, "The left-hand side of an assignment or mutating operation must be a variable, property or indexer");
++                              return null;
++                      }
  
++                      if (e != null){
                                if (e.eclass == ExprClass.Invalid)
                                        throw new Exception ("Expression " + e +
                                                             " ExprClass is Invalid after resolve");
                ///   Returns an expression that can be used to invoke operator true
                ///   on the expression if it exists.
                /// </summary>
 -              static public StaticCallExpr GetOperatorTrue (EmitContext ec, Expression e, Location loc)
 +              static public Expression GetOperatorTrue (EmitContext ec, Expression e, Location loc)
                {
                        return GetOperatorTrueOrFalse (ec, e, true, loc);
                }
                ///   Returns an expression that can be used to invoke operator false
                ///   on the expression if it exists.
                /// </summary>
 -              static public StaticCallExpr GetOperatorFalse (EmitContext ec, Expression e, Location loc)
 +              static public Expression GetOperatorFalse (EmitContext ec, Expression e, Location loc)
                {
                        return GetOperatorTrueOrFalse (ec, e, false, loc);
                }
  
 -              static StaticCallExpr GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
 +              static Expression GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
                {
                        MethodBase method;
                        Expression operator_group;
  
 +                      if (TypeManager.IsNullableType (e.Type))
 +                              return new Nullable.OperatorTrueOrFalse (e, is_true, loc).Resolve (ec);
 +
                        operator_group = MethodLookup (ec, e.Type, is_true ? "op_True" : "op_False", loc);
                        if (operator_group == null)
                                return null;
                                sb.Append (valid [i]);
                        }
  
 -                      Error (119, "Expression denotes a `" + ExprClassName () + "' where " +
 +                      Report.Error (119, loc, "Expression denotes a `" + ExprClassName () + "' where " +
                               "a `" + sb.ToString () + "' was expected");
                }
                
                public EmptyCast (Expression child, Type return_type)
                {
                        eclass = child.eclass;
++                      loc = child.Location;
                        type = return_type;
                        this.child = child;
                }
                        child.Emit (ec);
                }
  
++              public override bool IsDefaultValue {
++                      get {
++                              throw new NotImplementedException ();
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return false;
                {
                        return Child.ConvertToInt ();
                }
--              
++
++              public override bool IsDefaultValue {
++                      get {
++                              return Child.IsDefaultValue;
++                      }
++              }
++
                public override bool IsZeroInteger {
                        get { return Child.IsZeroInteger; }
                }
                        int errors = Report.Errors;
                        dt = ec.ResolvingTypeTree 
                                ? ds.FindType (loc, Name)
 -                              : ds.LookupType (Name, true, loc);
 +                              : ds.LookupType (Name, loc, /*silent=*/ true, /*ignore_cs0104=*/ false);
                        if (Report.Errors != errors)
                                return null;
  
        ///   section 10.8.1 (Fully Qualified Names).
        /// </summary>
        public abstract class FullNamedExpression : Expression {
 +              public override FullNamedExpression ResolveAsTypeStep (EmitContext ec)
 +              {
 +                      return this;
 +              }
 +
                public abstract string FullName {
                        get;
                }
                protected override TypeExpr DoResolveAsTypeStep (EmitContext ec)
                {
                        if (type == null) {
 -                              FullNamedExpression t = ec.DeclSpace.LookupType (name, false, Location.Null);
 +                              FullNamedExpression t = ec.DeclSpace.LookupType (
 +                                      name, Location.Null, /*silent=*/ false, /*ignore_cs0104=*/ false);
                                if (t == null)
                                        return null;
                                if (!(t is TypeExpr))
                                if (is_volatile)
                                        ig.Emit (OpCodes.Volatile);
  
 -                              ig.Emit (OpCodes.Ldfld, FieldInfo);
 +                              IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo);
 +                              if (ff != null)
 +                              {
 +                                      ig.Emit (OpCodes.Ldflda, FieldInfo);
 +                                      ig.Emit (OpCodes.Ldflda, ff.Element);
 +                              }
 +                              else {
 +                                      ig.Emit (OpCodes.Ldfld, FieldInfo);
 +                              }
                        }
  
                        if (leave_copy) {
                        return true;
                }
  
++              public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
++              {
++                      return DoResolve (ec);
++              }
++
                public override Expression DoResolve (EmitContext ec)
                {
                        if (instance_expr != null) {
diff --combined mcs/gmcs/expression.cs
index d395ac505f5b59b4efc81c15aee6379b760864c9,2bd435d050d4b1cce2e2279d285a7b75e0448f51..4a7f5f28b7edaf741f0467dbda5c051f4934ac2c
@@@ -416,11 -416,11 +416,6 @@@ namespace Mono.CSharp 
                                return this;
  
                        case Operator.AddressOf:
--                              if (Expr.eclass != ExprClass.Variable){
--                                      Error (211, "Cannot take the address of non-variables");
--                                      return null;
--                              }
--                              
                                if (!ec.InUnsafe) {
                                        UnsafeError (loc); 
                                        return null;
                                }
  
                                IVariable variable = Expr as IVariable;
 -                              if (!ec.InFixedInitializer && ((variable == null) || !variable.VerifyFixed (false))) {
 +                              bool is_fixed = variable != null && variable.VerifyFixed (false);
 +
 +                              if (!ec.InFixedInitializer && !is_fixed) {
                                        Error (212, "You can only take the address of an unfixed expression inside " +
                                               "of a fixed statement initializer");
                                        return null;
                                }
  
 -                              if (ec.InFixedInitializer && ((variable != null) && variable.VerifyFixed (false))) {
 +                              if (ec.InFixedInitializer && is_fixed) {
                                        Error (213, "You can not fix an already fixed expression");
                                        return null;
                                }
  
                public override Expression DoResolve (EmitContext ec)
                {
--                      if (Oper == Operator.AddressOf)
--                              Expr = Expr.ResolveLValue (ec, new EmptyExpression ());
++                      if (Oper == Operator.AddressOf) {
++                              Expr = Expr.DoResolveLValue (ec, new EmptyExpression ());
++
++                              if (Expr == null || Expr.eclass != ExprClass.Variable){
++                                      Error (211, "Cannot take the address of non-variables");
++                                      return null;
++                              }
++                      }
                        else
                                Expr = Expr.Resolve (ec);
                        
                        if (Expr == null)
                                return null;
  
 +                      if (TypeManager.IsNullableType (Expr.Type))
 +                              return new Nullable.LiftedUnaryOperator (Oper, Expr, loc).Resolve (ec);
 +
                        eclass = ExprClass.Value;
                        return ResolveOperator (ec);
                }
                public override Expression DoResolveLValue (EmitContext ec, Expression right)
                {
                        if (Oper == Operator.Indirection)
--                              return base.DoResolveLValue (ec, right);
++                              return DoResolve (ec);
  
--                      Error (131, "The left-hand side of an assignment must be a " +
--                             "variable, property or indexer");
                        return null;
                }
  
        // after semantic analysis (this is so we can take the address
        // of an indirection).
        //
 -      public class Indirection : Expression, IMemoryLocation, IAssignMethod {
 +      public class Indirection : Expression, IMemoryLocation, IAssignMethod, IVariable {
                Expression expr;
                LocalTemporary temporary;
                bool prepared;
                public Indirection (Expression expr, Location l)
                {
                        this.expr = expr;
 -                      this.type = TypeManager.GetElementType (expr.Type);
 +                      type = TypeManager.HasElementType (expr.Type) ? TypeManager.GetElementType (expr.Type) : expr.Type;
                        eclass = ExprClass.Variable;
                        loc = l;
                }
                        expr.Emit (ec);
                }
  
++              public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
++              {
++                      return DoResolve (ec);
++              }
++
                public override Expression DoResolve (EmitContext ec)
                {
                        //
                {
                        return "*(" + expr + ")";
                }
 +
 +              #region IVariable Members
 +
 +              public VariableInfo VariableInfo {
 +                      get {
 +                              return null;
 +                      }
 +              }
 +
 +              public bool VerifyFixed (bool is_expression)
 +              {
 +                      return true;
 +              }
 +
 +              #endregion
        }
        
        /// <summary>
  
                        mg = MemberLookup (ec, expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);
  
--                      if (mg == null && expr_type.BaseType != null)
--                              mg = MemberLookup (ec, expr_type.BaseType, op_name,
--                                                 MemberTypes.Method, AllBindingFlags, loc);
--                      
                        if (mg != null) {
                                method = StaticCallExpr.MakeSimpleCall (
                                        ec, (MethodGroupExpr) mg, expr, loc);
  
                                type = method.Type;
--                              return this;
++                      } else if (!IsIncrementableNumber (expr_type)) {
++                              Error (187, "No such operator '" + OperName (mode) + "' defined for type '" +
++                                     TypeManager.CSharpName (expr_type) + "'");
++                                 return null;
                        }
  
                        //
                        type = expr_type;
                        if (expr.eclass == ExprClass.Variable){
                                LocalVariableReference var = expr as LocalVariableReference;
--                              if ((var != null) && var.IsReadOnly)
++                              if ((var != null) && var.IsReadOnly) {
                                        Error (1604, "cannot assign to `" + var.Name + "' because it is readonly");
--                              if (IsIncrementableNumber (expr_type) ||
--                                  expr_type == TypeManager.decimal_type){
--                                      return this;
++                                      return null;
                                }
--                      } else if (expr.eclass == ExprClass.IndexerAccess){
--                              IndexerAccess ia = (IndexerAccess) expr;
--                              
--                              expr = ia.ResolveLValue (ec, this);
++                      } else if (expr.eclass == ExprClass.IndexerAccess || expr.eclass == ExprClass.PropertyAccess){
++                              expr = expr.ResolveLValue (ec, this);
                                if (expr == null)
                                        return null;
--
--                              return this;
--                      } else if (expr.eclass == ExprClass.PropertyAccess){
--                              PropertyExpr pe = (PropertyExpr) expr;
--
--                              if (pe.VerifyAssignable ())
--                                      return this;
--
--                              return null;
                        } else {
                                expr.Error_UnexpectedKind ("variable, indexer or property access", loc);
                                return null;
                        }
  
--                      Error (187, "No such operator '" + OperName (mode) + "' defined for type '" +
--                             TypeManager.CSharpName (expr_type) + "'");
--                      return null;
++                      return this;
                }
  
                public override Expression DoResolve (EmitContext ec)
                                return null;
  
                        eclass = ExprClass.Value;
 +
 +                      if (TypeManager.IsNullableType (expr.Type))
 +                              return new Nullable.LiftedUnaryMutator (mode, expr, loc).Resolve (ec);
 +
                        return ResolveOperator (ec);
                }
  
                        this.is_expr = is_expr;
                        ((IAssignMethod) expr).EmitAssign (ec, this, is_expr && (mode == Mode.PreIncrement || mode == Mode.PreDecrement), true);
                }
 -              
  
                public override void Emit (EmitContext ec)
                {
                        return null;
                }
                
 +              public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
 +              {
 +                      expr = expr.DoResolveLValue (ec, right_side);
 +                      if (expr == null)
 +                              return null;
 +
 +                      return ResolveRest (ec);
 +              }
 +
                public override Expression DoResolve (EmitContext ec)
                {
                        expr = expr.Resolve (ec);
                        if (expr == null)
                                return null;
  
 +                      return ResolveRest (ec);
 +              }
 +
 +              Expression ResolveRest (EmitContext ec)
 +              {
                        TypeExpr target = target_type.ResolveAsTypeTerminal (ec);
                        if (target == null)
                                return null;
                        expr = Convert.ExplicitConversion (ec, expr, type, loc);
                        return expr;
                }
 -
 +              
                public override void Emit (EmitContext ec)
                {
                        //
                                        return this;
                                }
  
 +                              bool left_is_null = left is NullLiteral;
 +                              bool right_is_null = right is NullLiteral;
 +                              if (left_is_null || right_is_null) {
 +                                      if (oper == Operator.Equality)
 +                                              return new BoolLiteral (left_is_null == right_is_null);
 +                                      else
 +                                              return new BoolLiteral (left_is_null != right_is_null);
 +                              }
 +
                                //
                                // operator != (object a, object b)
                                // operator == (object a, object b)
                                        if (((right.eclass == ExprClass.MethodGroup) ||
                                             (r == TypeManager.anonymous_method_type))){
                                                if ((RootContext.Version != LanguageVersion.ISO_1)){
 -                                              Expression tmp = Convert.ImplicitConversionRequired (ec, right, l, loc);
 -                                              if (tmp == null)
 -                                                      return null;
 -                                              right = tmp;
 -                                              r = right.Type;
 -                                      }
 +                                                      Expression tmp = Convert.ImplicitConversionRequired (ec, right, l, loc);
 +                                                      if (tmp == null)
 +                                                              return null;
 +                                                      right = tmp;
 +                                                      r = right.Type;
 +                                              }
                                        }
                                
                                        if (TypeManager.IsDelegateType (r)){
 -                                      MethodInfo method;
 -                                      ArrayList args = new ArrayList (2);
 +                                              MethodInfo method;
 +                                              ArrayList args = new ArrayList (2);
                                        
 -                                      args = new ArrayList (2);
 -                                      args.Add (new Argument (left, Argument.AType.Expression));
 -                                      args.Add (new Argument (right, Argument.AType.Expression));
 +                                              args = new ArrayList (2);
 +                                              args.Add (new Argument (left, Argument.AType.Expression));
 +                                              args.Add (new Argument (right, Argument.AType.Expression));
                                        
 -                                      if (oper == Operator.Addition)
 -                                              method = TypeManager.delegate_combine_delegate_delegate;
 -                                      else
 -                                              method = TypeManager.delegate_remove_delegate_delegate;
 +                                              if (oper == Operator.Addition)
 +                                                      method = TypeManager.delegate_combine_delegate_delegate;
 +                                              else
 +                                                      method = TypeManager.delegate_remove_delegate_delegate;
  
 -                                      if (l != r) {
 -                                              Error_OperatorCannotBeApplied ();
 -                                              return null;
 -                                      }
 +                                              if (!TypeManager.IsEqual (l, r)) {
 +                                                      Error_OperatorCannotBeApplied ();
 +                                                      return null;
 +                                              }
  
 -                                      return new BinaryDelegate (l, method, args);
 -                              }
 +                                              return new BinaryDelegate (l, method, args);
 +                                      }
                                }
  
                                //
                                                return e;
                        }
  
 +                      if (TypeManager.IsNullableType (left.Type) || TypeManager.IsNullableType (right.Type))
 +                              return new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
 +
                        return ResolveOperator (ec);
                }
  
                {
                        Type op_type = left.Type;
                        ILGenerator ig = ec.ig;
 -                      Type element = TypeManager.GetElementType (op_type);
 +                      
 +                      // It must be either array or fixed buffer
 +                      Type element = TypeManager.HasElementType (op_type) ?
 +                              element = TypeManager.GetElementType (op_type) :
 +                              element = AttributeTester.GetFixedBuffer (((FieldExpr)left).FieldInfo).ElementType;
 +
                        int size = GetTypeSize (element);
                        Type rtype = right.Type;
                        
                                //
                                left.Emit (ec);
                                ig.Emit (OpCodes.Conv_I);
 -                              right.Emit (ec);
 -                              if (size != 1){
 -                                      if (size == 0)
 -                                              ig.Emit (OpCodes.Sizeof, element);
 -                                      else 
 -                                              IntLiteral.EmitInt (ig, size);
 -                                      if (rtype == TypeManager.int64_type)
 -                                              ig.Emit (OpCodes.Conv_I8);
 -                                      else if (rtype == TypeManager.uint64_type)
 -                                              ig.Emit (OpCodes.Conv_U8);
 -                                      ig.Emit (OpCodes.Mul);
 +
 +                              Constant right_const = right as Constant;
 +                              if (right_const != null && size != 0) {
 +                                      Expression ex = ConstantFold.BinaryFold (ec, Binary.Operator.Multiply, new IntConstant (size), right_const, loc);
 +                                      if (ex == null)
 +                                              return;
 +                                      ex.Emit (ec);
 +                              } else {
 +                                      right.Emit (ec);
 +                                      if (size != 1){
 +                                              if (size == 0)
 +                                                      ig.Emit (OpCodes.Sizeof, element);
 +                                              else 
 +                                                      IntLiteral.EmitInt (ig, size);
 +                                              if (rtype == TypeManager.int64_type)
 +                                                      ig.Emit (OpCodes.Conv_I8);
 +                                              else if (rtype == TypeManager.uint64_type)
 +                                                      ig.Emit (OpCodes.Conv_U8);
 +                                              ig.Emit (OpCodes.Mul);
 +                                      }
                                }
                                
                                if (rtype == TypeManager.int64_type || rtype == TypeManager.uint64_type)
  
                        if (expr == null)
                                return null;
 +
 +                      if (TypeManager.IsNullableType (expr.Type))
 +                              return new Nullable.LiftedConditional (expr, trueExpr, falseExpr, loc).Resolve (ec);
                        
                        if (expr.Type != TypeManager.bool_type){
                                expr = Expression.ResolveBoolean (
                        ILGenerator ig = ec.ig;
                        int arg_idx = idx;
  
 -                      if (!ec.IsStatic)
 +                      if (!ec.MethodIsStatic)
                                arg_idx++;
 +                      
  
                        EmitLdArg (ig, arg_idx);
  
                        ILGenerator ig = ec.ig;
                        int arg_idx = idx;
  
 -                      if (!ec.IsStatic)
 +                      if (!ec.MethodIsStatic)
                                arg_idx++;
  
                        EmitLdArg (ig, arg_idx);
                        
                        prepared = prepare_for_load;
                        
 -                      if (!ec.IsStatic)
 +                      if (!ec.MethodIsStatic)
                                arg_idx++;
  
                        if (is_ref && !prepared)
                        
                        int arg_idx = idx;
  
 -                      if (!ec.IsStatic)
 +                      if (!ec.MethodIsStatic)
                                arg_idx++;
  
                        if (is_ref){
                        return true;
                }
                
++              void Error_LValueRequired (Location loc)
++              {
++                      Report.Error (1510, loc, "An lvalue is required as an argument to out or ref");
++              }
++
                public bool Resolve (EmitContext ec, Location loc)
                {
                        if (ArgType == AType.Ref) {
                                                return false;
                                        }
                                }
--                              Expr = Expr.ResolveLValue (ec, Expr);
--                      } else if (ArgType == AType.Out)
--                              Expr = Expr.ResolveLValue (ec, EmptyExpression.Null);
++                              Expr = Expr.DoResolveLValue (ec, Expr);
++                              if (Expr == null)
++                                      Error_LValueRequired (loc);
++                      } else if (ArgType == AType.Out) {
++                              Expr = Expr.DoResolveLValue (ec, EmptyExpression.Null);
++                              if (Expr == null)
++                                      Error_LValueRequired (loc);
++                      }
                        else
                                Expr = Expr.Resolve (ec);
  
                        if (Expr == null)
                                return false;
  
++                      if (Expr is IMemberExpr) {
++                              IMemberExpr me = Expr as IMemberExpr;
++
++                              //
++                              // This can happen with the following code:
++                              //
++                              //   class X {}
++                              //   class Y {
++                              //     public Y (X x) {}
++                              //   }
++                              //   class Z : Y {
++                              //     X X;
++                              //     public Z () : base (X) {}
++                              //   }
++                              //
++                              // SimpleNameResolve is conservative about flagging the X as
++                              // an error since it has identical name and type.  However,
++                              // because there's no MemberAccess, that is not really justified.
++                              // It is still simpler to fix it here, rather than in SimpleNameResolve.
++                              //
++                              if (me.IsInstance && me.InstanceExpression == null) {
++                                      SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
++                                      return false;
++                              }
++                      }
++
                        if (ArgType == AType.Expression)
                                return true;
                        else {
                                                "A property or indexer can not be passed as an out or ref " +
                                                "parameter");
                                } else {
--                                      Report.Error (
--                                              1510, loc,
--                                              "An lvalue is required as an argument to out or ref");
++                                      Error_LValueRequired (loc);
                                }
                                return false;
                        }
                Expression expr;
                MethodBase method = null;
                
 -              static Hashtable method_parameter_cache;
 -
 -              static Invocation ()
 -              {
 -                      method_parameter_cache = new PtrHashtable ();
 -              }
 -                      
                //
                // arguments is an ArrayList, but we do not want to typecast,
                // as it might be null.
                        }
                }
  
 -              /// <summary>
 -              ///   Returns the Parameters (a ParameterData interface) for the
 -              ///   Method `mb'
 -              /// </summary>
 -              public static ParameterData GetParameterData (MethodBase mb)
 -              {
 -                      object pd = method_parameter_cache [mb];
 -                      object ip;
 -                      
 -                      if (pd != null)
 -                              return (ParameterData) pd;
 -
 -                      ip = TypeManager.LookupParametersByBuilder (mb);
 -                      if (ip != null){
 -                              method_parameter_cache [mb] = ip;
 -
 -                              return (ParameterData) ip;
 -                      } else {
 -                              ReflectionParameters rp = new ReflectionParameters (mb);
 -                              method_parameter_cache [mb] = rp;
 -
 -                              return (ParameterData) rp;
 -                      }
 -              }
 -
                /// <summary>
                ///   Determines "better conversion" as specified in 7.4.2.3
                ///
                                           MethodBase candidate, bool candidate_params,
                                           MethodBase best, bool best_params, Location loc)
                {
 -                      ParameterData candidate_pd = GetParameterData (candidate);
 -                      ParameterData best_pd = GetParameterData (best);
 +                      ParameterData candidate_pd = TypeManager.GetParameterData (candidate);
 +                      ParameterData best_pd = TypeManager.GetParameterData (best);
                
 -                      int cand_count = candidate_pd.Count;
 -
 -                      //
 -                      // If there is no best method, than this one
 -                      // is better, however, if we already found a
 -                      // best method, we cant tell. This happens
 -                      // if we have:
 -                      // 
 -                      //      interface IFoo {
 -                      //              void DoIt ();
 -                      //      }
 -                      //      
 -                      //      interface IBar {
 -                      //              void DoIt ();
 -                      //      }
 -                      //      
 -                      //      interface IFooBar : IFoo, IBar {}
 -                      //
 -                      // We cant tell if IFoo.DoIt is better than IBar.DoIt
 -                      //
 -                      // However, we have to consider that
 -                      // Trim (); is better than Trim (params char[] chars);
 -                        //
 -                      if (cand_count == 0 && argument_count == 0)
 -                              return !candidate_params && best_params;
 -
 -                      if ((candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.PARAMS) &&
 -                          (candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.ARGLIST))
 -                              if (cand_count != argument_count)
 -                                      return false;
 -
                        bool better_at_least_one = false;
 -                      bool is_equal = true;
 -
 +                      bool same = true;
                        for (int j = 0; j < argument_count; ++j) {
                                Argument a = (Argument) args [j];
  
                                        if (best_params)
                                                bt = TypeManager.GetElementType (bt);
  
 -                              if (!ct.Equals (bt))
 -                                      is_equal = false;
 +                              if (ct.Equals (bt))
 +                                      continue;
  
 +                              same = false;
                                Type better = BetterConversion (ec, a, ct, bt, loc);
                                // for each argument, the conversion to 'ct' should be no worse than 
                                // the conversion to 'bt'.
                                        better_at_least_one = true;
                        }
  
 -                        //
 -                        // If a method (in the normal form) with the
 -                        // same signature as the expanded form of the
 -                        // current best params method already exists,
 -                        // the expanded form is not applicable so we
 -                        // force it to select the candidate
 -                        //
 -                        if (!candidate_params && best_params && cand_count == argument_count)
 -                                return true;
 +                      if (better_at_least_one)
 +                              return true;
 +
 +                      if (!same)
 +                              return false;
  
                        //
                        // If two methods have equal parameter types, but
                        // only one of them is generic, the non-generic one wins.
                        //
 -                      if (is_equal) {
 -                              if (TypeManager.IsGenericMethod (best) && !TypeManager.IsGenericMethod (candidate))
 -                                      return true;
 -                              else if (!TypeManager.IsGenericMethod (best) && TypeManager.IsGenericMethod (candidate))
 +                      if (TypeManager.IsGenericMethod (best) && !TypeManager.IsGenericMethod (candidate))
 +                              return true;
 +                      else if (!TypeManager.IsGenericMethod (best) && TypeManager.IsGenericMethod (candidate))
 +                              return false;
 +
 +                      //
 +                      // This handles the case
 +                      //
 +                      //   Add (float f1, float f2, float f3);
 +                      //   Add (params decimal [] foo);
 +                      //
 +                      // The call Add (3, 4, 5) should be ambiguous.  Without this check, the
 +                      // first candidate would've chosen as better.
 +                      //
 +                      //
 +                      // This handles the following cases:
 +                      //
 +                      //   Trim () is better than Trim (params char[] chars)
 +                      //   Concat (string s1, string s2, string s3) is better than
 +                      //     Concat (string s1, params string [] srest)
 +                      //
 +                        return !candidate_params && best_params;
 +              }
 +
 +              static bool IsOverride (MethodBase cand_method, MethodBase base_method)
 +              {
 +                      if (!IsAncestralType (base_method.DeclaringType, cand_method.DeclaringType))
 +                              return false;
 +
 +                      ParameterData cand_pd = TypeManager.GetParameterData (cand_method);
 +                      ParameterData 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.ParameterModifier (j);
 +                              Parameter.Modifier bm = base_pd.ParameterModifier (j);
 +                              Type ct = TypeManager.TypeToCoreType (cand_pd.ParameterType (j));
 +                              Type bt = TypeManager.TypeToCoreType (base_pd.ParameterType (j));
 +
 +                              if (cm != bm || ct != bt)
                                        return false;
                        }
  
 -                      return better_at_least_one;
 +                      return true;
                }
  
                public static string FullMethodDesc (MethodBase mb)
                        sb.Append (".");
                        sb.Append (mb.Name);
                        
 -                      ParameterData pd = GetParameterData (mb);
 +                      ParameterData pd = TypeManager.GetParameterData (mb);
  
                        int count = pd.Count;
                        sb.Append (" (");
                                                      int arg_count, MethodBase candidate,
                                                      bool do_varargs)
                {
 -                      ParameterData pd = GetParameterData (candidate);
 +                      ParameterData pd = TypeManager.GetParameterData (candidate);
                        
                        int pd_count = pd.Count;
  
                static bool IsApplicable (EmitContext ec, ArrayList arguments, int arg_count,
                                          MethodBase candidate)
                {
 -                      ParameterData pd = GetParameterData (candidate);
 +                      ParameterData pd = TypeManager.GetParameterData (candidate);
  
                        if (arg_count != pd.Count)
                                return false;
                        Type applicable_type = null;
                        int arg_count = 0;
                        ArrayList candidates = new ArrayList ();
 +                      ArrayList candidate_overrides = new ArrayList ();
  
                          //
                          // Used to keep a map between the candidate
                                    IsAncestralType (decl_type, applicable_type))
                                        continue;
  
 +                              //
 +                              // 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.
 +                              // We avoid doing the 'applicable' test here, since it'll anyway be applied
 +                              // to the base virtual function, and IsOverride is much faster than IsApplicable.
 +                              //
 +                              if (!me.IsBase &&
 +                                  methods [i].IsVirtual &&
 +                                  (methods [i].Attributes & MethodAttributes.NewSlot) == 0) {
 +                                      candidate_overrides.Add (methods [i]);
 +                                      continue;
 +                              }
 +
                                //
                                // Check if candidate is applicable (section 14.4.2.1)
                                //   Is candidate applicable in normal form?
  
                        int candidate_top = candidates.Count;
  
 -                      if (candidate_top == 0) {
 +                      if (applicable_type == null) {
                                //
                                // Okay so we have failed to find anything so we
                                // return by providing info about the closest match
                                //
                                for (int i = 0; i < methods.Length; ++i) {
                                        MethodBase c = (MethodBase) methods [i];
 -                                      ParameterData pd = GetParameterData (c);
 +                                      ParameterData pd = TypeManager.GetParameterData (c);
  
                                        if (pd.Count != arg_count)
                                                continue;
                                          
                                        for (int i = 0; i < methods.Length; ++i) {
                                                MethodBase c = methods [i];
 -                                              ParameterData pd = GetParameterData (c);
 +                                              ParameterData pd = TypeManager.GetParameterData (c);
  
                                                if (pd.Count != arg_count)
                                                        continue;
                                        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) {
 -                                              Type decl_type = ((MethodBase) candidates[i]).DeclaringType;
 +                                              MethodBase candidate = (MethodBase) candidates [i];
 +                                              Type decl_type = candidate.DeclaringType;
  
                                                if (decl_type == applicable_type) {
 -                                                      candidates[k++] = candidates[j];
 -                                                      candidates[j++] = candidates[i];
 +                                                      candidates [k++] = candidates [j];
 +                                                      candidates [j++] = candidates [i];
                                                        continue;
                                                }
  
                                                    IsAncestralType (decl_type, next_applicable_type))
                                                        continue;
  
 -                                              candidates[k++] = candidates[i];
 +                                              candidates [k++] = candidates [i];
  
- #if false
-                                               //
-                                               // Methods marked 'override' don't take part in 'applicable_type'
-                                               // computation.
-                                               //
-                                               if (!me.IsBase &&
-                                                   candidate.IsVirtual &&
-                                                   (candidate.Attributes & MethodAttributes.NewSlot) == 0)
-                                                       continue;
- #endif
                                                if (next_applicable_type == null ||
                                                    IsAncestralType (next_applicable_type, decl_type))
                                                        next_applicable_type = decl_type;
                          // Now we actually find the best method
                          //
  
 -                      method = (MethodBase) candidates[0];
 +                      method = (MethodBase) candidates [0];
                        method_params = candidate_to_form != null && candidate_to_form.Contains (method);
                        for (int ix = 1; ix < candidate_top; ix++){
                                MethodBase candidate = (MethodBase) candidates [ix];
 +
 +                              if (candidate == method)
 +                                      continue;
 +
                                bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
  
                                if (BetterFunction (ec, Arguments, arg_count, 
                                return null;
                        }
  
 +                      //
 +                      // If the method is a virtual function, pick an override closer to the LHS type.
 +                      //
 +                      if (!me.IsBase && method.IsVirtual) {
 +                              if ((method.Attributes & MethodAttributes.NewSlot) != MethodAttributes.NewSlot)
 +                                      throw new InternalErrorException (
 +                                              "Should not happen.  An 'override' method took part in overload resolution: " + method);
 +                                                                  
 +                              foreach (MethodBase candidate in candidate_overrides) {
 +                                      if (IsOverride (candidate, method))
 +                                              method = candidate;
 +                              }
 +                      }
 +
                        //
                        // And now check if the arguments are all
                        // compatible, perform conversions if
                                                          Type delegate_type, bool may_fail,
                                                          Location loc)
                {
 -                      ParameterData pd = GetParameterData (method);
 +                      ParameterData pd = TypeManager.GetParameterData (method);
                        int pd_count = pd.Count;
                        
                        for (int j = 0; j < arg_count; j++) {
                {
                        ParameterData pd;
                        if (mb != null)
 -                              pd = GetParameterData (mb);
 +                              pd = TypeManager.GetParameterData (mb);
                        else
                                pd = null;
                        
                static Type[] GetVarargsTypes (EmitContext ec, MethodBase mb,
                                               ArrayList arguments)
                {
 -                      ParameterData pd = GetParameterData (mb);
 +                      ParameterData pd = TypeManager.GetParameterData (mb);
  
                        if (arguments == null)
                                return new Type [0];
  //                    value_target = MyEmptyExpression;
                }
  
 +
 +              /// <summary>
 +              /// Converts complex core type syntax like 'new int ()' to simple constant
 +              /// </summary>
 +              Expression Constantify (Type t)
 +              {
 +                      if (t == TypeManager.int32_type)
 +                              return new IntConstant (0);
 +                      if (t == TypeManager.uint32_type)
 +                              return new UIntConstant (0);
 +                      if (t == TypeManager.int64_type)
 +                              return new LongConstant (0);
 +                      if (t == TypeManager.uint64_type)
 +                              return new ULongConstant (0);
 +                      if (t == TypeManager.float_type)
 +                              return new FloatConstant (0);
 +                      if (t == TypeManager.double_type)
 +                              return new DoubleConstant (0);
 +                      if (t == TypeManager.short_type)
 +                              return new ShortConstant (0);
 +                      if (t == TypeManager.ushort_type)
 +                              return new UShortConstant (0);
 +                      if (t == TypeManager.sbyte_type)
 +                              return new SByteConstant (0);
 +                      if (t == TypeManager.byte_type)
 +                              return new ByteConstant (0);
 +                      if (t == TypeManager.char_type)
 +                              return new CharConstant ('\0');
 +                      if (t == TypeManager.bool_type)
 +                              return new BoolConstant (false);
 +                      if (t == TypeManager.decimal_type)
 +                              return new DecimalConstant (0);
 +
 +                      return null;
 +              }
 +
                public override Expression DoResolve (EmitContext ec)
                {
                        //
                        TypeExpr texpr = RequestedType.ResolveAsTypeTerminal (ec);
                        if (texpr == null)
                                return null;
 +
 +                      if (Arguments == null) {
 +                              Expression c = Constantify (type);
 +                              if (c != null)
 +                                      return c;
 +                      }
                        
                        type = texpr.Type;
                        if (type == null)
                                                // If we are dealing with a struct, get the
                                                // address of it, so we can store it.
                                                //
 -                                              if ((dims == 1) && 
 -                                                  etype.IsSubclassOf (TypeManager.value_type) &&
 +                                              if ((dims == 1) && etype.IsValueType &&
                                                    (!TypeManager.IsBuiltinOrEnum (etype) ||
                                                     etype == TypeManager.decimal_type)) {
                                                        if (e is New){
                        if ((block != null) && (block.ThisVariable != null))
                                variable_info = block.ThisVariable.VariableInfo;
  
 +                      if (ec.CurrentAnonymousMethod != null)
 +                              ec.CaptureThis ();
 +                      
                        return true;
                }
  
                        if (sn == null || left == null || left.Type.Name != sn.Name)
                                return false;
  
 -                      return ec.DeclSpace.LookupType (sn.Name, true, loc) != null;
 +                      return ec.DeclSpace.LookupType (sn.Name, loc, /*silent=*/ true, /*ignore_cs0104*/ true) != null;
                }
                
                // TODO: possible optimalization
  
                                                object real_value = ((Constant) c.Expr).GetValue ();
  
 -                                              return Constantify (real_value, t);
 +                                              Expression exp = Constantify (real_value, t);
 +
 +                                              if (left_is_explicit && !left_is_type && !IdenticalNameAndTypeName (ec, left_original, left, loc)) {
 +                                                      Report.SymbolRelatedToPreviousError (c);
 +                                                      error176 (loc, c.GetSignatureForError ());
 +                                                      return null;
 +                                              }
 +                                      
 +                                              return exp;
                                        }
                                }
  
                }
  
                public override FullNamedExpression ResolveAsTypeStep (EmitContext ec)
 +              {
 +                      return ResolveNamespaceOrType (ec, false);
 +              }
 +
 +              public FullNamedExpression ResolveNamespaceOrType (EmitContext ec, bool silent)
                {
                        FullNamedExpression new_expr = expr.ResolveAsTypeStep (ec);
  
                                FullNamedExpression retval = ns.Lookup (ec.DeclSpace, lookup_id, loc);
                                if ((retval != null) && (args != null))
                                        retval = new ConstructedType (retval, args, loc).ResolveAsTypeStep (ec);
 -                              if (retval == null)
 +                              if (!silent && retval == null)
                                        Report.Error (234, loc, "The type or namespace name `{0}' could not be found in namespace `{1}'", Identifier, ns.FullName);
                                return retval;
                        }
  
                        Expression member_lookup;
                        member_lookup = MemberLookupFinal (ec, expr_type, expr_type, lookup_id, loc);
 -                      if (member_lookup == null) {
 +                      if (!silent && member_lookup == null) {
                                Report.Error (234, loc, "The type name `{0}' could not be found in type `{1}'", 
                                              Identifier, new_expr.FullName);
                                return null;
                        return true;
                }
  
 -              Expression MakePointerAccess (EmitContext ec)
 +              Expression MakePointerAccess (EmitContext ec, Type t)
                {
 -                      Type t = Expr.Type;
 -
                        if (t == TypeManager.void_ptr_type){
                                Error (242, "The array index operation is not valid for void pointers");
                                return null;
                        
                        if (t.IsArray)
                                return (new ArrayAccess (this, loc)).Resolve (ec);
 -                      else if (t.IsPointer)
 -                              return MakePointerAccess (ec);
 -                      else
 -                              return (new IndexerAccess (this, loc)).Resolve (ec);
 +                      if (t.IsPointer)
 +                              return MakePointerAccess (ec, Expr.Type);
 +
 +                      FieldExpr fe = Expr as FieldExpr;
 +                      if (fe != null) {
 +                              IFixedBuffer ff = AttributeTester.GetFixedBuffer (fe.FieldInfo);
 +                              if (ff != null) {
 +                                      return MakePointerAccess (ec, ff.ElementType);
 +                              }
 +                      }
 +                      return (new IndexerAccess (this, loc)).Resolve (ec);
                }
  
                public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
                        Type t = Expr.Type;
                        if (t.IsArray)
                                return (new ArrayAccess (this, loc)).ResolveLValue (ec, right_side);
 -                      else if (t.IsPointer)
 -                              return MakePointerAccess (ec);
 -                      else
 -                              return (new IndexerAccess (this, loc)).ResolveLValue (ec, right_side);
 +
 +                      if (t.IsPointer)
 +                              return MakePointerAccess (ec, Expr.Type);
 +
 +                      FieldExpr fe = Expr as FieldExpr;
 +                      if (fe != null) {
 +                              IFixedBuffer ff = AttributeTester.GetFixedBuffer (fe.FieldInfo);
 +                              if (ff != null) {
 +// TODO: not sure whether it is correct
 +//                                    if (!ec.InFixedInitializer) {
 +//                                    if (!ec.InFixedInitializer) {
 +//                                            Error (1666, "You cannot use fixed sized buffers contained in unfixed expressions. Try using the fixed statement.");
 +//                                            return null;
 +//                                    }
 +                                      return MakePointerAccess (ec, ff.ElementType);
 +                              }
 +                      }
 +                      return (new IndexerAccess (this, loc)).ResolveLValue (ec, right_side);
                }
                
                public override void Emit (EmitContext ec)
                        loc = l;
                }
  
++              public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
++              {
++                      return DoResolve (ec);
++              }
++
                public override Expression DoResolve (EmitContext ec)
                {
  #if false
                                return null;
                        }
  
 +                      if ((dim.Length > 0) && (dim [0] == '?')) {
 +                              TypeExpr nullable = new NullableType (left, loc);
 +                              if (dim.Length > 1)
 +                                      nullable = new ComposedCast (nullable, dim.Substring (1), loc);
 +                              return nullable.ResolveAsTypeTerminal (ec);
 +                      }
 +
                        int pos = 0;
                        while ((pos < dim.Length) && (dim [pos] == '[')) {
                                pos++;
                                return this;
                        }
  
 -                      //
 -                      // ltype.Fullname is already fully qualified, so we can skip
 -                      // a lot of probes, and go directly to TypeManager.LookupType
 -                      //
 -                      string fname = ltype.FullName != null ? ltype.FullName : ltype.Name;
 -                      string cname = fname + dim;
 -                      type = TypeManager.LookupTypeDirect (cname);
 -                      if (type == null){
 +                      if (dim != "") {
                                //
 -                              // For arrays of enumerations we are having a problem
 -                              // with the direct lookup.  Need to investigate.
 +                              // ltype.Fullname is already fully qualified, so we can skip
 +                              // a lot of probes, and go directly to TypeManager.LookupType
                                //
                                // For now, fall back to the full lookup in that case.
 -                              //
 -                              FullNamedExpression e = ec.DeclSpace.LookupType (cname, false, loc);
 +                              //      
 +                              string fname = ltype.FullName != null ? ltype.FullName : ltype.Name;
 +                              string cname = fname + dim;
 +                              FullNamedExpression e = ec.DeclSpace.LookupType (
 +                                      cname, loc, /*silent=*/ false, /*ignore_cs0104=*/ false);
                                if (e is TypeExpr)
                                        type = ((TypeExpr) e).ResolveType (ec);
                                if (type == null)
                }
        }
  
 -      //
 -      // This class is used to represent the address of an array, used
 -      // only by the Fixed statement, this is like the C "&a [0]" construct.
 -      //
 -      public class ArrayPtr : Expression {
 +      public class FixedBufferPtr: Expression {
                Expression array;
 -              
 -              public ArrayPtr (Expression array, Location l)
 -              {
 -                      Type array_type = TypeManager.GetElementType (array.Type);
  
 +              public FixedBufferPtr (Expression array, Type array_type, Location l)
 +              {
                        this.array = array;
 +                      this.loc = l;
  
                        type = TypeManager.GetPointerType (array_type);
                        eclass = ExprClass.Value;
 -                      loc = l;
                }
  
 -              public override void Emit (EmitContext ec)
 +              public override void Emit(EmitContext ec)
                {
 -                      ILGenerator ig = ec.ig;
 -                      
                        array.Emit (ec);
 -                      IntLiteral.EmitInt (ig, 0);
 -                      ig.Emit (OpCodes.Ldelema, TypeManager.GetElementType (array.Type));
                }
  
                public override Expression DoResolve (EmitContext ec)
                }
        }
  
 +
 +      //
 +      // This class is used to represent the address of an array, used
 +      // only by the Fixed statement, this generates "&a [0]" construct
 +      // for fixed (char *pa = a)
 +      //
 +      public class ArrayPtr : FixedBufferPtr {
 +              Type array_type;
 +              
 +              public ArrayPtr (Expression array, Type array_type, Location l):
 +                      base (array, array_type, l)
 +              {
 +                      this.array_type = array_type;
 +              }
 +
 +              public override void Emit (EmitContext ec)
 +              {
 +                      base.Emit (ec);
 +                      
 +                      ILGenerator ig = ec.ig;
 +                      IntLiteral.EmitInt (ig, 0);
 +                      ig.Emit (OpCodes.Ldelema, array_type);
 +              }
 +      }
 +
        //
        // Used by the fixed statement
        //
diff --combined mcs/gmcs/iterators.cs
index 85cd202458601957feeb19acffd112fa21a28714,85cd202458601957feeb19acffd112fa21a28714..56bb333c94bec63521c23aa16b249520298a98c2
@@@ -804,6 -804,6 +804,11 @@@ namespace Mono.CSharp 
                                this.field = field;
                        }
  
++                      public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
++                      {
++                              return DoResolve (ec);
++                      }
++
                        public override Expression DoResolve (EmitContext ec)
                        {
                                FieldExpr fexpr = new FieldExpr (field.FieldBuilder, loc);
diff --combined mcs/gmcs/literal.cs
index 0a97d502b5046af510de45853feb4e18fba29e99,0a97d502b5046af510de45853feb4e18fba29e99..1d7396536c633b41126120195e4daa076cd97620
@@@ -79,7 -79,7 +79,13 @@@ namespace Mono.CSharp 
                {
                        ec.ig.Emit (OpCodes.Ldnull);
                }
--              
++
++              public override bool IsDefaultValue {
++                      get {
++                              return true;
++                      }
++              }
++
                public override bool IsNegative {
                        get {
                                return false;
diff --combined mcs/gmcs/rootcontext.cs
index dffeaeda752431eefb44d53b2282f3e9887bda9f,2824da00840d2b489a253daa496655bd89113fc5..3e79b457aa602170bd62349baaee892530a75467
@@@ -71,6 -71,6 +71,11 @@@ namespace Mono.CSharp 
  
                public static bool VerifyClsCompliance = true;
  
++              /// <summary>
++              /// Holds /optimize option
++              /// </summary>
++              public static bool Optimize = true;
++
                public static LanguageVersion Version = LanguageVersion.Default;
  
                //
                                // Generic types
                                //
                                "System.Collections.Generic.IEnumerator`1",
 -                              "System.Collections.Generic.IEnumerable`1"
 +                              "System.Collections.Generic.IEnumerable`1",
                        };
  
                        foreach (string iname in interfaces_first_stage)
                        // These are classes that depends on the core interfaces
                        //
                        string [] classes_second_stage = {
 +                              "System.Enum",
 +                              "System.String",
 +                              "System.Array",
                                "System.Reflection.MemberInfo",
                                "System.Type",
                                "System.Exception",
                                "System.Security.CodeAccessPermission"
                        };
  
 -                      // We must store them here before calling BootstrapCorlib_ResolveDelegate.
 -                      TypeManager.string_type = BootstrapCorlib_ResolveClass (root, "System.String");
 -                      TypeManager.enum_type = BootstrapCorlib_ResolveClass (root, "System.Enum");
 -                      TypeManager.array_type = BootstrapCorlib_ResolveClass (root, "System.Array");
 -                      TypeManager.multicast_delegate_type = BootstrapCorlib_ResolveClass (root, "System.MulticastDelegate");
 -                      TypeManager.delegate_type = BootstrapCorlib_ResolveClass (root, "System.Delegate");
 -                      
                        foreach (string cname in classes_second_stage)
                                BootstrapCorlib_ResolveClass (root, cname);
  
 +                      BootstrapCorlib_ResolveStruct (root, "System.Nullable`1");
 +
                        BootstrapCorlib_ResolveDelegate (root, "System.AsyncCallback");
 +
 +                      // These will be defined indirectly during the previous ResolveDelegate.
 +                      // However make sure the rest of the checks happen.
 +                      string [] delegate_types = { "System.Delegate", "System.MulticastDelegate" };
 +                      foreach (string cname in delegate_types)
 +                              BootstrapCorlib_ResolveClass (root, cname);
                }
                        
                // <summary>
                        // If we have a <PrivateImplementationDetails> class, close it
                        //
                        if (helper_classes != null){
 -                              foreach (TypeBuilder type_builder in helper_classes)
 +                              foreach (TypeBuilder type_builder in helper_classes) {
 +#if NET_2_0
 +                                      type_builder.SetCustomAttribute (TypeManager.compiler_generated_attr);
 +#endif
                                        type_builder.CreateType ();
 +                              }
                        }
                        
                        attribute_types = null;
                ///   Used to register classes that need to be closed after all the
                ///   user defined classes
                /// </summary>
 -              public static void RegisterHelperClass (TypeBuilder helper_class)
 +              public static void RegisterCompilerGeneratedType (TypeBuilder helper_class)
                {
                        if (helper_classes == null)
                                helper_classes = new ArrayList ();
 +
                        helper_classes.Add (helper_class);
                }
                
                                          TypeAttributes.NotPublic,
                                          TypeManager.object_type);
                                  
 -                              RegisterHelperClass (impl_details_class);
 +                              RegisterCompilerGeneratedType (impl_details_class);
                        }
  
                        fb = impl_details_class.DefineInitializedData (