int count = mi.Length;
- if (count > 1)
- return new MethodGroupExpr (mi, loc);
-
if (mi [0] is MethodBase)
return new MethodGroupExpr (mi, loc);
+ if (count > 1)
+ return null;
+
return ExprClassFromMemberInfo (ec, mi [0], loc);
}
if (expr_type.IsValueType)
return new BoxedCast (expr);
- if (expr_type.IsClass || expr_type.IsInterface)
+ if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type)
return new EmptyCast (expr, target_type);
} else if (expr_type.IsSubclassOf (target_type)) {
//
//
if (expr_type.IsEnum)
return new BoxedCast (expr);
-
+
return new EmptyCast (expr, target_type);
} else {
// from the null type to any reference-type.
if (expr is NullLiteral && !target_type.IsValueType)
- return new EmptyCast (expr, target_type);
+ return new NullLiteralTyped (target_type);
// from any class-type S to any interface-type T.
if (target_type.IsInterface) {
return new EmptyCast (expr, target_type);
// from any delegate type to System.Delegate
- if (expr_type.IsSubclassOf (TypeManager.delegate_type) &&
+ if ((expr_type == TypeManager.delegate_type ||
+ expr_type.IsSubclassOf (TypeManager.delegate_type)) &&
target_type == TypeManager.delegate_type)
return new EmptyCast (expr, target_type);
// from any array-type or delegate type into System.ICloneable.
- if (expr_type.IsArray || expr_type.IsSubclassOf (TypeManager.delegate_type))
+ if (expr_type.IsArray ||
+ expr_type == TypeManager.delegate_type ||
+ expr_type.IsSubclassOf (TypeManager.delegate_type))
if (target_type == TypeManager.icloneable_type)
return new EmptyCast (expr, target_type);
//
// Attempt to do the implicit constant expression conversions
- if (expr is IntConstant){
- Expression e;
+ if (expr is Constant){
- e = TryImplicitIntConversion (target_type, (IntConstant) expr);
-
- if (e != null)
- return e;
- } else if (expr is LongConstant && target_type == TypeManager.uint64_type){
- //
- // Try the implicit constant expression conversion
- // from long to ulong, instead of a nice routine,
- // we just inline it
- //
- long v = ((LongConstant) expr).Value;
- if (v > 0)
- return new ULongConstant ((ulong) v);
+ if (expr is IntConstant){
+ Expression e;
+
+ e = TryImplicitIntConversion (target_type, (IntConstant) expr);
+
+ if (e != null)
+ return e;
+ } else if (expr is LongConstant && target_type == TypeManager.uint64_type){
+ //
+ // Try the implicit constant expression conversion
+ // from long to ulong, instead of a nice routine,
+ // we just inline it
+ //
+ long v = ((LongConstant) expr).Value;
+ if (v > 0)
+ return new ULongConstant ((ulong) v);
+ }
}
-
+
Type real_target_type = target_type;
if (expr_type == TypeManager.sbyte_type){
// This is the boxed case.
//
if (target_type == TypeManager.object_type) {
- if ((expr_type.IsClass) ||
- (expr_type.IsValueType) ||
- (expr_type.IsInterface))
+ if (expr_type.IsClass || expr_type.IsValueType ||
+ expr_type.IsInterface || expr_type == TypeManager.enum_type)
return true;
-
} else if (expr_type.IsSubclassOf (target_type)) {
return true;
} else {
return true;
// from any delegate type to System.Delegate
- if (expr_type.IsSubclassOf (TypeManager.delegate_type) &&
+ if ((expr_type == TypeManager.delegate_type ||
+ expr_type.IsSubclassOf (TypeManager.delegate_type)) &&
target_type == TypeManager.delegate_type)
if (target_type.IsAssignableFrom (expr_type))
return true;
// from any array-type or delegate type into System.ICloneable.
- if (expr_type.IsArray || expr_type.IsSubclassOf (TypeManager.delegate_type))
+ if (expr_type.IsArray ||
+ expr_type == TypeManager.delegate_type ||
+ expr_type.IsSubclassOf (TypeManager.delegate_type))
if (target_type == TypeManager.icloneable_type)
return true;
return true;
}
- if (target_type.IsSubclassOf (TypeManager.enum_type) && expr is IntLiteral){
+ if ((target_type == TypeManager.enum_type ||
+ target_type.IsSubclassOf (TypeManager.enum_type)) &&
+ expr is IntLiteral){
IntLiteral i = (IntLiteral) expr;
if (i.Value == 0)
int count = 0;
+
foreach (MethodBase mb in union.Methods){
ParameterData pd = Invocation.GetParameterData (mb);
MethodInfo mi = (MethodInfo) mb;
e = ConvertImplicitStandard (ec, e, target, loc);
else
e = ConvertExplicitStandard (ec, e, target, loc);
- }
+ }
+
return e;
}
e = ImplicitReferenceConversion (expr, target_type);
if (e != null)
return e;
-
- if (target_type.IsSubclassOf (TypeManager.enum_type) && expr is IntLiteral){
+
+ if ((target_type == TypeManager.enum_type ||
+ target_type.IsSubclassOf (TypeManager.enum_type)) &&
+ expr is IntLiteral){
IntLiteral i = (IntLiteral) expr;
if (i.Value == 0)
- return new EmptyCast (expr, target_type);
+ return new EnumConstant ((Constant) expr, target_type);
}
if (ec.InUnsafe) {
// t1 == t2, we have to compare their element types.
//
if (target_type.IsPointer){
- if (target_type.GetElementType()==expr_type.GetElementType())
+ if (target_type.GetElementType() == expr_type.GetElementType())
return expr;
}
}
- if (target_type.IsPointer){
+ if (target_type.IsPointer) {
if (expr is NullLiteral)
return new EmptyCast (expr, target_type);
+
+ if (expr_type == TypeManager.void_ptr_type)
+ return new EmptyCast (expr, target_type);
}
}
{
int value = ic.Value;
- //
- // FIXME: This could return constants instead of EmptyCasts
- //
if (target_type == TypeManager.sbyte_type){
if (value >= SByte.MinValue && value <= SByte.MaxValue)
return new SByteConstant ((sbyte) value);
/// </summary>
public class EmptyCast : Expression {
protected Expression child;
-
+
public EmptyCast (Expression child, Type return_type)
{
eclass = child.eclass;
this.child = child;
}
- public Expression Peel ()
- {
- if (child is EmptyCast)
- return ((EmptyCast) child).Peel ();
- return child;
- }
-
public override Expression DoResolve (EmitContext ec)
{
// This should never be invoked, we are born in fully
public class BoxedCast : EmptyCast {
public BoxedCast (Expression expr)
- : base (expr, TypeManager.object_type)
+ : base (expr, TypeManager.object_type)
{
}
-
+
public override Expression DoResolve (EmitContext ec)
{
// This should never be invoked, we are born in fully
/// </remarks>
public class SimpleName : Expression, ITypeExpression {
public readonly string Name;
+
+ //
+ // If true, then we are a simple name, not composed with a ".
+ //
+ bool is_base;
+
+ public SimpleName (string a, string b, Location l)
+ {
+ Name = String.Concat (a, ".", b);
+ loc = l;
+ is_base = false;
+ }
public SimpleName (string name, Location l)
{
Name = name;
loc = l;
+ is_base = true;
}
public static void Error_ObjectRefRequired (EmitContext ec, Location l, string name)
public Expression DoResolveType (EmitContext ec)
{
- //
- // Stage 3: Lookup symbol in the various namespaces.
- //
DeclSpace ds = ec.DeclSpace;
+ Namespace ns = ds.Namespace;
Type t;
string alias_value;
+ //
+ // Since we are cheating: we only do the Alias lookup for
+ // namespaces if the name does not include any dots in it
+ //
+ if (ns != null && is_base)
+ alias_value = ns.LookupAlias (Name);
+ else
+ alias_value = null;
+
if (ec.ResolvingTypeTree){
+ if (alias_value != null){
+ if ((t = RootContext.LookupType (ds, alias_value, true, loc)) != null)
+ return new TypeExpr (t, loc);
+ }
+
int errors = Report.Errors;
Type dt = ec.DeclSpace.FindType (loc, Name);
if (Report.Errors != errors)
return new TypeExpr (dt, loc);
}
- if ((t = RootContext.LookupType (ds, Name, true, loc)) != null)
- return new TypeExpr (t, loc);
-
-
- //
- // Stage 2 part b: Lookup up if we are an alias to a type
- // or a namespace.
//
- // Since we are cheating: we only do the Alias lookup for
- // namespaces if the name does not include any dots in it
+ // First, the using aliases
//
-
- alias_value = ec.DeclSpace.LookupAlias (Name);
-
- if (Name.IndexOf ('.') == -1 && alias_value != null) {
+ if (alias_value != null){
if ((t = RootContext.LookupType (ds, alias_value, true, loc)) != null)
return new TypeExpr (t, loc);
-
+
// we have alias value, but it isn't Type, so try if it's namespace
return new SimpleName (alias_value, loc);
}
+
+ //
+ // Stage 2: Lookup up if we are an alias to a type
+ // or a namespace.
+ //
+
+ if ((t = RootContext.LookupType (ds, Name, true, loc)) != null)
+ return new TypeExpr (t, loc);
// No match, maybe our parent can compose us
// into something meaningful.
{
if (!FieldInfo.IsStatic){
if (instance_expr == null){
- throw new Exception ("non-static FieldExpr without instance var\n" +
- "You have to assign the Instance variable\n" +
- "Of the FieldExpr to set this\n");
+ //
+ // This can happen when referencing an instance field using
+ // a fully qualified type expression: TypeName.InstanceField = xxx
+ //
+ SimpleName.Error_ObjectRefRequired (ec, loc, FieldInfo.Name);
+ return null;
}
// Resolve the field's instance expression while flow analysis is turned
// InitOnly fields can only be assigned in constructors
//
- if (ec.IsConstructor)
- return this;
+ if (ec.IsConstructor){
+ if (ec.ContainerType == FieldInfo.DeclaringType)
+ return this;
+ }
Report_AssignToReadonly (true);
if (FieldInfo.IsStatic)
ig.Emit (OpCodes.Ldsflda, FieldInfo);
else {
- if (instance_expr is IMemoryLocation)
- ((IMemoryLocation)instance_expr).AddressOf (ec, AddressOp.LoadStore);
+ //
+ // In the case of `This', we call the AddressOf method, which will
+ // only load the pointer, and not perform an Ldobj immediately after
+ // the value has been loaded into the stack.
+ //
+ if (instance_expr is This)
+ ((This)instance_expr).AddressOf (ec, AddressOp.LoadStore);
else
instance_expr.Emit (ec);
ig.Emit (OpCodes.Ldflda, FieldInfo);