else if (t == TypeManager.bool_type)
return new BoolConstant ((bool) v);
else if (TypeManager.IsEnumType (t)){
- Constant e = Constantify (v, TypeManager.TypeToCoreType (v.GetType ()));
+ Type real_type = TypeManager.TypeToCoreType (v.GetType ());
+ if (real_type == t)
+ real_type = real_type.UnderlyingSystemType;
+
+ Constant e = Constantify (v, real_type);
return new EnumConstant (e, t);
} else
//
Block current_block = ec.CurrentBlock;
if (current_block != null){
+ if (is_base && current_block.IsVariableNameUsedInChildBlock(Name)) {
+ Report.Error (135, Location, "'" + Name + "' has a different meaning in a child block");
+ return null;
+ }
+
LocalInfo vi = current_block.GetLocalInfo (Name);
if (vi != null){
Expression var;
IMemoryLocation ml = (IMemoryLocation) instance_expr;
ml.AddressOf (ec, AddressOp.LoadStore);
- } else
+ } else {
instance_expr.Emit (ec);
+
+ if (instance_expr.Type.IsValueType) {
+ LocalBuilder local = ig.DeclareLocal (instance_expr.Type);
+ ig.Emit(OpCodes.Stloc, local);
+ ig.Emit(OpCodes.Ldloca, local);
+ ig.Emit(OpCodes.Ldfld, FieldInfo);
+ LocalBuilder local2 = ig.DeclareLocal(type);
+ ig.Emit(OpCodes.Stloc, local2);
+ ig.Emit(OpCodes.Ldloca, local2);
+ return;
+ }
+ }
ig.Emit (OpCodes.Ldflda, FieldInfo);
}
}
return true;
}
- MethodInfo GetAccessor (Type invocation_type, string accessor_name)
+ MethodInfo FindAccessor (Type invocation_type, bool is_set)
{
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.Static | BindingFlags.Instance;
- MemberInfo[] group;
+ BindingFlags.Static | BindingFlags.Instance |
+ BindingFlags.DeclaredOnly;
- group = TypeManager.MemberLookup (
- invocation_type, invocation_type, PropertyInfo.DeclaringType,
- MemberTypes.Method, flags, accessor_name + "_" + PropertyInfo.Name);
+ Type current = PropertyInfo.DeclaringType;
+ for (; current != null; current = current.BaseType) {
+ MemberInfo[] group = TypeManager.MemberLookup (
+ invocation_type, invocation_type, current,
+ MemberTypes.Property, flags, PropertyInfo.Name);
- //
- // The first method is the closest to us
- //
- if (group == null)
+ if (group == null)
+ continue;
+
+ if (group.Length != 1)
+ // Oooops, can this ever happen ?
+ return null;
+
+ PropertyInfo pi = (PropertyInfo) group [0];
+
+ MethodInfo get = pi.GetGetMethod (true);
+ MethodInfo set = pi.GetSetMethod (true);
+
+ if (is_set) {
+ if (set != null)
+ return set;
+ } else {
+ if (get != null)
+ return get;
+ }
+
+ MethodInfo accessor = get != null ? get : set;
+ if (accessor == null)
+ continue;
+ if ((accessor.Attributes & MethodAttributes.NewSlot) != 0)
+ break;
+ }
+
+ return null;
+ }
+
+ MethodInfo GetAccessor (Type invocation_type, bool is_set)
+ {
+ MethodInfo mi = FindAccessor (invocation_type, is_set);
+ if (mi == null)
return null;
- foreach (MethodInfo mi in group) {
- MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
+ MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
- //
- // If only accessible to the current class or children
- //
- if (ma == MethodAttributes.Private) {
- Type declaring_type = mi.DeclaringType;
+ //
+ // If only accessible to the current class or children
+ //
+ if (ma == MethodAttributes.Private) {
+ Type declaring_type = mi.DeclaringType;
- if (invocation_type != declaring_type){
- if (TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
- return mi;
- else
- continue;
- } else
+ if (invocation_type != declaring_type){
+ if (TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
return mi;
- }
- //
- // FamAndAssem requires that we not only derivate, but we are on the
- // same assembly.
- //
- if (ma == MethodAttributes.FamANDAssem){
- if (mi.DeclaringType.Assembly != invocation_type.Assembly)
- continue;
else
- return mi;
- }
+ return null;
+ } else
+ return mi;
+ }
+ //
+ // FamAndAssem requires that we not only derivate, but we are on the
+ // same assembly.
+ //
+ if (ma == MethodAttributes.FamANDAssem){
+ if (mi.DeclaringType.Assembly != invocation_type.Assembly)
+ return null;
+ else
+ return mi;
+ }
- // Assembly and FamORAssem succeed if we're in the same assembly.
- if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
- if (mi.DeclaringType.Assembly == invocation_type.Assembly)
- return mi;
- }
+ // Assembly and FamORAssem succeed if we're in the same assembly.
+ if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
+ if (mi.DeclaringType.Assembly == invocation_type.Assembly)
+ return mi;
+ }
- // We already know that we aren't in the same assembly.
- if (ma == MethodAttributes.Assembly)
- continue;
+ // We already know that we aren't in the same assembly.
+ if (ma == MethodAttributes.Assembly)
+ return null;
- // Family and FamANDAssem require that we derive.
- if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
- if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
- continue;
- else {
+ // Family and FamANDAssem require that we derive.
+ if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
+ if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
+ return null;
+ else {
+ if (!TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType))
must_do_cs1540_check = true;
- return mi;
- }
+ return mi;
}
-
- return mi;
}
- return null;
+ return mi;
}
//
//
void ResolveAccessors (EmitContext ec)
{
- getter = GetAccessor (ec.ContainerType, "get");
+ getter = GetAccessor (ec.ContainerType, false);
if ((getter != null) && getter.IsStatic)
is_static = true;
- setter = GetAccessor (ec.ContainerType, "set");
+ setter = GetAccessor (ec.ContainerType, true);
if ((setter != null) && setter.IsStatic)
is_static = true;
override public Expression DoResolve (EmitContext ec)
{
+ if (getter != null){
+ if (TypeManager.GetArgumentTypes (getter).Length != 0){
+ Report.Error (
+ 117, loc, "`{0}' does not contain a " +
+ "definition for `{1}'.", getter.DeclaringType,
+ Name);
+ return null;
+ }
+ }
+
if (getter == null){
//
// The following condition happens if the PropertyExpr was
return null;
}
+ if (TypeManager.GetArgumentTypes (setter).Length != 1){
+ Report.Error (
+ 117, loc, "`{0}' does not contain a " +
+ "definition for `{1}'.", getter.DeclaringType,
+ Name);
+ return null;
+ }
+
if (!InstanceResolve (ec))
return null;