+2003-07-22 Ravi Pratap <ravi@ximian.com>
+
+ * expression.cs (Invocation.OverloadResolve): Follow the spec more
+ closely: we eliminate methods in base types when we have an
+ applicable method in a top-level type.
+
+ Please see section 14.5.5.1 for an exact description of what goes
+ on.
+
+ This fixes bug #45127 and a host of other related to corlib compilation.
+
+ * ecore.cs (MethodGroupExpr.DeclaringType): The element in the
+ array is the method corresponding to the top-level type (this is
+ because of the changes made to icall.c) so we change this
+ accordingly.
+
+ (MethodGroupExpr.Name): This too.
+
+ * typemanager.cs (GetElementType): New method which does the right
+ thing when compiling corlib.
+
+ * everywhere: Make use of the above in the relevant places.
+
2003-07-22 Martin Baulig <martin@ximian.com>
* cs-parser.jay (invocation_expression): Moved
public bool AsAccessible (Type parent, int flags)
{
while (parent.IsArray || parent.IsPointer || parent.IsByRef)
- parent = parent.GetElementType ();
+ parent = TypeManager.GetElementType (parent);
AccessLevel level = GetAccessLevel (flags);
AccessLevel level2 = GetAccessLevel (parent, flags);
Type t = pinfo.ParameterType(0);
if (t.IsArray &&
(t.GetArrayRank() == 1) &&
- (t.GetElementType() == TypeManager.string_type) &&
+ (TypeManager.GetElementType(t) == TypeManager.string_type) &&
(pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
return true;
else
if (partype.IsPointer){
if (!UnsafeOK (container))
error = true;
- if (!TypeManager.VerifyUnManaged (partype.GetElementType (), Location))
+ if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
error = true;
}
if (expr_type.IsArray && target_type.IsArray) {
if (expr_type.GetArrayRank () == target_type.GetArrayRank ()) {
- Type expr_element_type = expr_type.GetElementType ();
+ Type expr_element_type = TypeManager.GetElementType (expr_type);
if (MyEmptyExpr == null)
MyEmptyExpr = new EmptyExpression ();
MyEmptyExpr.SetType (expr_element_type);
- Type target_element_type = target_type.GetElementType ();
+ Type target_element_type = TypeManager.GetElementType (target_type);
if (!expr_element_type.IsValueType && !target_element_type.IsValueType)
if (ImplicitStandardConversionExists (MyEmptyExpr,
MyEmptyExpr = new EmptyExpression ();
MyEmptyExpr.SetType (expr_element_type);
- Type target_element_type = target_type.GetElementType ();
+ Type target_element_type = TypeManager.GetElementType (target_type);
if (!expr_element_type.IsValueType && !target_element_type.IsValueType)
if (ImplicitStandardConversionExists (MyEmptyExpr,
/// </summary>
public static bool ImplicitConversionExists (EmitContext ec, Expression expr, Type target_type)
{
- if (ImplicitStandardConversionExists (expr, target_type) == true)
+ if (ImplicitStandardConversionExists (expr, target_type))
return true;
Expression dummy = ImplicitUserConversion (ec, expr, target_type, Location.Null);
if (expr_type == TypeManager.void_type)
return false;
-
+
+ //Console.WriteLine ("Expr is {0}", expr);
+ //Console.WriteLine ("{0} -> {1} ?", expr_type, target_type);
if (expr_type == target_type)
return true;
+ //Console.WriteLine ("No !!");
+
// First numeric conversions
if (expr_type == TypeManager.sbyte_type){
// t1 == t2, we have to compare their element types.
//
if (target_type.IsPointer){
- if (target_type.GetElementType() == expr_type.GetElementType())
+ if (TypeManager.GetElementType(target_type) == TypeManager.GetElementType(expr_type))
return expr;
}
}
if (source_type.IsArray && target_type.IsArray) {
if (source_type.GetArrayRank () == target_type.GetArrayRank ()) {
- Type source_element_type = source_type.GetElementType ();
- Type target_element_type = target_type.GetElementType ();
+ Type source_element_type = TypeManager.GetElementType (source_type);
+ Type target_element_type = TypeManager.GetElementType (target_type);
if (!source_element_type.IsValueType && !target_element_type.IsValueType)
if (ExplicitReferenceConversionExists (source_element_type,
if (source_type.IsArray && target_type.IsArray) {
if (source_type.GetArrayRank () == target_type.GetArrayRank ()) {
- Type source_element_type = source_type.GetElementType ();
- Type target_element_type = target_type.GetElementType ();
+ Type source_element_type = TypeManager.GetElementType (source_type);
+ Type target_element_type = TypeManager.GetElementType (target_type);
if (!source_element_type.IsValueType && !target_element_type.IsValueType)
if (ExplicitReferenceConversionExists (source_element_type,
// NonPublic visibility for pointers
//
if (check_type.IsArray || check_type.IsPointer)
- return CheckAccessLevel (check_type.GetElementType ());
+ return CheckAccessLevel (TypeManager.GetElementType (check_type));
switch (check_attr){
case TypeAttributes.Public:
// If we have a parent class (we have a parent class unless we're
// TypeManager.object_type), we deep-copy its MemberCache here.
- if (Container.Parent != null)
+ if (Container.Parent != null) {
member_hash = SetupCache (Container.Parent.MemberCache);
- else if (Container.IsInterface)
+ } else if (Container.IsInterface)
member_hash = SetupCacheForInterface ();
else
member_hash = new Hashtable ();
IDictionaryEnumerator it = parent.member_hash.GetEnumerator ();
while (it.MoveNext ()) {
hash [it.Key] = ((ArrayList) it.Value).Clone ();
- }
-
+ }
+
return hash;
}
}
throw;
}
+
loc = l;
eclass = ExprClass.MethodGroup;
type = TypeManager.object_type;
public Type DeclaringType {
get {
- return Methods [0].DeclaringType;
+ //
+ // We assume that the top-level type is in the end
+ //
+ return Methods [Methods.Length - 1].DeclaringType;
+ //return Methods [0].DeclaringType;
}
}
public string Name {
get {
- return Methods [0].Name;
+ //return Methods [0].Name;
+ return Methods [Methods.Length - 1].Name;
}
}
public void ReportUsageError ()
{
- Report.Error (654, loc, "Method `" + Methods [0].DeclaringType + "." +
- Methods [0].Name + "()' is referenced without parentheses");
+ Report.Error (654, loc, "Method `" + DeclaringType + "." +
+ Name + "()' is referenced without parentheses");
}
override public void Emit (EmitContext ec)
public Indirection (Expression expr, Location l)
{
this.expr = expr;
- this.type = TypeManager.TypeToCoreType (expr.Type.GetElementType ());
+ this.type = TypeManager.GetElementType (expr.Type);
eclass = ExprClass.Variable;
loc = l;
}
static int PtrTypeSize (Type t)
{
- return GetTypeSize (t.GetElementType ());
+ return GetTypeSize (TypeManager.GetElementType (t));
}
//
{
Type op_type = left.Type;
ILGenerator ig = ec.ig;
- int size = GetTypeSize (op_type.GetElementType ());
+ int size = GetTypeSize (TypeManager.GetElementType (op_type));
Type rtype = right.Type;
if (rtype.IsPointer){
if (candidate_pd.ParameterModifier (j) == Parameter.Modifier.PARAMS)
if (expanded_form)
- t = t.GetElementType ();
+ t = TypeManager.GetElementType (t);
x = BetterConversion (ec, a, t, null, loc);
if (candidate_pd.ParameterModifier (j) == Parameter.Modifier.PARAMS)
if (expanded_form)
- ct = ct.GetElementType ();
+ ct = TypeManager.GetElementType (ct);
if (best_pd.ParameterModifier (j) == Parameter.Modifier.PARAMS)
if (expanded_form)
- bt = bt.GetElementType ();
+ bt = TypeManager.GetElementType (bt);
x = BetterConversion (ec, a, ct, bt, loc);
y = BetterConversion (ec, a, bt, ct, loc);
}
- Type element_type = pd.ParameterType (pd_count - 1).GetElementType ();
+ Type element_type = TypeManager.GetElementType (pd.ParameterType (pd_count - 1));
for (int i = pd_count - 1; i < arg_count; i++) {
Argument a = (Argument) arguments [i];
if (arg_count != pd.Count)
return false;
-
+
for (int i = arg_count; i > 0; ) {
i--;
if (a_mod == p_mod ||
(a_mod == Parameter.Modifier.NONE && p_mod == Parameter.Modifier.PARAMS)) {
- if (a_mod == Parameter.Modifier.NONE)
- if (!Convert.ImplicitConversionExists (ec, a.Expr, pd.ParameterType (i)))
+ if (a_mod == Parameter.Modifier.NONE) {
+ if (!Convert.ImplicitConversionExists (ec,
+ a.Expr, pd.ParameterType (i)))
return false;
+ }
if ((a_mod & Parameter.Modifier.ISBYREF) != 0) {
Type pt = pd.ParameterType (i);
ArrayList Arguments, Location loc)
{
MethodBase method = null;
- Type current_type = null;
+ Type applicable_type = null;
int argument_count;
ArrayList candidates = new ArrayList ();
-
- foreach (MethodBase candidate in me.Methods){
- int x;
+ //
+ // First we construct the set of applicable methods
+ //
+
+ //
+ // We start at the top of the type hierarchy and
+ // go down to find applicable methods
+ //
+ applicable_type = me.DeclaringType;
+
+ bool found_applicable = false;
+ foreach (MethodBase candidate in me.Methods) {
+ Type decl_type = candidate.DeclaringType;
+
+ //
+ // If we have already found an applicable method
+ // we eliminate all base types (Section 14.5.5.1)
+ //
+ if (decl_type != applicable_type &&
+ (applicable_type.IsSubclassOf (decl_type) ||
+ TypeManager.ImplementsInterface (applicable_type, decl_type)) &&
+ found_applicable)
+ continue;
- // If we're going one level higher in the class hierarchy, abort if
- // we already found an applicable method.
- if (candidate.DeclaringType != current_type) {
- current_type = candidate.DeclaringType;
- if (method != null)
- break;
- }
// Check if candidate is applicable (section 14.4.2.1)
if (!IsApplicable (ec, Arguments, candidate))
continue;
+
candidates.Add (candidate);
- x = BetterFunction (ec, Arguments, candidate, method, false, loc);
-
- if (x == 0)
- continue;
+ applicable_type = candidate.DeclaringType;
+ found_applicable = true;
- method = candidate;
}
+
+ //
+ // Now we actually find the best method
+ //
+ foreach (MethodBase candidate in candidates) {
+ int x = BetterFunction (ec, Arguments, candidate, method, false, loc);
+
+ if (x == 0)
+ continue;
+
+ method = candidate;
+ }
+
+
if (Arguments == null)
argument_count = 0;
else
argument_count = Arguments.Count;
//
- // Now we see if we can find params functions, applicable in their expanded form
- // since if they were applicable in their normal form, they would have been selected
- // above anyways
+ // Now we see if we can find params functions,
+ // applicable in their expanded form since if
+ // they were applicable in their normal form,
+ // they would have been selected above anyways
//
bool chose_params_expanded = false;
continue;
//
- // If a normal method is applicable in the sense that it has the same
- // number of arguments, then the expanded params method is never applicable
- // so we debar the params method.
+ // If a normal method is applicable in
+ // the sense that it has the same
+ // number of arguments, then the
+ // expanded params method is never
+ // applicable so we debar the params
+ // method.
//
- if (IsParamsMethodApplicable (ec, Arguments, candidate) &&
+
+ if (IsParamsMethodApplicable (ec, Arguments, candidate) &&
IsApplicable (ec, Arguments, method))
continue;
}
//
- // And now check if the arguments are all compatible, perform conversions
- // if necessary etc. and return if everything is all right
+ // And now check if the arguments are all
+ // compatible, perform conversions if
+ // necessary etc. and return if everything is
+ // all right
//
if (!VerifyArgumentsCompat (ec, Arguments, argument_count, method,
}
if (chose_params_expanded)
- parameter_type = TypeManager.TypeToCoreType (parameter_type.GetElementType ());
+ parameter_type = TypeManager.GetElementType (parameter_type);
} else {
//
// Check modifiers
conv = Convert.ImplicitConversion (ec, a_expr, parameter_type, loc);
if (conv == null) {
+ Console.WriteLine ("GAA: {0} {1} {2}",
+ pd.ParameterType (j),
+ pd.ParameterType (j).Assembly == CodeGen.AssemblyBuilder,
+ method.DeclaringType.Assembly == CodeGen.AssemblyBuilder);
+
if (!Location.IsNull (loc))
Error_InvalidArguments (
loc, j, method, delegate_type,
ILGenerator ig = ec.ig;
IntConstant.EmitInt (ig, 0);
- ig.Emit (OpCodes.Newarr, pd.ParameterType (0).GetElementType ());
+ ig.Emit (OpCodes.Newarr, TypeManager.GetElementType (pd.ParameterType (0)));
}
return;
ILGenerator ig = ec.ig;
IntConstant.EmitInt (ig, 0);
- ig.Emit (OpCodes.Newarr, pd.ParameterType (top).GetElementType ());
+ ig.Emit (OpCodes.Newarr, TypeManager.GetElementType (pd.ParameterType (top)));
}
}
underlying_type = type;
if (underlying_type.IsArray)
- underlying_type = TypeManager.TypeToCoreType (underlying_type.GetElementType ());
+ underlying_type = TypeManager.GetElementType (underlying_type);
dimensions = type.GetArrayRank ();
return true;
}
}
- array_element_type = TypeManager.TypeToCoreType (type.GetElementType ());
+ array_element_type = TypeManager.GetElementType (type);
if (arg_count == 1) {
is_one_dimensional = true;
ea.Arguments.Count);
return null;
}
- type = TypeManager.TypeToCoreType (t.GetElementType ());
- if (type.IsPointer && !ec.InUnsafe){
+
+ type = TypeManager.GetElementType (t);
+ if (type.IsPointer && !ec.InUnsafe){
UnsafeError (ea.Location);
return null;
}
public ArrayPtr (Expression array, Location l)
{
- Type array_type = array.Type.GetElementType ();
+ Type array_type = TypeManager.GetElementType (array.Type);
this.array = array;
array.Emit (ec);
IntLiteral.EmitInt (ig, 0);
- ig.Emit (OpCodes.Ldelema, array.Type.GetElementType ());
+ ig.Emit (OpCodes.Ldelema, TypeManager.GetElementType (array.Type));
}
public override Expression DoResolve (EmitContext ec)
Report.Error (1536, l, "`void' parameter is not permitted");
return false;
}
-
+
return parameter_type != null;
}
if (impl_details_class == null){
impl_details_class = CodeGen.ModuleBuilder.DefineType (
- "<PrivateImplementationDetails>", TypeAttributes.NotPublic, TypeManager.object_type);
+ "<PrivateImplementationDetails>",
+ TypeAttributes.NotPublic,
+ TypeManager.object_type);
+
RegisterHelperClass (impl_details_class);
}
continue;
VariableNames [i] = ip.ParameterName (i);
- VariableTypes [i] = ip.ParameterType (i).GetElementType ();
+ VariableTypes [i] = TypeManager.GetElementType (ip.ParameterType (i));
map [i] = new VariableInfo (VariableNames [i], VariableTypes [i], i, Length);
Length += map [i].Length;
// but the fact is that you would not be able to use the pointer variable
// *anyways*
//
- if (!TypeManager.VerifyUnManaged (variable_type.GetElementType (), vi.Location))
+ if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (variable_type),
+ vi.Location))
continue;
}
// Case 2: Array
//
if (e.Type.IsArray){
- Type array_type = e.Type.GetElementType ();
+ Type array_type = TypeManager.GetElementType (e.Type);
vi.MakePinned ();
//
if (expr.Type.IsArray) {
array_type = expr.Type;
- element_type = array_type.GetElementType ();
+ element_type = TypeManager.GetElementType (array_type);
empty = new EmptyExpression (element_type);
} else {
Type partype = ParameterType (pos);
if (partype.IsByRef){
- partype = partype.GetElementType ();
+ partype = TypeManager.GetElementType (partype);
if (pi [pos].IsOut)
sb.Append ("out ");
else
foreach (ModuleBuilder mb in modules) {
t = mb.GetType (name);
- if (t != null){
+ if (t != null)
return t;
- }
}
+
return null;
}
private static MemberList MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
string name, out bool used_cache)
{
+ bool not_loaded_corlib = (t.Assembly == CodeGen.AssemblyBuilder);
+
//
// We have to take care of arrays specially, because GetType on
// a TypeBuilder array will return a Type, not a TypeBuilder,
return false;
}
+ //
+ // Do the right thing when returning the element type of
+ // an array type based on whether we
+ //
+ public static Type GetElementType (Type t)
+ {
+ if (RootContext.StdLib)
+ return t.GetElementType ();
+ else
+ return TypeToCoreType (t.GetElementType ());
+ }
+
/// <summary>
/// Returns the User Defined Types
/// </summary>
return true;
}
- static public bool RegisterIndexer (PropertyBuilder pb, MethodBase get, MethodBase set, Type[] args)
+ static public bool RegisterIndexer (PropertyBuilder pb, MethodBase get,
+ MethodBase set, Type[] args)
{
if (!RegisterProperty (pb, get,set))
return false;
mt &= (MemberTypes.Method | MemberTypes.Constructor);
} while (searching);
- if (method_list != null && method_list.Count > 0)
- return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
-
+ if (method_list != null && method_list.Count > 0) {
+ return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
+ }
//
// This happens if we already used the cache in the first iteration, in this case
// the cache already looked in all interfaces.