return te;
}
-
+
public TypeExpr ResolveAsBaseTerminal (IResolveContext ec, bool silent)
{
int errors = Report.Errors;
}
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)
/// 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 (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);
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);
//
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 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)
//
// This works only sometimes
//
- if (type.Module == CodeGen.Module.Builder)
+ if (type.Module == RootContext.ToplevelTypes.Builder)
return Child.GetValue ();
#endif
{
// 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)
{
- ILGenerator ig = ec.ig;
-
base.Emit (ec);
-#if GMCS_SOURCE
- if (type.IsGenericParameter || type.IsGenericType && type.IsValueType)
- ig.Emit (OpCodes.Unbox_Any, type);
- else
-#endif
- {
- ig.Emit (OpCodes.Unbox, type);
- LoadFromPtr (ig, type);
- }
+ 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)
/// 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 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));
}
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));
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 (vi != 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)
}
Expression expr = current_block.Toplevel.GetParameterReference (Name, loc);
- if (expr == null)
- expr = current_block.Toplevel.GetTransparentIdentifier (Name);
-
if (expr != null) {
if (right_side != null)
- return expr.ResolveLValue (ec, right_side, loc);
+ return expr.ResolveLValue (ec, right_side);
return expr.Resolve (ec);
}
} 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;
}
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;
-
- GenericTypeExpr ct = new GenericTypeExpr (
- 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 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;
}
public override string GetSignatureForError ()
{
if (type == null)
- return TypeManager.CSharpName (name, null);
+ return TypeManager.CSharpName (ns_name + "." + name, null);
return base.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)
- {
- if (arguments == null)
- arguments = new ArrayList (1);
- arguments.Insert (0, extension_argument);
- base.EmitCall (ec, arguments);
- }
-
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
{
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);
}
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)
{
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;
}
}
/// 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)
{
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 = candidate_pd.Types [c_idx];
Type bt = best_pd.Types [b_idx];
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
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,
}
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 = idx >= expected_par.Count ? 0 : expected_par.FixedParameters [idx].ModFlags;
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, AParametersCollection parameters)
{
/// 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;
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.FixedParameters [i].ModFlags & ~(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;
+ }
+ 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 && 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;
}
/// 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);
+
+ candidates_expanded.Add (Methods [i], candidate_args);
+ candidate_args = Arguments;
+ }
if (candidate_rate != 0 || has_inaccessible_candidates_only) {
if (msg_recorder != null)
// 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;
AParametersCollection pd = TypeManager.GetParameterData (best_candidate);
bool cand_params = candidate_to_form != null && candidate_to_form.Contains (best_candidate);
// 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, type, ec.ContainerType);
+ Error_CannotAccessProtected (loc, best_candidate, queried_type, ec.ContainerType);
} else {
+ Report.SymbolRelatedToPreviousError (best_candidate);
ErrorIsInaccesible (loc, GetSignatureForError ());
}
}
if (has_inaccessible_candidates_only)
return null;
+
+ throw new InternalErrorException ("VerifyArgumentsCompat didn't find any problem with rejected candidate " + best_candidate);
}
}
// 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];
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 (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
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)
{
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.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);
break;
continue;
+ } else {
+ 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;
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;
+ protected FieldExpr (Location l)
+ {
+ loc = l;
+ }
+
public FieldExpr (FieldInfo fi, Location l)
{
FieldInfo = fi;
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);
}
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 (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);
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)
// 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.IsFixed;
+ 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 ());
+ }
}
}
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 = 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;
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;
//
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;
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 IsFixed {