Variable,
Namespace,
Type,
+ TypeParameter,
MethodGroup,
PropertyAccess,
EventAccess,
VariableOrValue = 1,
// Returns a type expression.
- Type = 2,
+ Type = 1 << 1,
// Returns a method group.
- MethodGroup = 4,
+ MethodGroup = 1 << 2,
+
+ TypeParameter = 1 << 3,
// Mask of all the expression class flags.
- MaskExprClass = 7,
+ MaskExprClass = VariableOrValue | Type | MethodGroup | TypeParameter,
// Disable control flow analysis while resolving the expression.
// This is used when resolving the instance expression of a field expression.
- DisableFlowAnalysis = 8,
+ DisableFlowAnalysis = 1 << 10,
// Set if this is resolving the first part of a MemberAccess.
- Intermediate = 16,
+ Intermediate = 1 << 11,
// Disable control flow analysis _of struct_ while resolving the expression.
// This is used when resolving the instance expression of a field expression.
- DisableStructFlowAnalysis = 32,
+ DisableStructFlowAnalysis = 1 << 12,
}
//
// An expressions resolved as a direct variable reference
//
- public interface IVariableReference {
- bool IsFixedVariable { get; }
+ public interface IVariableReference : IFixedExpression
+ {
bool IsHoisted { get; }
string Name { get; }
VariableInfo VariableInfo { get; }
void SetHasAddressTaken ();
}
+ //
+ // Implemented by an expression which could be or is always
+ // fixed
+ //
+ public interface IFixedExpression
+ {
+ bool IsFixed { get; }
+ }
+
/// <remarks>
/// Base class for expressions
/// </remarks>
}
}
- ConstructedType ct = te as ConstructedType;
+ GenericTypeExpr ct = te as GenericTypeExpr;
if (ct != null) {
// Skip constrains check for overrides and explicit implementations
// TODO: they should use different overload
return te;
}
-
+
public TypeExpr ResolveAsBaseTerminal (IResolveContext ec, bool silent)
{
int errors = Report.Errors;
if (fne == null)
return null;
-
- if (fne.eclass != ExprClass.Type) {
+
+ TypeExpr te = fne as TypeExpr;
+ if (te == null) {
if (!silent && errors == Report.Errors)
fne.Error_UnexpectedKind (null, "type", loc);
return null;
}
- TypeExpr te = fne as TypeExpr;
-
if (!te.CheckAccessLevel (ec.GenericDeclContainer)) {
Report.SymbolRelatedToPreviousError (te.Type);
ErrorIsInaccesible (loc, TypeManager.CSharpName (te.Type));
}
public virtual void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl)
+ {
+ Error_ValueCannotBeConvertedCore (ec, loc, target, expl);
+ }
+
+ protected void Error_ValueCannotBeConvertedCore (EmitContext ec, Location loc, Type target, bool expl)
{
// The error was already reported as CS1660
if (type == TypeManager.anonymous_method_type)
{
get {
switch (eclass) {
- case ExprClass.Type:
- case ExprClass.Namespace:
- return ResolveFlags.Type;
-
- case ExprClass.MethodGroup:
- return ResolveFlags.MethodGroup;
-
- case ExprClass.Value:
- case ExprClass.Variable:
- case ExprClass.PropertyAccess:
- case ExprClass.EventAccess:
- case ExprClass.IndexerAccess:
- return ResolveFlags.VariableOrValue;
-
- default:
- throw new InternalErrorException (loc.ToString () + " " + GetType () + " ExprClass is Invalid after resolve");
+ case ExprClass.Type:
+ case ExprClass.Namespace:
+ return ResolveFlags.Type;
+
+ case ExprClass.MethodGroup:
+ return ResolveFlags.MethodGroup;
+
+ case ExprClass.TypeParameter:
+ return ResolveFlags.TypeParameter;
+
+ case ExprClass.Value:
+ case ExprClass.Variable:
+ case ExprClass.PropertyAccess:
+ case ExprClass.EventAccess:
+ case ExprClass.IndexerAccess:
+ return ResolveFlags.VariableOrValue;
+
+ default:
+ throw new InternalErrorException (loc.ToString () + " " + GetType () + " ExprClass is Invalid after resolve");
}
}
}
if (c != null)
return c;
- Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ());
+ if (type != null && TypeManager.IsReferenceType (type))
+ Const.Error_ConstantCanBeInitializedWithNullOnly (type, loc, mc.GetSignatureForError ());
+ else
+ Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ());
+
return null;
}
/// Currently ResolveLValue wraps DoResolveLValue to perform sanity
/// checking and assertion checking on what we expect from Resolve
/// </remarks>
- public Expression ResolveLValue (EmitContext ec, Expression right_side, Location loc)
+ public Expression ResolveLValue (EmitContext ec, Expression right_side)
{
int errors = Report.Errors;
bool out_access = right_side == EmptyExpression.OutAccess;
if (e.eclass == ExprClass.Invalid)
throw new Exception ("Expression " + e + " ExprClass is Invalid after resolve");
- if (e.eclass == ExprClass.MethodGroup) {
- ((MethodGroupExpr) e).ReportUsageError ();
- return null;
- }
-
- if ((e.type == null) && !(e is ConstructedType))
+ if ((e.type == null) && !(e is GenericTypeExpr))
throw new Exception ("Expression " + e + " did not set its type after Resolve");
return e;
return null;
}
+ // TODO: [Obsolete ("Can be removed")]
protected static ArrayList almost_matched_members = new ArrayList (4);
//
Expression e;
int errors = Report.Errors;
-
e = MemberLookup (ec.ContainerType, qualifier_type, queried_type, name, mt, bf, loc);
if (e != null || errors != Report.Errors)
Type queried_type, string name, string class_name,
MemberTypes mt, BindingFlags bf)
{
- if (almost_matched_members.Count != 0) {
- for (int i = 0; i < almost_matched_members.Count; ++i) {
- MemberInfo m = (MemberInfo) almost_matched_members [i];
- for (int j = 0; j < i; ++j) {
- if (m == almost_matched_members [j]) {
- m = null;
- break;
- }
- }
- if (m == null)
- continue;
-
- Type declaring_type = m.DeclaringType;
-
- Report.SymbolRelatedToPreviousError (m);
- if (qualifier_type == null) {
- Report.Error (38, loc, "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'",
- TypeManager.CSharpName (m.DeclaringType),
- TypeManager.CSharpName (container_type));
-
- } else if (qualifier_type != container_type &&
- TypeManager.IsNestedFamilyAccessible (container_type, declaring_type)) {
- // Although a derived class can access protected members of
- // its base class it cannot do so through an instance of the
- // base class (CS1540). If the qualifier_type is a base of the
- // ec.ContainerType and the lookup succeeds with the latter one,
- // then we are in this situation.
- Error_CannotAccessProtected (loc, m, qualifier_type, container_type);
- } else {
- ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (m));
- }
- }
- almost_matched_members.Clear ();
- return null;
- }
-
MemberInfo[] lookup = null;
if (queried_type == null) {
class_name = "global::";
name, null);
if (lookup != null) {
- Report.SymbolRelatedToPreviousError (lookup [0]);
- ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (lookup [0]));
- return Error_MemberLookupFailed (lookup);
+ Expression e = Error_MemberLookupFailed (queried_type, lookup);
+
+ //
+ // FIXME: This is still very wrong, it should be done inside
+ // OverloadResolve to do correct arguments matching.
+ // Requires MemberLookup accessiblity check removal
+ //
+ if (e == null || (mt & (MemberTypes.Method | MemberTypes.Constructor)) == 0) {
+ MemberInfo mi = lookup[0];
+ Report.SymbolRelatedToPreviousError (mi);
+ if (qualifier_type != null && container_type != null && qualifier_type != container_type &&
+ TypeManager.IsNestedFamilyAccessible (container_type, mi.DeclaringType)) {
+ // Although a derived class can access protected members of
+ // its base class it cannot do so through an instance of the
+ // base class (CS1540). If the qualifier_type is a base of the
+ // ec.ContainerType and the lookup succeeds with the latter one,
+ // then we are in this situation.
+ Error_CannotAccessProtected (loc, mi, qualifier_type, container_type);
+ } else {
+ ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (mi));
+ }
+ }
+
+ return e;
}
lookup = TypeManager.MemberLookup (queried_type, null, queried_type,
}
}
- return Error_MemberLookupFailed (lookup);
+ return Error_MemberLookupFailed (queried_type, lookup);
}
- protected virtual Expression Error_MemberLookupFailed (MemberInfo[] members)
+ protected virtual Expression Error_MemberLookupFailed (Type type, MemberInfo[] members)
{
for (int i = 0; i < members.Length; ++i) {
if (!(members [i] is MethodBase))
}
// By default propagate the closest candidates upwards
- return new MethodGroupExpr (members, type, loc);
+ return new MethodGroupExpr (members, type, loc, true);
}
protected virtual void Error_NegativeArrayIndex (Location loc)
if (operator_group == null)
return null;
- ArrayList arguments = new ArrayList (1);
- arguments.Add (new Argument (e, Argument.AType.Expression));
+ Arguments arguments = new Arguments (1);
+ arguments.Add (new Argument (e));
operator_group = operator_group.OverloadResolve (
ec, ref arguments, false, loc);
{
get {
switch (eclass){
- case ExprClass.Invalid:
- return "Invalid";
- case ExprClass.Value:
- return "value";
- case ExprClass.Variable:
- return "variable";
- case ExprClass.Namespace:
- return "namespace";
- case ExprClass.Type:
- return "type";
- case ExprClass.MethodGroup:
- return "method group";
- case ExprClass.PropertyAccess:
- return "property access";
- case ExprClass.EventAccess:
- return "event access";
- case ExprClass.IndexerAccess:
- return "indexer access";
- case ExprClass.Nothing:
- return "null";
+ case ExprClass.Invalid:
+ return "Invalid";
+ case ExprClass.Value:
+ return "value";
+ case ExprClass.Variable:
+ return "variable";
+ case ExprClass.Namespace:
+ return "namespace";
+ case ExprClass.Type:
+ return "type";
+ case ExprClass.MethodGroup:
+ return "method group";
+ case ExprClass.PropertyAccess:
+ return "property access";
+ case ExprClass.EventAccess:
+ return "event access";
+ case ExprClass.IndexerAccess:
+ return "indexer access";
+ case ExprClass.Nothing:
+ return "null";
+ case ExprClass.TypeParameter:
+ return "type parameter";
}
throw new Exception ("Should not happen");
}
ig.Emit (OpCodes.Ldind_Ref);
else
LoadFromPtr (ig, TypeManager.GetEnumUnderlyingType (t));
- } else if (t.IsValueType || TypeManager.IsGenericParameter (t))
+ } else if (TypeManager.IsStruct (t) || TypeManager.IsGenericParameter (t))
ig.Emit (OpCodes.Ldobj, t);
else if (t.IsPointer)
ig.Emit (OpCodes.Ldind_I);
ig.Emit (OpCodes.Stind_I1);
else if (type == TypeManager.intptr_type)
ig.Emit (OpCodes.Stind_I);
- else if (type.IsValueType || TypeManager.IsGenericParameter (type))
+ else if (TypeManager.IsStruct (type) || TypeManager.IsGenericParameter (type))
ig.Emit (OpCodes.Stobj, type);
else
ig.Emit (OpCodes.Stind_Ref);
{
Report.SymbolRelatedToPreviousError (type);
if (ec.CurrentInitializerVariable != null) {
- Report.Error (1918, loc, "Members of a value type property `{0}' cannot be assigned with an object initializer",
- GetSignatureForError ());
+ Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
+ TypeManager.CSharpName (type), GetSignatureForError ());
} else {
Report.Error (1612, loc, "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
GetSignatureForError ());
}
}
+ public void Error_ExpressionCannotBeGeneric (Location loc)
+ {
+ Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
+ ExprClassName, GetSignatureForError ());
+ }
+
//
// Converts `source' to an int, uint, long or ulong.
//
//
public abstract Expression CreateExpressionTree (EmitContext ec);
- protected Expression CreateExpressionFactoryCall (string name, ArrayList args)
+ protected Expression CreateExpressionFactoryCall (string name, Arguments args)
{
return CreateExpressionFactoryCall (name, null, args, loc);
}
- protected Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, ArrayList args)
+ protected Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, Arguments args)
{
return CreateExpressionFactoryCall (name, typeArguments, args, loc);
}
- public static Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, ArrayList args, Location loc)
+ public static Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, Arguments args, Location loc)
{
return new Invocation (new MemberAccess (CreateExpressionTypeExpression (loc), name, typeArguments, loc), args);
}
public override Expression CreateExpressionTree (EmitContext ec)
{
- ArrayList args = new ArrayList (2);
+ Arguments args = new Arguments (2);
args.Add (new Argument (child.CreateExpressionTree (ec)));
args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
+ type = storey.MutateType (type);
child.MutateHoistedGenericType (storey);
}
}
}
- /// <summary>
- /// Performs a cast using an operator (op_Explicit or op_Implicit)
- /// </summary>
+ //
+ // Used for predefined class library user casts (no obsolete check, etc.)
+ //
public class OperatorCast : TypeCast {
MethodInfo conversion_operator;
- bool find_explicit;
- public OperatorCast (Expression child, Type target_type) : this (child, target_type, false) {}
+ public OperatorCast (Expression child, Type target_type)
+ : this (child, target_type, false)
+ {
+ }
public OperatorCast (Expression child, Type target_type, bool find_explicit)
: base (child, target_type)
{
- this.find_explicit = find_explicit;
+ conversion_operator = GetConversionOperator (find_explicit);
+ if (conversion_operator == null)
+ throw new InternalErrorException ("Outer conversion routine is out of sync");
}
// Returns the implicit operator that converts from
}
foreach (MethodInfo oper in mi) {
- ParameterData pd = TypeManager.GetParameterData (oper);
+ AParametersCollection pd = TypeManager.GetParameterData (oper);
- if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
+ if (pd.Types [0] == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
return oper;
}
return null;
-
-
}
+
public override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
-
child.Emit (ec);
- conversion_operator = GetConversionOperator (find_explicit);
-
- if (conversion_operator == null)
- throw new InternalErrorException ("Outer conversion routine is out of sync");
-
- ig.Emit (OpCodes.Call, conversion_operator);
+ ec.ig.Emit (OpCodes.Call, conversion_operator);
}
-
}
/// <summary>
/// This is a numeric cast to a Decimal
/// </summary>
- public class CastToDecimal : TypeCast {
- MethodInfo conversion_operator;
-
+ public class CastToDecimal : OperatorCast {
public CastToDecimal (Expression child)
: this (child, false)
{
}
public CastToDecimal (Expression child, bool find_explicit)
- : base (child, TypeManager.decimal_type)
- {
- conversion_operator = GetConversionOperator (find_explicit);
-
- if (conversion_operator == null)
- throw new InternalErrorException ("Outer conversion routine is out of sync");
- }
-
- // Returns the implicit operator that converts from
- // 'child.Type' to System.Decimal.
- MethodInfo GetConversionOperator (bool find_explicit)
- {
- string operator_name = find_explicit ? "op_Explicit" : "op_Implicit";
-
- MemberInfo [] mi = TypeManager.MemberLookup (type, type, type, MemberTypes.Method,
- BindingFlags.Static | BindingFlags.Public, operator_name, null);
-
- foreach (MethodInfo oper in mi) {
- ParameterData pd = TypeManager.GetParameterData (oper);
-
- if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
- return oper;
- }
-
- return null;
- }
- public override void Emit (EmitContext ec)
+ : base (child, TypeManager.decimal_type, find_explicit)
{
- ILGenerator ig = ec.ig;
- child.Emit (ec);
-
- ig.Emit (OpCodes.Call, conversion_operator);
}
}
operators = new System.Collections.Specialized.HybridDictionary ();
foreach (MethodInfo oper in all_oper) {
- ParameterData pd = TypeManager.GetParameterData (oper);
- if (pd.ParameterType (0) == TypeManager.decimal_type)
+ AParametersCollection pd = TypeManager.GetParameterData (oper);
+ if (pd.Types [0] == TypeManager.decimal_type)
operators.Add (TypeManager.TypeToCoreType (oper.ReturnType), oper);
}
}
public override Expression CreateExpressionTree (EmitContext ec)
{
- ArrayList args = new ArrayList (2);
- args.Add (new Argument (child.CreateExpressionTree (ec)));
- args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+ Arguments args = Arguments.CreateForExpressionTree (ec, null,
+ child.CreateExpressionTree (ec),
+ new TypeOf (new TypeExpression (type, loc), loc));
+
if (type.IsPointer)
Error_PointerInsideExpressionTree ();
public override void Emit (EmitContext ec)
{
- child.Emit (ec);
+ child.Emit (ec);
}
public override void EmitBranchable (EmitContext ec, Label label, bool on_true)
{
child.EmitBranchable (ec, label, on_true);
+
+#if GMCS_SOURCE
+ // Only to make verifier happy
+ if (TypeManager.IsGenericParameter (type) && child.IsNull)
+ ec.ig.Emit (OpCodes.Unbox_Any, type);
+#endif
}
public override void EmitSideEffect (EmitContext ec)
return null;
return child.ConvertImplicitly (target_type);
}
+
+ public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+ {
+ child.MutateHoistedGenericType (storey);
+ }
}
return Child.GetValue ();
}
+#if MS_COMPATIBLE
+ // Small workaround for big problem
+ // System.Enum.ToObject cannot be called on dynamic types
+ // EnumBuilder has to be used, but we cannot use EnumBuilder
+ // because it does not properly support generics
+ //
+ // This works only sometimes
+ //
+ if (type.Module == RootContext.ToplevelTypes.Builder)
+ return Child.GetValue ();
+#endif
+
return System.Enum.ToObject (type, Child.GetValue ());
}
public override string AsString ()
{
- return TypeManager.CSharpEnumValue (type, Child.GetValue ());
+ return Child.AsString ();
}
public override Constant Increment()
{
// boxing is side-effectful, since it involves runtime checks, except when boxing to Object or ValueType
// so, we need to emit the box+pop instructions in most cases
- if (child.Type.IsValueType &&
+ if (TypeManager.IsStruct (child.Type) &&
(type == TypeManager.object_type || type == TypeManager.value_type))
child.EmitSideEffect (ec);
else
public override void Emit (EmitContext ec)
{
- Type t = type;
- ILGenerator ig = ec.ig;
-
base.Emit (ec);
-#if GMCS_SOURCE
- if (t.IsGenericParameter || t.IsGenericType && t.IsValueType)
- ig.Emit (OpCodes.Unbox_Any, t);
- else
-#endif
- {
- ig.Emit (OpCodes.Unbox, t);
- LoadFromPtr (ig, t);
- }
+ ILGenerator ig = ec.ig;
+
+#if GMCS_SOURCE
+ ig.Emit (OpCodes.Unbox_Any, type);
+#else
+ ig.Emit (OpCodes.Unbox, type);
+ LoadFromPtr (ig, type);
+#endif
}
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
type = storey.MutateType (type);
+ base.MutateHoistedGenericType (storey);
}
}
/// to the class requested
/// </summary>
public sealed class ClassCast : TypeCast {
- Type child_generic_parameter;
-
+ readonly bool forced;
+
public ClassCast (Expression child, Type return_type)
: base (child, return_type)
-
{
- if (TypeManager.IsGenericParameter (child.Type))
- child_generic_parameter = child.Type;
}
-
- public override Expression DoResolve (EmitContext ec)
+
+ public ClassCast (Expression child, Type return_type, bool forced)
+ : base (child, return_type)
{
- // This should never be invoked, we are born in fully
- // initialized state.
-
- return this;
+ this.forced = forced;
}
public override void Emit (EmitContext ec)
{
base.Emit (ec);
- if (child_generic_parameter != null)
- ec.ig.Emit (OpCodes.Box, child_generic_parameter);
-
#if GMCS_SOURCE
- if (type.IsGenericParameter)
+ bool gen = TypeManager.IsGenericParameter (child.Type);
+ if (gen)
+ ec.ig.Emit (OpCodes.Box, child.Type);
+
+ if (type.IsGenericParameter) {
ec.ig.Emit (OpCodes.Unbox_Any, type);
- else
+ return;
+ }
+
+ if (gen && !forced)
+ return;
#endif
- ec.ig.Emit (OpCodes.Castclass, type);
- }
-
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
- {
- type = storey.MutateType (type);
- if (child_generic_parameter != null)
- child_generic_parameter = storey.MutateGenericArgument (child_generic_parameter);
-
- base.MutateHoistedGenericType (storey);
+
+ ec.ig.Emit (OpCodes.Castclass, type);
}
}
//
public class ReducedExpression : Expression
{
- class ReducedConstantExpression : Constant
+ sealed class ReducedConstantExpression : EmptyConstantCast
{
- readonly Constant expr;
readonly Expression orig_expr;
public ReducedConstantExpression (Constant expr, Expression orig_expr)
- : base (expr.Location)
+ : base (expr, expr.Type)
{
- this.expr = expr;
this.orig_expr = orig_expr;
- eclass = expr.eclass;
- type = expr.Type;
}
- public override string AsString ()
+ public override Constant ConvertImplicitly (Type target_type)
{
- return expr.AsString ();
+ Constant c = base.ConvertImplicitly (target_type);
+ if (c != null)
+ c = new ReducedConstantExpression (c, orig_expr);
+ return c;
}
public override Expression CreateExpressionTree (EmitContext ec)
// Even if resolved result is a constant original expression was not
// and attribute accepts constants only
//
- Attribute.Error_AttributeArgumentNotValid (loc);
+ Attribute.Error_AttributeArgumentNotValid (orig_expr.Location);
value = null;
return false;
}
- public override object GetValue ()
- {
- return expr.GetValue ();
- }
-
public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
{
- throw new NotImplementedException ();
+ Constant c = base.ConvertExplicitly (in_checked_context, target_type);
+ if (c != null)
+ c = new ReducedConstantExpression (c, orig_expr);
+ return c;
}
+ }
- public override Expression DoResolve (EmitContext ec)
+ sealed class ReducedExpressionStatement : ExpressionStatement
+ {
+ readonly Expression orig_expr;
+ readonly ExpressionStatement stm;
+
+ public ReducedExpressionStatement (ExpressionStatement stm, Expression orig)
{
- return this;
+ this.orig_expr = orig;
+ this.stm = stm;
+ this.loc = orig.Location;
}
- public override Constant Increment ()
+ public override Expression CreateExpressionTree (EmitContext ec)
{
- throw new NotImplementedException ();
+ return orig_expr.CreateExpressionTree (ec);
}
- public override bool IsDefaultValue {
- get {
- return expr.IsDefaultValue;
- }
+ public override Expression DoResolve (EmitContext ec)
+ {
+ eclass = stm.eclass;
+ type = stm.Type;
+ return this;
}
- public override bool IsNegative {
- get {
- return expr.IsNegative;
- }
+ public override void Emit (EmitContext ec)
+ {
+ stm.Emit (ec);
}
- public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+ public override void EmitStatement (EmitContext ec)
{
- expr.MutateHoistedGenericType (storey);
+ stm.EmitStatement (ec);
}
- public override void Emit (EmitContext ec)
+ public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
- expr.Emit (ec);
+ stm.MutateHoistedGenericType (storey);
}
}
this.loc = orig_expr.Location;
}
- public static Expression Create (Constant expr, Expression original_expr)
+ public static Constant Create (Constant expr, Expression original_expr)
{
return new ReducedConstantExpression (expr, original_expr);
}
+ public static ExpressionStatement Create (ExpressionStatement s, Expression orig)
+ {
+ return new ReducedExpressionStatement (s, orig);
+ }
+
public static Expression Create (Expression expr, Expression original_expr)
{
Constant c = expr as Constant;
if (c != null)
return Create (c, original_expr);
+ ExpressionStatement s = expr as ExpressionStatement;
+ if (s != null)
+ return Create (s, original_expr);
+
return new ReducedExpression (expr, original_expr);
}
}
}
+ public override bool Equals (object obj)
+ {
+ ATypeNameExpression atne = obj as ATypeNameExpression;
+ return atne != null && atne.Name == Name &&
+ (targs == null || targs.Equals (atne.targs));
+ }
+
+ public override int GetHashCode ()
+ {
+ return Name.GetHashCode ();
+ }
+
public override string GetSignatureForError ()
{
if (targs != null) {
public SimpleName (string name, TypeParameter[] type_params, Location l)
: base (name, l)
{
- targs = new TypeArguments (l);
+ targs = new TypeArguments ();
foreach (TypeParameter type_param in type_params)
targs.Add (new TypeParameterExpr (type_param, l));
}
"A field initializer cannot reference the nonstatic field, method, or property `{0}'",
name);
else
- Report.Error (
- 120, l, "`{0}': An object reference is required for the nonstatic field, method or property",
+ Report.Error (120, l,
+ "An object reference is required to access non-static member `{0}'",
name);
}
for (; (ds != null) && ds.IsGeneric; ds = ds.Parent) {
if (arg_count + ds.CountTypeParameters == gen_params.Length) {
- TypeArguments new_args = new TypeArguments (loc);
+ TypeArguments new_args = new TypeArguments ();
foreach (TypeParameter param in ds.TypeParameters)
new_args.Add (new TypeParameterExpr (param, loc));
if (targs != null)
new_args.Add (targs);
- return new ConstructedType (t, new_args, loc);
+ return new GenericTypeExpr (t, new_args, loc);
}
}
return nested.ResolveAsTypeStep (ec, false);
if (targs != null) {
- ConstructedType ct = new ConstructedType (fne, targs, loc);
+ GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
return ct.ResolveAsTypeStep (ec, false);
}
string ns = ec.DeclContainer.NamespaceEntry.NS.Name;
string fullname = (ns.Length > 0) ? ns + "." + Name : Name;
- foreach (Assembly a in RootNamespace.Global.Assemblies) {
+ foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) {
Type type = a.GetType (fullname);
if (type != null) {
Report.SymbolRelatedToPreviousError (type);
if (targs != null) {
FullNamedExpression retval = ec.DeclContainer.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
if (retval != null) {
- Namespace.Error_TypeArgumentsCannotBeUsed (retval.Type, loc);
+ Namespace.Error_TypeArgumentsCannotBeUsed (retval, loc);
return;
}
}
if (current_block != null){
LocalInfo vi = current_block.GetLocalInfo (Name);
if (vi != null){
- if (targs != null) {
- Report.Error (307, loc,
- "The variable `{0}' cannot be used with type arguments",
- Name);
- return null;
- }
-
LocalVariableReference var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
if (right_side != null) {
- return var.ResolveLValue (ec, right_side, loc);
+ return var.ResolveLValue (ec, right_side);
} else {
ResolveFlags rf = ResolveFlags.VariableOrValue;
if (intermediate)
}
}
- ParameterReference pref = current_block.Toplevel.GetParameterReference (Name, loc);
- if (pref != null) {
- if (targs != null) {
- Report.Error (307, loc,
- "The variable `{0}' cannot be used with type arguments",
- Name);
- return null;
- }
-
- if (right_side != null)
- return pref.ResolveLValue (ec, right_side, loc);
- else
- return pref.Resolve (ec);
- }
-
- Expression expr = current_block.Toplevel.GetTransparentIdentifier (Name);
+ Expression expr = current_block.Toplevel.GetParameterReference (Name, loc);
if (expr != null) {
if (right_side != null)
- return expr.ResolveLValue (ec, right_side, loc);
+ return expr.ResolveLValue (ec, right_side);
+
return expr.Resolve (ec);
}
}
e = MemberLookup (ec.ContainerType, lookup_ds.TypeBuilder, Name, loc);
if (e != null) {
- if (e is PropertyExpr) {
+ PropertyExpr pe = e as PropertyExpr;
+ if (pe != null) {
+ AParametersCollection param = TypeManager.GetParameterData (pe.PropertyInfo);
+
// since TypeManager.MemberLookup doesn't know if we're doing a lvalue access or not,
// it doesn't know which accessor to check permissions against
- if (((PropertyExpr) e).IsAccessibleFrom (ec.ContainerType, right_side != null))
+ if (param.IsEmpty && pe.IsAccessibleFrom (ec.ContainerType, right_side != null))
break;
} else if (e is EventExpr) {
if (((EventExpr) e).IsAccessibleFrom (ec.ContainerType))
break;
+ } else if (targs != null && e is TypeExpression) {
+ e = new GenericTypeExpr (e.Type, targs, loc).ResolveAsTypeStep (ec, false);
+ break;
} else {
break;
}
}
}
+ if (RootContext.EvalMode){
+ FieldInfo fi = Evaluator.LookupField (Name);
+ if (fi != null)
+ return new FieldExpr (fi, loc).Resolve (ec);
+ }
+
if (almost_matched != null)
almost_matched_members = almost_matched;
if (almost_matched_type == null)
almost_matched_type = ec.ContainerType;
- Error_MemberLookupFailed (ec.ContainerType, null, almost_matched_type, Name,
+ return Error_MemberLookupFailed (ec.ContainerType, null, almost_matched_type, Name,
ec.DeclContainer.Name, AllMemberTypes, AllBindingFlags);
- return null;
- }
-
- if (e is TypeExpr) {
- if (targs == null)
- return e;
-
- ConstructedType ct = new ConstructedType (
- e.Type, targs, loc);
- return ct.ResolveAsTypeStep (ec, false);
}
if (e is MemberExpr) {
return null;
if (targs != null) {
- targs.Resolve (ec);
+ if (!targs.Resolve (ec))
+ return null;
+
me.SetTypeArguments (targs);
}
- if (!me.IsStatic && (me.InstanceExpression != null) &&
+ if (!me.IsStatic && (me.InstanceExpression != null && me.InstanceExpression != EmptyExpression.Null) &&
TypeManager.IsNestedFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
me.InstanceExpression.Type != me.DeclaringType &&
!TypeManager.IsFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
return e;
}
-
- protected override void CloneTo (CloneContext clonectx, Expression target)
- {
- // CloneTo: Nothing, we do not keep any state on this expression
- }
}
/// <summary>
/// Represents a namespace or a type. The name of the class was inspired by
/// section 10.8.1 (Fully Qualified Names).
/// </summary>
- public abstract class FullNamedExpression : Expression {
+ public abstract class FullNamedExpression : Expression
+ {
+ protected override void CloneTo (CloneContext clonectx, Expression target)
+ {
+ // Do nothing, most unresolved type expressions cannot be
+ // resolved to different type
+ }
public override Expression CreateExpressionTree (EmitContext ec)
{
/// Expression that evaluates to a type
/// </summary>
public abstract class TypeExpr : FullNamedExpression {
- override public FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
+ public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
{
TypeExpr t = DoResolveAsTypeStep (ec);
if (t == null)
return ds.CheckAccessLevel (Type);
}
- public virtual bool AsAccessible (DeclSpace ds)
- {
- return ds.IsAccessibleAs (Type);
- }
-
public virtual bool IsClass {
get { return Type.IsClass; }
}
public virtual bool IsValueType {
- get { return Type.IsValueType; }
+ get { return TypeManager.IsStruct (Type); }
}
public virtual bool IsInterface {
}
}
- /// <summary>
- /// Used to create types from a fully qualified name. These are just used
- /// by the parser to setup the core types. A TypeLookupExpression is always
- /// classified as a type.
- /// </summary>
+ //
+ // Used to create types from a fully qualified name. These are just used
+ // by the parser to setup the core types.
+ //
public sealed class TypeLookupExpression : TypeExpr {
+ readonly string ns_name;
readonly string name;
- public TypeLookupExpression (string name)
+ public TypeLookupExpression (string ns, string name)
{
this.name = name;
+ this.ns_name = ns;
eclass = ExprClass.Type;
}
public override TypeExpr ResolveAsTypeTerminal (IResolveContext ec, bool silent)
{
- // It's null for corlib compilation only
- if (type == null)
- return DoResolveAsTypeStep (ec);
+ //
+ // It's null only during mscorlib bootstrap when DefineType
+ // nees to resolve base type of same type
+ //
+ // For instance struct Char : IComparable<char>
+ //
+ // TODO: it could be removed when Resolve starts to use
+ // DeclSpace instead of Type
+ //
+ if (type == null) {
+ Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, false);
+ FullNamedExpression fne = ns.Lookup (null, name, loc);
+ if (fne != null)
+ type = fne.Type;
+ }
return this;
}
- private class UnexpectedType
- {
- }
-
- // This performes recursive type lookup, providing support for generic types.
- // For example, given the type:
- //
- // System.Collections.Generic.KeyValuePair`2[[System.Int32],[System.String]]
- //
- // The types will be checked in the following order:
- // _
- // System |
- // System.Collections |
- // System.Collections.Generic |
- // _ |
- // System | recursive call 1 |
- // System.Int32 _| | main method call
- // _ |
- // System | recursive call 2 |
- // System.String _| |
- // |
- // System.Collections.Generic.KeyValuePair`2[[System.Int32],[System.String]] _|
- //
- private Type TypeLookup (IResolveContext ec, string name)
- {
- int index = 0;
- int dot = 0;
- bool done = false;
- FullNamedExpression resolved = null;
- Type type = null;
- Type recursive_type = null;
- while (index < name.Length) {
- if (name[index] == '[') {
- int open = index;
- int braces = 1;
- do {
- index++;
- if (name[index] == '[')
- braces++;
- else if (name[index] == ']')
- braces--;
- } while (braces > 0);
- recursive_type = TypeLookup (ec, name.Substring (open + 1, index - open - 1));
- if (recursive_type == null || (recursive_type == typeof(UnexpectedType)))
- return recursive_type;
- }
- else {
- if (name[index] == ',')
- done = true;
- else if ((name[index] == '.' && !done) || (index == name.Length && name[0] != '[')) {
- string substring = name.Substring(dot, index - dot);
-
- if (resolved == null)
- resolved = RootNamespace.Global.Lookup (ec.DeclContainer, substring, Location.Null);
- else if (resolved is Namespace)
- resolved = (resolved as Namespace).Lookup (ec.DeclContainer, substring, Location.Null);
- else if (type != null)
- type = TypeManager.GetNestedType (type, substring);
- else
- return null;
-
- if (resolved == null)
- return null;
- else if (type == null && resolved is TypeExpr)
- type = resolved.Type;
-
- dot = index + 1;
- }
- }
- index++;
- }
- if (name[0] != '[') {
- string substring = name.Substring(dot, index - dot);
-
- if (type != null)
- return TypeManager.GetNestedType (type, substring);
-
- if (resolved != null) {
- resolved = (resolved as Namespace).Lookup (ec.DeclContainer, substring, Location.Null);
- if (resolved is TypeExpr)
- return resolved.Type;
-
- if (resolved == null)
- return null;
-
- resolved.Error_UnexpectedKind (ec.DeclContainer, "type", loc);
- return typeof (UnexpectedType);
- }
- else
- return null;
- }
- else
- return recursive_type;
- }
-
protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
{
- Type t = TypeLookup (ec, name);
- if (t == null) {
- NamespaceEntry.Error_NamespaceNotFound (loc, name);
- return null;
- }
- if (t == typeof(UnexpectedType))
- return null;
- type = t;
return this;
}
- protected override void CloneTo (CloneContext clonectx, Expression target)
- {
- // CloneTo: Nothing, we do not keep any state on this expression
- }
-
public override string GetSignatureForError ()
{
if (type == null)
- return TypeManager.CSharpName (name);
+ return TypeManager.CSharpName (ns_name + "." + name, null);
return base.GetSignatureForError ();
}
}
- /// <summary>
- /// Represents an "unbound generic type", ie. typeof (Foo<>).
- /// See 14.5.11.
- /// </summary>
- public class UnboundTypeExpression : TypeExpr
- {
- MemberName name;
-
- public UnboundTypeExpression (MemberName name, Location l)
- {
- this.name = name;
- loc = l;
- }
-
- protected override void CloneTo (CloneContext clonectx, Expression target)
- {
- // Nothing to clone
- }
-
- protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
- {
- Expression expr;
- if (name.Left != null) {
- Expression lexpr = name.Left.GetTypeExpression ();
- expr = new MemberAccess (lexpr, name.Basename);
- } else {
- expr = new SimpleName (name.Basename, loc);
- }
-
- FullNamedExpression fne = expr.ResolveAsTypeStep (ec, false);
- if (fne == null)
- return null;
-
- type = fne.Type;
- return new TypeExpression (type, loc);
- }
- }
-
/// <summary>
/// This class denotes an expression which evaluates to a member
/// of a struct or a class.
//
if (left is TypeExpr) {
- left = left.ResolveAsTypeTerminal (ec, true);
+ left = left.ResolveAsBaseTerminal (ec, false);
if (left == null)
return null;
+ // TODO: Same problem as in class.cs, TypeTerminal does not
+ // always do all necessary checks
+ ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (left.Type);
+ if (oa != null && !ec.IsInObsoleteScope) {
+ AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc);
+ }
+
+ GenericTypeExpr ct = left as GenericTypeExpr;
+ if (ct != null && !ct.CheckConstraints (ec))
+ return null;
+ //
+
if (!IsStatic) {
SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
return null;
SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
return;
}
-
- if (InstanceExpression.Type.IsValueType) {
+
+ if (TypeManager.IsValueType (InstanceExpression.Type)) {
if (InstanceExpression is IMemoryLocation) {
((IMemoryLocation) InstanceExpression).AddressOf (ec, AddressOp.LoadStore);
} else {
get { return namespace_entry == null; }
}
- public override void EmitArguments (EmitContext ec, ArrayList arguments)
- {
- if (arguments == null)
- arguments = new ArrayList (1);
- arguments.Insert (0, extension_argument);
- base.EmitArguments (ec, arguments);
- }
-
- public override void EmitCall (EmitContext ec, ArrayList arguments)
+ public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
- if (arguments == null)
- arguments = new ArrayList (1);
- arguments.Insert (0, extension_argument);
- base.EmitCall (ec, arguments);
+ extension_argument.Expr.MutateHoistedGenericType (storey);
+ base.MutateHoistedGenericType (storey);
}
- public override MethodGroupExpr OverloadResolve (EmitContext ec, ref ArrayList arguments, bool may_fail, Location loc)
+ public override MethodGroupExpr OverloadResolve (EmitContext ec, ref Arguments arguments, bool may_fail, Location loc)
{
if (arguments == null)
- arguments = new ArrayList (1);
+ arguments = new Arguments (1);
arguments.Insert (0, new Argument (ExtensionExpression));
- MethodGroupExpr mg = ResolveOverloadExtensions (ec, arguments, namespace_entry, loc);
+ MethodGroupExpr mg = ResolveOverloadExtensions (ec, ref arguments, namespace_entry, loc);
// Store resolved argument and restore original arguments
if (mg != null)
- ((ExtensionMethodGroupExpr)mg).extension_argument = (Argument)arguments [0];
- arguments.RemoveAt (0);
+ ((ExtensionMethodGroupExpr)mg).extension_argument = arguments [0];
+ else
+ arguments.RemoveAt (0); // Clean-up modified arguments for error reporting
return mg;
}
- MethodGroupExpr ResolveOverloadExtensions (EmitContext ec, ArrayList arguments, NamespaceEntry ns, Location loc)
+ MethodGroupExpr ResolveOverloadExtensions (EmitContext ec, ref Arguments arguments, NamespaceEntry ns, Location loc)
{
// Use normal resolve rules
MethodGroupExpr mg = base.OverloadResolve (ec, ref arguments, ns != null, loc);
e.ExtensionExpression = ExtensionExpression;
e.SetTypeArguments (type_arguments);
- return e.ResolveOverloadExtensions (ec, arguments, e.namespace_entry, loc);
+ return e.ResolveOverloadExtensions (ec, ref arguments, e.namespace_entry, loc);
}
}
{
public interface IErrorHandler
{
+ bool AmbiguousCall (MethodBase ambiguous);
bool NoExactMatch (EmitContext ec, MethodBase method);
}
// TODO: make private
public TypeArguments type_arguments;
bool identical_type_name;
+ bool has_inaccessible_candidates_only;
Type delegate_type;
+ Type queried_type;
public MethodGroupExpr (MemberInfo [] mi, Type type, Location l)
: this (type, l)
mi.CopyTo (Methods, 0);
}
+ public MethodGroupExpr (MemberInfo[] mi, Type type, Location l, bool inacessibleCandidatesOnly)
+ : this (mi, type, l)
+ {
+ has_inaccessible_candidates_only = inacessibleCandidatesOnly;
+ }
+
public MethodGroupExpr (ArrayList list, Type type, Location l)
: this (type, l)
{
{
this.loc = loc;
eclass = ExprClass.MethodGroup;
- this.type = type;
+ this.type = typeof (MethodGroupExpr);
+ queried_type = type;
}
public override Type DeclaringType {
get {
- //
- // We assume that the top-level type is in the end
- //
- return Methods [Methods.Length - 1].DeclaringType;
- //return Methods [0].DeclaringType;
+ return queried_type;
}
}
get {
return identical_type_name;
}
-
- set {
- identical_type_name = value;
- }
}
public override string GetSignatureForError ()
/// false if candidate ain't better
/// true if candidate is better than the current best match
/// </remarks>
- static bool BetterFunction (EmitContext ec, ArrayList args, int argument_count,
+ static bool BetterFunction (EmitContext ec, Arguments args, int argument_count,
MethodBase candidate, bool candidate_params,
MethodBase best, bool best_params)
{
- ParameterData candidate_pd = TypeManager.GetParameterData (candidate);
- ParameterData best_pd = TypeManager.GetParameterData (best);
+ AParametersCollection candidate_pd = TypeManager.GetParameterData (candidate);
+ AParametersCollection best_pd = TypeManager.GetParameterData (best);
bool better_at_least_one = false;
bool same = true;
for (int j = 0, c_idx = 0, b_idx = 0; j < argument_count; ++j, ++c_idx, ++b_idx)
{
- Argument a = (Argument) args [j];
+ Argument a = args [j];
+
+ // Provided default argument value is never better
+ if (a.IsDefaultArgument && candidate_params == best_params)
+ return false;
- Type ct = TypeManager.TypeToCoreType (candidate_pd.ParameterType (c_idx));
- Type bt = TypeManager.TypeToCoreType (best_pd.ParameterType (b_idx));
+ Type ct = candidate_pd.Types [c_idx];
+ Type bt = best_pd.Types [b_idx];
- if (candidate_params && candidate_pd.ParameterModifier (c_idx) == Parameter.Modifier.PARAMS)
+ if (candidate_params && candidate_pd.FixedParameters [c_idx].ModFlags == Parameter.Modifier.PARAMS)
{
ct = TypeManager.GetElementType (ct);
--c_idx;
}
- if (best_params && best_pd.ParameterModifier (b_idx) == Parameter.Modifier.PARAMS)
+ if (best_params && best_pd.FixedParameters [b_idx].ModFlags == Parameter.Modifier.PARAMS)
{
bt = TypeManager.GetElementType (bt);
--b_idx;
//
// The two methods have equal parameter types. Now apply tie-breaking rules
//
- if (TypeManager.IsGenericMethod (best) && !TypeManager.IsGenericMethod (candidate))
- return true;
- if (!TypeManager.IsGenericMethod (best) && TypeManager.IsGenericMethod (candidate))
+ if (TypeManager.IsGenericMethod (best)) {
+ if (!TypeManager.IsGenericMethod (candidate))
+ return true;
+ } else if (TypeManager.IsGenericMethod (candidate)) {
return false;
+ }
//
// This handles the following cases:
if (candidate_param_count != best_param_count)
// can only happen if (candidate_params && best_params)
- return candidate_param_count > best_param_count;
+ return candidate_param_count > best_param_count && best_pd.HasParams;
//
// now, both methods have the same number of parameters, and the parameters have the same types
MethodBase orig_candidate = TypeManager.DropGenericMethodArguments (candidate);
MethodBase orig_best = TypeManager.DropGenericMethodArguments (best);
- ParameterData orig_candidate_pd = TypeManager.GetParameterData (orig_candidate);
- ParameterData orig_best_pd = TypeManager.GetParameterData (orig_best);
+ AParametersCollection orig_candidate_pd = TypeManager.GetParameterData (orig_candidate);
+ AParametersCollection orig_best_pd = TypeManager.GetParameterData (orig_best);
bool specific_at_least_once = false;
for (int j = 0; j < candidate_param_count; ++j)
{
- Type ct = TypeManager.TypeToCoreType (orig_candidate_pd.ParameterType (j));
- Type bt = TypeManager.TypeToCoreType (orig_best_pd.ParameterType (j));
+ Type ct = orig_candidate_pd.Types [j];
+ Type bt = orig_best_pd.Types [j];
if (ct.Equals (bt))
continue;
Type specific = MoreSpecific (ct, bt);
{
if (!(left is TypeExpr) &&
original != null && original.IdenticalNameAndTypeName (ec, left, loc))
- IdenticalTypeName = true;
+ identical_type_name = true;
return base.ResolveMemberAccess (ec, left, loc, original);
}
ReportUsageError ();
}
- public virtual void EmitArguments (EmitContext ec, ArrayList arguments)
+ public void EmitCall (EmitContext ec, Arguments arguments)
{
- Invocation.EmitArguments (ec, arguments, false, null);
+ Invocation.EmitCall (ec, IsBase, InstanceExpression, best_candidate, arguments, loc);
}
-
- public virtual void EmitCall (EmitContext ec, ArrayList arguments)
+
+ void Error_AmbiguousCall (MethodBase ambiguous)
{
- Invocation.EmitCall (ec, IsBase, InstanceExpression, best_candidate, arguments, loc);
+ if (CustomErrorHandler != null && CustomErrorHandler.AmbiguousCall (ambiguous))
+ return;
+
+ Report.SymbolRelatedToPreviousError (best_candidate);
+ Report.Error (121, loc, "The call is ambiguous between the following methods or properties: `{0}' and `{1}'",
+ TypeManager.CSharpSignature (ambiguous), TypeManager.CSharpSignature (best_candidate));
}
protected virtual void Error_InvalidArguments (EmitContext ec, Location loc, int idx, MethodBase method,
- Argument a, ParameterData expected_par, Type paramType)
+ Argument a, AParametersCollection expected_par, Type paramType)
{
ExtensionMethodGroupExpr emg = this as ExtensionMethodGroupExpr;
if (a is CollectionElementInitializer.ElementInitializerArgument) {
Report.SymbolRelatedToPreviousError (method);
- if ((expected_par.ParameterModifier (idx) & Parameter.Modifier.ISBYREF) != 0) {
+ if ((expected_par.FixedParameters [idx].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
TypeManager.CSharpSignature (method));
return;
}
Report.Error (1950, loc, "The best overloaded collection initalizer method `{0}' has some invalid arguments",
TypeManager.CSharpSignature (method));
- } else if (delegate_type == null) {
+ } else if (TypeManager.IsDelegateType (method.DeclaringType)) {
+ Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
+ TypeManager.CSharpName (method.DeclaringType));
+ } else {
Report.SymbolRelatedToPreviousError (method);
if (emg != null) {
Report.Error (1928, loc,
Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
TypeManager.CSharpSignature (method));
}
- } else
- Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
- TypeManager.CSharpName (delegate_type));
+ }
- Parameter.Modifier mod = expected_par.ParameterModifier (idx);
+ Parameter.Modifier mod = idx >= expected_par.Count ? 0 : expected_par.FixedParameters [idx].ModFlags;
string index = (idx + 1).ToString ();
if (((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) ^
Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
Name, TypeManager.CSharpName (target));
}
+
+ void Error_ArgumentCountWrong (int arg_count)
+ {
+ Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
+ Name, arg_count.ToString ());
+ }
- protected virtual int GetApplicableParametersCount (MethodBase method, ParameterData parameters)
+ protected virtual int GetApplicableParametersCount (MethodBase method, AParametersCollection parameters)
{
return parameters.Count;
}
/// 0 = the best, int.MaxValue = the worst
///
public int IsApplicable (EmitContext ec,
- ArrayList arguments, int arg_count, ref MethodBase method, ref bool params_expanded_form)
+ ref Arguments arguments, int arg_count, ref MethodBase method, ref bool params_expanded_form)
{
MethodBase candidate = method;
- ParameterData pd = TypeManager.GetParameterData (candidate);
+ AParametersCollection pd = TypeManager.GetParameterData (candidate);
int param_count = GetApplicableParametersCount (candidate, pd);
+ int optional_count = 0;
if (arg_count != param_count) {
- if (!pd.HasParams)
- return int.MaxValue - 10000 + Math.Abs (arg_count - param_count);
- if (arg_count < param_count - 1)
- return int.MaxValue - 10000 + Math.Abs (arg_count - param_count);
+ for (int i = 0; i < pd.Count; ++i) {
+ if (pd.FixedParameters [i].HasDefaultValue) {
+ optional_count = pd.Count - i;
+ break;
+ }
+ }
+
+ int args_gap = Math.Abs (arg_count - param_count);
+ if (optional_count != 0) {
+ if (args_gap > optional_count)
+ return int.MaxValue - 10000 + args_gap - optional_count;
+
+ // Readjust expected number when params used
+ if (pd.HasParams) {
+ optional_count--;
+ if (arg_count < param_count)
+ param_count--;
+ }
+ } else if (arg_count != param_count) {
+ if (!pd.HasParams)
+ return int.MaxValue - 10000 + args_gap;
+ if (arg_count < param_count - 1)
+ return int.MaxValue - 10000 + args_gap;
+ }
+
+ // Initialize expanded form of a method with 1 params parameter
+ params_expanded_form = param_count == 1 && pd.HasParams;
+
+ // Resize to fit optional arguments
+ if (optional_count != 0) {
+ Arguments resized;
+ if (arguments == null) {
+ resized = new Arguments (optional_count);
+ } else {
+ resized = new Arguments (param_count);
+ resized.AddRange (arguments);
+ }
+
+ for (int i = arg_count; i < param_count; ++i)
+ resized.Add (null);
+ arguments = resized;
+ }
+ }
+
+ if (arg_count > 0) {
+ //
+ // Shuffle named arguments to the right positions if there are any
+ //
+ if (arguments [arg_count - 1] is NamedArgument) {
+ arg_count = arguments.Count;
+
+ for (int i = 0; i < arg_count; ++i) {
+ bool arg_moved = false;
+ while (true) {
+ NamedArgument na = arguments[i] as NamedArgument;
+ if (na == null)
+ break;
+
+ int index = pd.GetParameterIndexByName (na.Name.Value);
+
+ // Named parameter not found or already reordered
+ if (index <= i)
+ break;
+
+ // When using parameters which should not be available to the user
+ if (index >= param_count)
+ break;
+
+ if (!arg_moved) {
+ arguments.MarkReorderedArgument (na);
+ arg_moved = true;
+ }
+
+ Argument temp = arguments[index];
+ arguments[index] = arguments[i];
+ arguments[i] = temp;
+
+ if (temp == null)
+ break;
+ }
+ }
+ } else {
+ arg_count = arguments.Count;
+ }
+ } else if (arguments != null) {
+ arg_count = arguments.Count;
}
#if GMCS_SOURCE
if (type_arguments != null)
return int.MaxValue - 15000;
}
-#endif
+#endif
//
// 2. Each argument has to be implicitly convertible to method parameter
Parameter.Modifier p_mod = 0;
Type pt = null;
for (int i = 0; i < arg_count; i++) {
- Argument a = (Argument) arguments [i];
- Parameter.Modifier a_mod = a.Modifier &
- ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
-
- if (p_mod != Parameter.Modifier.PARAMS) {
- p_mod = pd.ParameterModifier (i) & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
+ Argument a = arguments [i];
+ if (a == null) {
+ if (!pd.FixedParameters [i].HasDefaultValue)
+ throw new InternalErrorException ();
- if (p_mod == Parameter.Modifier.ARGLIST) {
- if (a.Type == TypeManager.runtime_argument_handle_type)
- continue;
+ Expression e = pd.FixedParameters [i].DefaultValue as Constant;
+ if (e == null)
+ e = new DefaultValueExpression (new TypeExpression (pd.Types [i], loc), loc).Resolve (ec);
- p_mod = 0;
- }
+ arguments [i] = new Argument (e, Argument.AType.Default);
+ continue;
+ }
- pt = pd.ParameterType (i);
+ if (p_mod != Parameter.Modifier.PARAMS) {
+ p_mod = pd.FixedParameters [i].ModFlags & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
+ pt = pd.Types [i];
} else {
params_expanded_form = true;
}
+ Parameter.Modifier a_mod = a.Modifier & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
int score = 1;
if (!params_expanded_form)
score = IsArgumentCompatible (ec, a_mod, a, p_mod & ~Parameter.Modifier.PARAMS, pt);
- if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0) {
+ if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0 && delegate_type == null) {
// It can be applicable in expanded form
- score = IsArgumentCompatible (ec, a_mod, a, 0, pt.GetElementType ());
+ score = IsArgumentCompatible (ec, a_mod, a, 0, TypeManager.GetElementType (pt));
if (score == 0)
params_expanded_form = true;
}
}
if (arg_count != param_count)
- params_expanded_form = true;
+ params_expanded_form = true;
return 0;
}
//
if (arg_mod != 0 || param_mod != 0) {
if (TypeManager.HasElementType (parameter))
- parameter = parameter.GetElementType ();
+ parameter = TypeManager.GetElementType (parameter);
Type a_type = argument.Type;
if (TypeManager.HasElementType (a_type))
- a_type = a_type.GetElementType ();
+ a_type = TypeManager.GetElementType (a_type);
if (a_type != parameter)
return 2;
} else {
- if (delegate_type != null ?
- !Delegate.IsTypeCovariant (argument.Expr, parameter) :
- !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
+ if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
return 2;
}
if (!IsAncestralType (base_method.DeclaringType, cand_method.DeclaringType))
return false;
- ParameterData cand_pd = TypeManager.GetParameterData (cand_method);
- ParameterData base_pd = TypeManager.GetParameterData (base_method);
+ AParametersCollection cand_pd = TypeManager.GetParameterData (cand_method);
+ AParametersCollection base_pd = TypeManager.GetParameterData (base_method);
if (cand_pd.Count != base_pd.Count)
return false;
for (int j = 0; j < cand_pd.Count; ++j)
{
- Parameter.Modifier cm = cand_pd.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));
+ Parameter.Modifier cm = cand_pd.FixedParameters [j].ModFlags;
+ Parameter.Modifier bm = base_pd.FixedParameters [j].ModFlags;
+ Type ct = cand_pd.Types [j];
+ Type bt = base_pd.Types [j];
if (cm != bm || ct != bt)
return false;
/// that is the best match of me on Arguments.
///
/// </summary>
- public virtual MethodGroupExpr OverloadResolve (EmitContext ec, ref ArrayList Arguments,
+ public virtual MethodGroupExpr OverloadResolve (EmitContext ec, ref Arguments Arguments,
bool may_fail, Location loc)
{
bool method_params = false;
Type applicable_type = null;
- int arg_count = 0;
ArrayList candidates = new ArrayList (2);
ArrayList candidate_overrides = null;
// false is normal form, true is expanded form
//
Hashtable candidate_to_form = null;
+ Hashtable candidates_expanded = null;
+ Arguments candidate_args = Arguments;
- if (Arguments != null)
- arg_count = Arguments.Count;
+ int arg_count = Arguments != null ? Arguments.Count : 0;
if (RootContext.Version == LanguageVersion.ISO_1 && Name == "Invoke" && TypeManager.IsDelegateType (DeclaringType)) {
if (!may_fail)
// Check if candidate is applicable (section 14.4.2.1)
//
bool params_expanded_form = false;
- int candidate_rate = IsApplicable (ec, Arguments, arg_count, ref Methods [i], ref params_expanded_form);
+ int candidate_rate = IsApplicable (ec, ref candidate_args, arg_count, ref Methods [i], ref params_expanded_form);
if (candidate_rate < best_candidate_rate) {
best_candidate_rate = candidate_rate;
MethodBase candidate = Methods [i];
candidate_to_form [candidate] = candidate;
}
+
+ if (candidate_args != Arguments) {
+ if (candidates_expanded == null)
+ candidates_expanded = new Hashtable (2);
- if (candidate_rate != 0) {
+ candidates_expanded.Add (Methods [i], candidate_args);
+ candidate_args = Arguments;
+ }
+
+ if (candidate_rate != 0 || has_inaccessible_candidates_only) {
if (msg_recorder != null)
msg_recorder.EndSession ();
continue;
// return error info about the closest match
//
if (best_candidate != null) {
- if (CustomErrorHandler != null) {
- if (CustomErrorHandler.NoExactMatch (ec, best_candidate))
- return null;
- }
+ if (CustomErrorHandler != null && !has_inaccessible_candidates_only && CustomErrorHandler.NoExactMatch (ec, best_candidate))
+ return null;
- ParameterData pd = TypeManager.GetParameterData (best_candidate);
+ AParametersCollection pd = TypeManager.GetParameterData (best_candidate);
bool cand_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
if (arg_count == pd.Count || pd.HasParams) {
if (TypeManager.IsGenericMethodDefinition (best_candidate)) {
TypeManager.CSharpSignature (best_candidate));
return null;
}
-
- Type [] g_args = TypeManager.GetGenericArguments (best_candidate);
+
+ Type[] g_args = TypeManager.GetGenericArguments (best_candidate);
if (type_arguments.Count != g_args.Length) {
Report.SymbolRelatedToPreviousError (best_candidate);
Report.Error (305, loc, "Using the generic method `{0}' requires `{1}' type argument(s)",
return null;
}
}
-
+
+ if (has_inaccessible_candidates_only) {
+ if (InstanceExpression != null && type != ec.ContainerType && TypeManager.IsNestedFamilyAccessible (ec.ContainerType, best_candidate.DeclaringType)) {
+ // Although a derived class can access protected members of
+ // its base class it cannot do so through an instance of the
+ // base class (CS1540). If the qualifier_type is a base of the
+ // ec.ContainerType and the lookup succeeds with the latter one,
+ // then we are in this situation.
+ Error_CannotAccessProtected (loc, best_candidate, queried_type, ec.ContainerType);
+ } else {
+ Report.SymbolRelatedToPreviousError (best_candidate);
+ ErrorIsInaccesible (loc, GetSignatureForError ());
+ }
+ }
+
if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, may_fail, loc))
return null;
+
+ if (has_inaccessible_candidates_only)
+ return null;
+
+ throw new InternalErrorException ("VerifyArgumentsCompat didn't find any problem with rejected candidate " + best_candidate);
}
}
- if (almost_matched_members.Count != 0) {
- Error_MemberLookupFailed (ec.ContainerType, type, type, ".ctor",
- null, MemberTypes.Constructor, AllBindingFlags);
- return null;
- }
-
//
// We failed to find any method with correct argument count
//
if (Name == ConstructorInfo.ConstructorName) {
- Report.SymbolRelatedToPreviousError (type);
+ Report.SymbolRelatedToPreviousError (queried_type);
Report.Error (1729, loc,
"The type `{0}' does not contain a constructor that takes `{1}' arguments",
- TypeManager.CSharpName (type), arg_count);
+ TypeManager.CSharpName (queried_type), arg_count);
} else {
- Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
- Name, arg_count.ToString ());
+ Error_ArgumentCountWrong (arg_count);
}
return null;
//
best_candidate = (MethodBase) candidates [0];
- if (delegate_type == null)
- method_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
+ method_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
+
+ //
+ // TODO: Broken inverse order of candidates logic does not work with optional
+ // parameters used for method overrides and I am not going to fix it for SRE
+ //
+ if (candidates_expanded != null && candidates_expanded.Contains (best_candidate)) {
+ candidate_args = (Arguments) candidates_expanded [best_candidate];
+ arg_count = candidate_args.Count;
+ }
for (int ix = 1; ix < candidate_top; ix++) {
MethodBase candidate = (MethodBase) candidates [ix];
bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
- if (BetterFunction (ec, Arguments, arg_count,
+ if (BetterFunction (ec, candidate_args, arg_count,
candidate, cand_params,
best_candidate, method_params)) {
best_candidate = candidate;
continue;
bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
- if (!BetterFunction (ec, Arguments, arg_count,
+ if (!BetterFunction (ec, candidate_args, arg_count,
best_candidate, method_params,
candidate, cand_params))
{
}
if (ambiguous != null) {
- Report.SymbolRelatedToPreviousError (ambiguous);
- Report.SymbolRelatedToPreviousError (best_candidate);
- Report.Error (121, loc, "The call is ambiguous between the following methods or properties: `{0}' and `{1}'",
- TypeManager.CSharpSignature (ambiguous), TypeManager.CSharpSignature (best_candidate));
+ Error_AmbiguousCall (ambiguous);
return this;
}
// necessary etc. and return if everything is
// all right
//
- if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate,
+ if (!VerifyArgumentsCompat (ec, ref candidate_args, arg_count, best_candidate,
method_params, may_fail, loc))
return null;
return null;
MethodBase the_method = TypeManager.DropGenericMethodArguments (best_candidate);
-#if GMCS_SOURCE
- if (the_method.IsGenericMethodDefinition &&
+ if (TypeManager.IsGenericMethodDefinition (the_method) &&
!ConstraintChecker.CheckConstraints (ec, the_method, best_candidate, loc))
return null;
-#endif
+
+ //
+ // Check ObsoleteAttribute on the best method
+ //
+ ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (the_method);
+ if (oa != null && !ec.IsInObsoleteScope)
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
IMethodData data = TypeManager.GetMethod (the_method);
if (data != null)
data.SetMemberIsUsed ();
+ Arguments = candidate_args;
return this;
}
type_arguments = ta;
}
- public bool VerifyArgumentsCompat (EmitContext ec, ref ArrayList arguments,
+ public bool VerifyArgumentsCompat (EmitContext ec, ref Arguments arguments,
int arg_count, MethodBase method,
bool chose_params_expanded,
bool may_fail, Location loc)
{
- ParameterData pd = TypeManager.GetParameterData (method);
+ AParametersCollection pd = TypeManager.GetParameterData (method);
+ int param_count = GetApplicableParametersCount (method, pd);
int errors = Report.Errors;
Parameter.Modifier p_mod = 0;
bool has_unsafe_arg = false;
for (; a_idx < arg_count; a_idx++, ++a_pos) {
- a = (Argument) arguments [a_idx];
+ a = arguments [a_idx];
if (p_mod != Parameter.Modifier.PARAMS) {
- p_mod = pd.ParameterModifier (a_idx);
- pt = pd.ParameterType (a_idx);
+ p_mod = pd.FixedParameters [a_idx].ModFlags;
+ pt = pd.Types [a_idx];
has_unsafe_arg |= pt.IsPointer;
- if (p_mod == Parameter.Modifier.ARGLIST) {
- if (a.Type != TypeManager.runtime_argument_handle_type)
- break;
- continue;
- }
-
if (p_mod == Parameter.Modifier.PARAMS) {
if (chose_params_expanded) {
params_initializers = new ArrayList (arg_count - a_idx);
pt = TypeManager.GetElementType (pt);
}
- } else if (p_mod != 0) {
- pt = TypeManager.GetElementType (pt);
}
}
break;
continue;
- }
-
- Expression conv;
- if (TypeManager.IsEqual (a.Type, pt)) {
- conv = a.Expr;
} else {
- conv = Convert.ImplicitConversion (ec, a.Expr, pt, loc);
- if (conv == null)
- break;
+ NamedArgument na = a as NamedArgument;
+ if (na != null) {
+ int name_index = pd.GetParameterIndexByName (na.Name.Value);
+ if (name_index < 0 || name_index >= param_count) {
+ if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType)) {
+ Report.SymbolRelatedToPreviousError (DeclaringType);
+ Report.Error (1746, na.Name.Location,
+ "The delegate `{0}' does not contain a parameter named `{1}'",
+ TypeManager.CSharpName (DeclaringType), na.Name.Value);
+ } else {
+ Report.SymbolRelatedToPreviousError (best_candidate);
+ Report.Error (1739, na.Name.Location,
+ "The best overloaded method match for `{0}' does not contain a parameter named `{1}'",
+ TypeManager.CSharpSignature (method), na.Name.Value);
+ }
+ } else if (arguments[name_index] != a) {
+ if (DeclaringType != null && TypeManager.IsDelegateType (DeclaringType))
+ Report.SymbolRelatedToPreviousError (DeclaringType);
+ else
+ Report.SymbolRelatedToPreviousError (best_candidate);
+
+ Report.Error (1744, na.Name.Location,
+ "Named argument `{0}' cannot be used for a parameter which has positional argument specified",
+ na.Name.Value);
+ }
+ }
}
+ if (delegate_type != null && !Delegate.IsTypeCovariant (a.Expr, pt))
+ break;
+
+ Expression conv = Convert.ImplicitConversion (ec, a.Expr, pt, loc);
+ if (conv == null)
+ break;
+
//
// Convert params arguments to an array initializer
//
a.Expr = conv;
}
+ if (a_idx != arg_count) {
+ if (!may_fail && Report.Errors == errors) {
+ if (CustomErrorHandler != null)
+ CustomErrorHandler.NoExactMatch (ec, best_candidate);
+ else
+ Error_InvalidArguments (ec, loc, a_pos, method, a, pd, pt);
+ }
+ return false;
+ }
+
//
// Fill not provided arguments required by params modifier
//
- if (params_initializers == null && pd.HasParams && arg_count < pd.Count && a_idx + 1 == pd.Count) {
+ if (params_initializers == null && pd.HasParams && arg_count + 1 == param_count) {
if (arguments == null)
- arguments = new ArrayList (1);
+ arguments = new Arguments (1);
- pt = pd.Types [GetApplicableParametersCount (method, pd) - 1];
+ pt = pd.Types [param_count - 1];
pt = TypeManager.GetElementType (pt);
has_unsafe_arg |= pt.IsPointer;
params_initializers = new ArrayList (0);
}
- if (a_idx == arg_count) {
- //
- // Append an array argument with all params arguments
- //
- if (params_initializers != null) {
- arguments.Add (new Argument (
- new ArrayCreation (new TypeExpression (pt, loc), "[]",
- params_initializers, loc).Resolve (ec)));
- }
-
- if (has_unsafe_arg && !ec.InUnsafe) {
- if (!may_fail)
- UnsafeError (loc);
- return false;
- }
+ //
+ // Append an array argument with all params arguments
+ //
+ if (params_initializers != null) {
+ arguments.Add (new Argument (
+ new ArrayCreation (new TypeExpression (pt, loc), "[]",
+ params_initializers, loc).Resolve (ec)));
+ arg_count++;
+ }
- return true;
+ if (arg_count < param_count) {
+ if (!may_fail)
+ Error_ArgumentCountWrong (arg_count);
+ return false;
}
- if (!may_fail && Report.Errors == errors) {
- if (CustomErrorHandler != null)
- CustomErrorHandler.NoExactMatch (ec, best_candidate);
- else
- Error_InvalidArguments (ec, loc, a_pos, method, a, pd, pt);
+ if (has_unsafe_arg && !ec.InUnsafe) {
+ if (!may_fail)
+ UnsafeError (loc);
+ return false;
}
- return false;
+
+ return true;
}
}
LocalTemporary temp;
bool prepared;
- bool in_initializer;
-
- public FieldExpr (FieldInfo fi, Location l, bool in_initializer):
- this (fi, l)
+
+ protected FieldExpr (Location l)
{
- this.in_initializer = in_initializer;
+ loc = l;
}
public FieldExpr (FieldInfo fi, Location l)
{
FieldInfo = fi;
- eclass = ExprClass.Variable;
type = TypeManager.TypeToCoreType (fi.FieldType);
loc = l;
}
public FieldExpr (FieldInfo fi, Type genericType, Location l)
: this (fi, l)
{
+ if (TypeManager.IsGenericTypeDefinition (genericType))
+ return;
this.constructed_generic_type = genericType;
}
instance = InstanceExpression.CreateExpressionTree (ec);
}
- ArrayList args = new ArrayList (2);
- args.Add (new Argument (instance));
- args.Add (new Argument (CreateTypeOfExpression ()));
+ Arguments args = Arguments.CreateForExpressionTree (ec, null,
+ instance,
+ CreateTypeOfExpression ());
+
return CreateExpressionFactoryCall ("Field", args);
}
public Expression CreateTypeOfExpression ()
{
- return new TypeOfField (FieldInfo, loc);
+ return new TypeOfField (GetConstructedFieldInfo (), loc);
}
override public Expression DoResolve (EmitContext ec)
using (ec.With (EmitContext.Flags.DoFlowAnalysis, false)) {
Expression right_side =
out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
- InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side, loc);
+
+ if (InstanceExpression != EmptyExpression.Null)
+ InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
}
} else {
ResolveFlags rf = ResolveFlags.VariableOrValue | ResolveFlags.DisableFlowAnalysis;
- InstanceExpression = InstanceExpression.Resolve (ec, rf);
+
+ if (InstanceExpression != EmptyExpression.Null)
+ InstanceExpression = InstanceExpression.Resolve (ec, rf);
}
if (InstanceExpression == null)
}
}
- if (!in_initializer && !ec.IsInFieldInitializer) {
- ObsoleteAttribute oa;
+ // TODO: the code above uses some non-standard multi-resolve rules
+ if (eclass != ExprClass.Invalid)
+ return this;
+
+ if (!ec.IsInObsoleteScope) {
FieldBase f = TypeManager.GetField (FieldInfo);
if (f != null) {
- if (!ec.IsInObsoleteScope)
- f.CheckObsoleteness (loc);
-
- // To be sure that type is external because we do not register generated fields
- } else if (!(FieldInfo.DeclaringType is TypeBuilder)) {
- oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
+ f.CheckObsoleteness (loc);
+ } else {
+ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
if (oa != null)
AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc);
}
IVariableReference var = InstanceExpression as IVariableReference;
if (fb != null) {
- if (!ec.InFixedInitializer && ec.ContainerType.IsValueType) {
+ IFixedExpression fe = InstanceExpression as IFixedExpression;
+ if (!ec.InFixedInitializer && (fe == null || !fe.IsFixed)) {
Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
}
return new FixedBufferPtr (this, fb.ElementType, loc).Resolve (ec);
}
+ eclass = ExprClass.Variable;
+
// If the instance expression is a local variable or parameter.
if (var == null || var.VariableInfo == null)
return this;
return null;
variable_info = vi.GetSubStruct (FieldInfo.Name);
+ eclass = ExprClass.Variable;
return this;
}
if (var != null && var.VariableInfo != null)
var.VariableInfo.SetFieldAssigned (ec, FieldInfo.Name);
- bool lvalue_instance = !FieldInfo.IsStatic && FieldInfo.DeclaringType.IsValueType;
+ bool lvalue_instance = !FieldInfo.IsStatic && TypeManager.IsValueType (FieldInfo.DeclaringType);
bool out_access = right_side == EmptyExpression.OutAccess || right_side == EmptyExpression.LValueMemberOutAccess;
Expression e = DoResolve (ec, lvalue_instance, out_access);
GetSignatureForError ());
}
+ eclass = ExprClass.Variable;
return this;
}
bool is_marshal_by_ref ()
{
- return !IsStatic && Type.IsValueType && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type);
+ return !IsStatic && TypeManager.IsStruct (Type) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type);
}
public override void CheckMarshalByRefAccess (EmitContext ec)
return FieldInfo.GetHashCode ();
}
- public bool IsFixedVariable {
+ public bool IsFixed {
get {
//
// A variable of the form V.I is fixed when V is a fixed variable of a struct type
//
IVariableReference variable = InstanceExpression as IVariableReference;
- return variable != null && InstanceExpression.Type.IsValueType && variable.IsFixedVariable;
+ if (variable != null)
+ return TypeManager.IsStruct (InstanceExpression.Type) && variable.IsFixed;
+
+ IFixedExpression fe = InstanceExpression as IFixedExpression;
+ return fe != null && fe.IsFixed;
}
}
if (!prepared)
EmitInstance (ec, false);
- IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo);
- if (ff != null) {
- ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
- ig.Emit (OpCodes.Ldflda, ff.Element);
+ // Optimization for build-in types
+ // TODO: Iterators don't set current container
+ if (TypeManager.IsStruct (type) && type == ec.DeclContainer.TypeBuilder && ec.CurrentIterator == null) {
+ LoadFromPtr (ig, type);
} else {
- if (is_volatile)
- ig.Emit (OpCodes.Volatile);
+ IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo);
+ if (ff != null) {
+ ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
+ ig.Emit (OpCodes.Ldflda, ff.Element);
+ } else {
+ if (is_volatile)
+ ig.Emit (OpCodes.Volatile);
- ig.Emit (OpCodes.Ldfld, GetConstructedFieldInfo ());
+ ig.Emit (OpCodes.Ldfld, GetConstructedFieldInfo ());
+ }
}
}
prepared = prepare_for_load;
EmitInstance (ec, prepared);
- source.Emit (ec);
+ source.Emit (ec);
if (leave_copy) {
ec.ig.Emit (OpCodes.Dup);
if (!FieldInfo.IsStatic) {
public override Expression CreateExpressionTree (EmitContext ec)
{
- ArrayList args;
+ Arguments args;
if (IsSingleDimensionalArrayLength ()) {
- args = new ArrayList (1);
+ args = new Arguments (1);
args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
return CreateExpressionFactoryCall ("ArrayLength", args);
}
return null;
}
- args = new ArrayList (2);
+ args = new Arguments (2);
if (InstanceExpression == null)
args.Add (new Argument (new NullLiteral (loc)));
else
InstanceExpression.MutateHoistedGenericType (storey);
type = storey.MutateType (type);
- getter = storey.MutateGenericMethod (getter);
+ if (getter != null)
+ getter = storey.MutateGenericMethod (getter);
+ if (setter != null)
+ setter = storey.MutateGenericMethod (setter);
}
bool InstanceResolve (EmitContext ec, bool lvalue_instance, bool must_do_cs1540_check)
InstanceExpression = InstanceExpression.DoResolve (ec);
if (lvalue_instance && InstanceExpression != null)
- InstanceExpression = InstanceExpression.ResolveLValue (ec, EmptyExpression.LValueMemberAccess, loc);
+ InstanceExpression = InstanceExpression.ResolveLValue (ec, EmptyExpression.LValueMemberAccess);
if (InstanceExpression == null)
return false;
StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
sig.Append ('.');
- ParameterData iparams = TypeManager.GetParameterData (mi);
+ AParametersCollection iparams = TypeManager.GetParameterData (mi);
sig.Append (getter ? "get_" : "set_");
sig.Append (Name);
sig.Append (iparams.GetSignatureForError ());
//
if (IsBase && getter.IsAbstract) {
Error_CannotCallAbstractBase (TypeManager.GetFullNameSignature (PropertyInfo));
- return null;
}
if (PropertyInfo.PropertyType.IsPointer && !ec.InUnsafe){
UnsafeError (loc);
- return null;
+ }
+
+ if (!ec.IsInObsoleteScope) {
+ PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
+ if (pb != null) {
+ pb.CheckObsoleteness (loc);
+ } else {
+ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+ }
}
resolved = true;
override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
{
if (right_side == EmptyExpression.OutAccess) {
- if (ec.CurrentBlock.Toplevel.GetTransparentIdentifier (PropertyInfo.Name) != null) {
+ if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
Report.Error (1939, loc, "A range variable `{0}' may not be passes as `ref' or `out' parameter",
PropertyInfo.Name);
} else {
if (getter == null)
return null;
- if (ec.CurrentBlock.Toplevel.GetTransparentIdentifier (PropertyInfo.Name) != null) {
+ if (ec.CurrentBlock.Toplevel.GetParameterReference (PropertyInfo.Name, loc) is MemberAccess) {
Report.Error (1947, loc, "A range variable `{0}' cannot be assigned to. Consider using `let' clause to store the value",
PropertyInfo.Name);
} else {
return null;
}
- if (!InstanceResolve (ec, PropertyInfo.DeclaringType.IsValueType, must_do_cs1540_check))
+ if (!InstanceResolve (ec, TypeManager.IsStruct (PropertyInfo.DeclaringType), must_do_cs1540_check))
return null;
//
//
if (IsBase && setter.IsAbstract){
Error_CannotCallAbstractBase (TypeManager.GetFullNameSignature (PropertyInfo));
- return null;
}
if (PropertyInfo.PropertyType.IsPointer && !ec.InUnsafe) {
UnsafeError (loc);
}
+ if (!ec.IsInObsoleteScope) {
+ PropertyBase pb = TypeManager.GetProperty (PropertyInfo);
+ if (pb != null) {
+ pb.CheckObsoleteness (loc);
+ } else {
+ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (PropertyInfo);
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+ }
+ }
+
return this;
}
my_source = temp;
}
- ArrayList args = new ArrayList (1);
- args.Add (new Argument (my_source, Argument.AType.Expression));
+ Arguments args = new Arguments (1);
+ args.Add (new Argument (my_source));
Invocation.EmitCall (ec, IsBase, InstanceExpression, setter, args, loc, false, prepared);
if ((mi.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.IsInCompoundAssignment)
Error_AssignmentEventOnly ();
- FieldExpr ml = new FieldExpr (mi.FieldBuilder, loc);
+ FieldExpr ml = new FieldExpr (mi.BackingField.FieldBuilder, loc);
InstanceExpression = null;
Error_CannotAssign ();
return null;
}
+
+ if (!ec.IsInObsoleteScope) {
+ EventField ev = TypeManager.GetEventField (EventInfo);
+ if (ev != null) {
+ ev.CheckObsoleteness (loc);
+ } else {
+ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (EventInfo);
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+ }
+ }
return this;
}
public void EmitAddOrRemove (EmitContext ec, bool is_add, Expression source)
{
- ArrayList args = new ArrayList (1);
- args.Add (new Argument (source, Argument.AType.Expression));
+ Arguments args = new Arguments (1);
+ args.Add (new Argument (source));
Invocation.EmitCall (ec, IsBase, InstanceExpression, is_add ? add_accessor : remove_accessor, args, loc);
}
}
EmitAssign (ec, source, false, false);
}
- public override HoistedVariable HoistedVariable {
- get { return li.HoistedVariableReference; }
+ public override HoistedVariable GetHoistedVariable (EmitContext ec)
+ {
+ return li.HoistedVariableReference;
}
- public override bool IsFixedVariable {
+ public override bool IsFixed {
get { return true; }
}