return TypeManager.IsPrivateAccessible (invocation_type, mi.DeclaringType) ||
TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType);
- if (mi.DeclaringType.Assembly == invocation_type.Assembly ||
- TypeManager.IsFriendAssembly (mi.DeclaringType.Assembly)) {
+ if (TypeManager.IsThisOrFriendAssembly (mi.DeclaringType.Assembly)) {
if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
return true;
} else {
if (TypeManager.IsGenericParameter (Type) && TypeManager.IsGenericParameter (target) && type.Name == target.Name) {
#if GMCS_SOURCE
- string sig1 = Type.DeclaringMethod == null ?
- TypeManager.CSharpName (Type.DeclaringType) :
- TypeManager.CSharpSignature (Type.DeclaringMethod);
+ string sig1 = type.DeclaringMethod == null ?
+ TypeManager.CSharpName (type.DeclaringType) :
+ TypeManager.CSharpSignature (type.DeclaringMethod);
string sig2 = target.DeclaringMethod == null ?
TypeManager.CSharpName (target.DeclaringType) :
TypeManager.CSharpSignature (target.DeclaringMethod);
if (t == TypeManager.enum_type)
ig.Emit (OpCodes.Ldind_Ref);
else
- LoadFromPtr (ig, TypeManager.EnumToUnderlying (t));
+ LoadFromPtr (ig, TypeManager.GetEnumUnderlyingType (t));
} else if (t.IsValueType || TypeManager.IsGenericParameter (t))
ig.Emit (OpCodes.Ldobj, t);
else if (t.IsPointer)
public static void StoreFromPtr (ILGenerator ig, Type type)
{
if (TypeManager.IsEnumType (type))
- type = TypeManager.EnumToUnderlying (type);
+ type = TypeManager.GetEnumUnderlyingType (type);
if (type == TypeManager.int32_type || type == TypeManager.uint32_type)
ig.Emit (OpCodes.Stind_I4);
else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)
public static Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, ArrayList args, Location loc)
{
- TypeExpression texpr = new TypeExpression (LinqExpression.expression_type, loc);
+ TypeExpr texpr = TypeManager.expression_type_expr;
+ if (texpr == null) {
+ Type t = TypeManager.CoreLookupType ("System.Linq.Expressions", "Expression", Kind.Class, true);
+ if (t == null)
+ return null;
+
+ TypeManager.expression_type_expr = texpr = new TypeExpression (t, Location.Null);
+ }
+
return new Invocation (new MemberAccess (texpr, name, typeArguments, loc), args);
}
}
if (c != null)
return new EmptyConstantCast (c, type);
+ //
+ // No double conversion required when wrapping nullable types
+ //
+ if (TypeManager.IsNullableType (type)) {
+ EmptyCast empty_cast = child as EmptyCast;
+ if (empty_cast != null) {
+ if (TypeManager.IsNullableTypeOf (empty_cast.type, type))
+ throw new InternalErrorException ("Missing nullable underlying type conversion {0} != {1}",
+ TypeManager.CSharpName (empty_cast.type), TypeManager.CSharpName (type));
+
+ empty_cast.type = type;
+ return empty_cast;
+ }
+ }
+
return new EmptyCast (child, type);
}
foreach (MethodInfo oper in mi) {
ParameterData pd = TypeManager.GetParameterData (oper);
- if (pd.ParameterType (0) == child.Type && oper.ReturnType == type)
+ if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
return oper;
}
foreach (MethodInfo oper in mi) {
ParameterData pd = TypeManager.GetParameterData (oper);
- if (pd.ParameterType (0) == child.Type && oper.ReturnType == type)
+ if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
return oper;
}
foreach (MethodInfo oper in all_oper) {
ParameterData pd = TypeManager.GetParameterData (oper);
if (pd.ParameterType (0) == TypeManager.decimal_type)
- operators.Add (oper.ReturnType, oper);
+ operators.Add (TypeManager.TypeToCoreType (oper.ReturnType), oper);
}
}
second_valid = true;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ // A cast has no expresion tree representation
+ return child.CreateExpressionTree (ec);
+ }
+
public override Expression DoResolve (EmitContext ec)
{
// This should never be invoked, we are born in fully
if (second_valid)
ec.ig.Emit (op2);
- }
+ }
+
+ public Type UnderlyingType {
+ get { return child.Type; }
+ }
}
/// <summary>
ec.ig.Emit (OpCodes.Castclass, type);
}
}
+
+ //
+ // Used when resolved expression has different representations for
+ // expression trees and emit phase
+ //
+ public class ReducedExpression : Expression
+ {
+ class ReducedConstantExpression : Constant
+ {
+ readonly Constant expr;
+ readonly Expression orig_expr;
+
+ public ReducedConstantExpression (Constant expr, Expression orig_expr)
+ : base (expr.Location)
+ {
+ this.expr = expr;
+ this.orig_expr = orig_expr;
+ }
+
+ public override string AsString ()
+ {
+ return expr.AsString ();
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return orig_expr.CreateExpressionTree (ec);
+ }
+
+ public override object GetValue ()
+ {
+ return expr.GetValue ();
+ }
+
+ public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ eclass = expr.eclass;
+ type = expr.Type;
+ return this;
+ }
+
+ public override Constant Increment ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool IsDefaultValue {
+ get {
+ return expr.IsDefaultValue;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return expr.IsNegative;
+ }
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ expr.Emit (ec);
+ }
+ }
+
+ readonly Expression expr, orig_expr;
+
+ private ReducedExpression (Expression expr, Expression orig_expr)
+ {
+ this.expr = expr;
+ this.orig_expr = orig_expr;
+ }
+
+ public static Expression Create (Constant expr, Expression original_expr)
+ {
+ return new ReducedConstantExpression (expr, original_expr);
+ }
+
+ public static Expression Create (Expression expr, Expression original_expr)
+ {
+ Constant c = expr as Constant;
+ if (c != null)
+ return Create (c, original_expr);
+
+ return new ReducedExpression (expr, original_expr);
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return orig_expr.CreateExpressionTree (ec);
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ eclass = expr.eclass;
+ type = expr.Type;
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ expr.Emit (ec);
+ }
+ }
/// <summary>
/// SimpleName expressions are formed of a single word and only happen at the beginning
if (!me.IsStatic &&
(!intermediate || !IdenticalNameAndTypeName (ec, me, loc))) {
Error_ObjectRefRequired (ec, loc, me.GetSignatureForError ());
- return EmptyExpression.Null;
+ return null;
}
//
return ds.CheckAccessLevel (Type);
}
- public virtual bool AsAccessible (DeclSpace ds, int flags)
+ public virtual bool AsAccessible (DeclSpace ds)
{
- return ds.AsAccessible (Type, flags);
+ return ds.IsAccessibleAs (Type);
}
public virtual bool IsClass {
return texpr.CheckAccessLevel (ds);
}
- public override bool AsAccessible (DeclSpace ds, int flags)
+ public override bool AsAccessible (DeclSpace ds)
{
- return texpr.AsAccessible (ds, flags);
+ return texpr.AsAccessible (ds);
}
public override bool IsClass {
}
//
- // Determines "better conversion" as specified in 7.4.3
+ // 7.4.3.3 Better conversion from expression
// Returns : 1 if a->p is better,
// 2 if a->q is better,
// 0 if neither is better
//
- static int BetterConversion (EmitContext ec, Argument a, Type p, Type q)
+ static int BetterExpressionConversion (EmitContext ec, Argument a, Type p, Type q)
{
- if (p == null || q == null)
- throw new InternalErrorException ("BetterConversion Got a null conversion");
-
- Expression argument_expr = a.Expr;
- if (argument_expr is NullLiteral) {
- //
- // If the argument is null and one of the types to compare is 'object' and
- // the other is a reference type, we prefer the other.
- //
- // This follows from the usual rules:
- // * There is an implicit conversion from 'null' to type 'object'
- // * There is an implicit conversion from 'null' to any reference type
- // * There is an implicit conversion from any reference type to type 'object'
- // * There is no implicit conversion from type 'object' to other reference types
- // => Conversion of 'null' to a reference type is better than conversion to 'object'
- //
- // FIXME: This probably isn't necessary, since the type of a NullLiteral is the
- // null type. I think it used to be 'object' and thus needed a special
- // case to avoid the immediately following two checks.
- //
- if (!p.IsValueType && q == TypeManager.object_type)
- return 1;
- if (!q.IsValueType && p == TypeManager.object_type)
- return 2;
- }
-
Type argument_type = TypeManager.TypeToCoreType (a.Type);
if (argument_type == TypeManager.anonymous_method_type && RootContext.Version > LanguageVersion.ISO_2) {
//
return 2;
}
- Expression p_tmp = new EmptyExpression (p);
- Expression q_tmp = new EmptyExpression (q);
-
- bool p_to_q = Convert.ImplicitConversionExists (ec, p_tmp, q);
- bool q_to_p = Convert.ImplicitConversionExists (ec, q_tmp, p);
-
- if (p_to_q && !q_to_p)
- return 1;
+ return BetterTypeConversion (ec, p, q);
+ }
- if (q_to_p && !p_to_q)
- return 2;
+ //
+ // 7.4.3.4 Better conversion from type
+ //
+ public static int BetterTypeConversion (EmitContext ec, Type p, Type q)
+ {
+ if (p == null || q == null)
+ throw new InternalErrorException ("BetterTypeConversion got a null conversion");
- if (p == TypeManager.sbyte_type)
+ if (p == TypeManager.int32_type) {
+ if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
+ return 1;
+ } else if (p == TypeManager.int64_type) {
+ if (q == TypeManager.uint64_type)
+ return 1;
+ } else if (p == TypeManager.sbyte_type) {
if (q == TypeManager.byte_type || q == TypeManager.ushort_type ||
q == TypeManager.uint32_type || q == TypeManager.uint64_type)
return 1;
- if (q == TypeManager.sbyte_type)
- if (p == TypeManager.byte_type || p == TypeManager.ushort_type ||
- p == TypeManager.uint32_type || p == TypeManager.uint64_type)
- return 2;
-
- if (p == TypeManager.short_type)
+ } else if (p == TypeManager.short_type) {
if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
q == TypeManager.uint64_type)
return 1;
- if (q == TypeManager.short_type)
- if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
- p == TypeManager.uint64_type)
- return 2;
+ }
- if (p == TypeManager.int32_type)
- if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
- return 1;
- if (q == TypeManager.int32_type)
+ if (q == TypeManager.int32_type) {
if (p == TypeManager.uint32_type || p == TypeManager.uint64_type)
return 2;
-
- if (p == TypeManager.int64_type)
- if (q == TypeManager.uint64_type)
- return 1;
- if (q == TypeManager.int64_type)
+ } if (q == TypeManager.int64_type) {
if (p == TypeManager.uint64_type)
return 2;
+ } else if (q == TypeManager.sbyte_type) {
+ if (p == TypeManager.byte_type || p == TypeManager.ushort_type ||
+ p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+ return 2;
+ } if (q == TypeManager.short_type) {
+ if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
+ p == TypeManager.uint64_type)
+ return 2;
+ }
+
+ // TODO: this is expensive
+ Expression p_tmp = new EmptyExpression (p);
+ Expression q_tmp = new EmptyExpression (q);
+
+ bool p_to_q = Convert.ImplicitConversionExists (ec, p_tmp, q);
+ bool q_to_p = Convert.ImplicitConversionExists (ec, q_tmp, p);
+
+ if (p_to_q && !q_to_p)
+ return 1;
+
+ if (q_to_p && !p_to_q)
+ return 2;
return 0;
}
continue;
same = false;
- int result = BetterConversion (ec, a, ct, bt);
+ int result = BetterExpressionConversion (ec, a, ct, bt);
// for each argument, the conversion to 'ct' should be no worse than
// the conversion to 'bt'.
params_expanded_form = true;
}
- if (score != 0)
+ if (score != 0) {
+ if (params_expanded_form)
+ ++score;
return (arg_count - i) * 2 + score;
+ }
}
if (arg_count != param_count)
}
}
- if (VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, may_fail, loc))
- throw new InternalErrorException ("Overload verification expected failure");
- return null;
+ if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, may_fail, loc))
+ return null;
}
}
// should be better than all the others
//
MethodBase ambiguous = null;
- for (int ix = 0; ix < candidate_top; ix++) {
+ for (int ix = 1; ix < candidate_top; ix++) {
MethodBase candidate = (MethodBase) candidates [ix];
if (candidate == best_candidate)
//
// Fill not provided arguments required by params modifier
//
- if (params_initializers == null && pd.HasParams && arg_count < pd.Count) {
+ if (params_initializers == null && pd.HasParams && arg_count < pd.Count && a_idx + 1 == pd.Count) {
if (arguments == null)
arguments = new ArrayList (1);
}
if (right_side == EmptyExpression.OutAccess &&
- !IsStatic && !(InstanceExpression is This) && DeclaringType.IsSubclassOf (TypeManager.mbr_type)) {
+ !IsStatic && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type)) {
Report.SymbolRelatedToPreviousError (DeclaringType);
Report.Warning (197, 1, loc,
"Passing `{0}' as ref or out or taking its address may cause a runtime exception because it is a field of a marshal-by-reference class",
public override void CheckMarshalByRefAccess (EmitContext ec)
{
- if (!IsStatic && Type.IsValueType && !(InstanceExpression is This) && DeclaringType.IsSubclassOf (TypeManager.mbr_type)) {
+ if (!IsStatic && Type.IsValueType && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type)) {
Report.SymbolRelatedToPreviousError (DeclaringType);
Report.Warning (1690, 1, loc, "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
GetSignatureForError ());
Error_TypeDoesNotContainDefinition (loc, PropertyInfo.DeclaringType, Name);
return;
}
-
+
StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
sig.Append ('.');
ParameterData iparams = TypeManager.GetParameterData (mi);
bool IsSingleDimensionalArrayLength ()
{
- if (getter == TypeManager.system_int_array_get_length ||
- getter == TypeManager.int_array_get_length) {
- Type iet = InstanceExpression.Type;
-
- //
- // System.Array.Length can be called, but the Type does not
- // support invoking GetArrayRank, so test for that case first
- //
- return iet != TypeManager.array_type && (iet.GetArrayRank () == 1);
- }
+ if (DeclaringType != TypeManager.array_type || getter == null || Name != "Length")
+ return false;
- return false;
+ string t_name = InstanceExpression.Type.Name;
+ int t_name_len = t_name.Length;
+ return t_name_len > 2 && t_name [t_name_len - 2] == '[' && t_name [t_name_len - 3] != ']';
}
override public Expression DoResolve (EmitContext ec)
//
if (must_do_cs1540_check && InstanceExpression != EmptyExpression.Null &&
InstanceExpression.Type != ec.ContainerType &&
- ec.ContainerType.IsSubclassOf (InstanceExpression.Type)) {
+ TypeManager.IsSubclassOf (ec.ContainerType, InstanceExpression.Type)) {
Report.SymbolRelatedToPreviousError (EventInfo);
ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
return false;