X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fecore.cs;h=743b255c62697aaa352b5ec0018ebccd130bb2b8;hb=9076dfdec8582c59a2c683da9943496514f8d2dd;hp=5aab354514ea9add7a8939c86f824fc9a04f58f6;hpb=47a64096c98492f6f512cf46baf4525e71aa7ba1;p=mono.git
diff --git a/mcs/gmcs/ecore.cs b/mcs/gmcs/ecore.cs
index 5aab354514e..743b255c626 100755
--- a/mcs/gmcs/ecore.cs
+++ b/mcs/gmcs/ecore.cs
@@ -61,7 +61,10 @@ namespace Mono.CSharp {
// Disable control flow analysis while resolving the expression.
// This is used when resolving the instance expression of a field expression.
- DisableFlowAnalysis = 16
+ DisableFlowAnalysis = 16,
+
+ // Set if this is resolving the first part of a MemberAccess.
+ Intermediate = 32
}
//
@@ -92,6 +95,25 @@ namespace Mono.CSharp {
void AddressOf (EmitContext ec, AddressOp mode);
}
+ ///
+ /// We are either a namespace or a type.
+ /// If we're a type, `IsType' is true and we may use `Type' to get
+ /// a TypeExpr representing that type.
+ ///
+ public interface IAlias {
+ bool IsType {
+ get;
+ }
+
+ string Name {
+ get;
+ }
+
+ TypeExpr Type {
+ get;
+ }
+ }
+
///
/// This interface is implemented by variables
///
@@ -184,22 +206,21 @@ namespace Mono.CSharp {
///
/// Utility wrapper routine for Warning, just to beautify the code
///
- public void Warning (int warning, string s)
+ public void Warning (int code, string format, params object[] args)
{
- if (!Location.IsNull (loc))
- Report.Warning (warning, loc, s);
- else
- Report.Warning (warning, s);
+ Report.Warning (code, loc, format, args);
}
///
- /// Utility wrapper routine for Warning, only prints the warning if
- /// warnings of level `level' are enabled.
+ /// Tests presence of ObsoleteAttribute and report proper error
///
- public void Warning (int warning, int level, string s)
+ protected void CheckObsoleteAttribute (Type type)
{
- if (level <= RootContext.WarningLevel)
- Warning (warning, s);
+ ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type);
+ if (obsolete_attr == null)
+ return;
+
+ AttributeTester.Report_ObsoleteMessage (obsolete_attr, type.FullName, loc);
}
///
@@ -274,8 +295,10 @@ namespace Mono.CSharp {
ec.DoFlowAnalysis = false;
Expression e;
+ bool intermediate = (flags & ResolveFlags.Intermediate) == ResolveFlags.Intermediate;
if (this is SimpleName)
- e = ((SimpleName) this).DoResolveAllowStatic (ec);
+ e = ((SimpleName) this).DoResolveAllowStatic (ec, intermediate);
+
else
e = DoResolve (ec);
@@ -289,7 +312,7 @@ namespace Mono.CSharp {
if ((flags & ResolveFlags.SimpleName) == 0) {
MemberLookupFailed (ec, null, ec.ContainerType, s.Name,
- 0, ec.DeclSpace.Name, loc);
+ ec.DeclSpace.Name, loc);
return null;
}
@@ -376,7 +399,7 @@ namespace Mono.CSharp {
if (e is SimpleName){
SimpleName s = (SimpleName) e;
MemberLookupFailed (ec, null, ec.ContainerType, s.Name,
- 0, ec.DeclSpace.Name, loc);
+ ec.DeclSpace.Name, loc);
return null;
}
@@ -466,7 +489,11 @@ namespace Mono.CSharp {
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
@@ -492,6 +519,9 @@ namespace Mono.CSharp {
return null;
}
+
+ private static ArrayList almostMatchedMembers = new ArrayList (4);
+
//
// FIXME: Probably implement a cache for (t,name,current_access_set)?
//
@@ -523,7 +553,7 @@ namespace Mono.CSharp {
public static Expression MemberLookup (EmitContext ec, Type queried_type, string name,
MemberTypes mt, BindingFlags bf, Location loc)
{
- return MemberLookup (ec, ec.ContainerType, null, queried_type, name, 0, mt, bf, loc);
+ return MemberLookup (ec, ec.ContainerType, null, queried_type, name, mt, bf, loc);
}
//
@@ -533,13 +563,14 @@ namespace Mono.CSharp {
public static Expression MemberLookup (EmitContext ec, Type container_type,
Type qualifier_type, Type queried_type,
- string name, int num_type_arguments,
- MemberTypes mt, BindingFlags bf,
- Location loc)
+ string name, MemberTypes mt,
+ BindingFlags bf, Location loc)
{
- MemberInfo [] mi = TypeManager.MemberLookup (container_type, qualifier_type,
- queried_type, num_type_arguments,
- mt, bf, name);
+ almostMatchedMembers.Clear ();
+
+ MemberInfo [] mi = TypeManager.MemberLookup (
+ container_type, qualifier_type,queried_type, mt, bf, name,
+ almostMatchedMembers);
if (mi == null)
return null;
@@ -568,34 +599,25 @@ namespace Mono.CSharp {
BindingFlags.Static |
BindingFlags.Instance;
- public static Expression MemberLookup (EmitContext ec, Type queried_type,
- string name, int num_type_arguments,
- Location loc)
- {
- return MemberLookup (ec, ec.ContainerType, null, queried_type, name,
- num_type_arguments, AllMemberTypes, AllBindingFlags,
- loc);
- }
-
public static Expression MemberLookup (EmitContext ec, Type queried_type,
string name, Location loc)
{
return MemberLookup (ec, ec.ContainerType, null, queried_type, name,
- 0, AllMemberTypes, AllBindingFlags, loc);
+ AllMemberTypes, AllBindingFlags, loc);
}
public static Expression MemberLookup (EmitContext ec, Type qualifier_type,
Type queried_type, string name, Location loc)
{
return MemberLookup (ec, ec.ContainerType, qualifier_type, queried_type,
- name, 0, AllMemberTypes, AllBindingFlags, loc);
+ name, AllMemberTypes, AllBindingFlags, loc);
}
public static Expression MethodLookup (EmitContext ec, Type queried_type,
string name, Location loc)
{
return MemberLookup (ec, ec.ContainerType, null, queried_type, name,
- 0, MemberTypes.Method, AllBindingFlags, loc);
+ MemberTypes.Method, AllBindingFlags, loc);
}
///
@@ -606,45 +628,68 @@ namespace Mono.CSharp {
///
public static Expression MemberLookupFinal (EmitContext ec, Type qualifier_type,
Type queried_type, string name,
- int num_type_arguments, Location loc)
+ Location loc)
{
return MemberLookupFinal (ec, qualifier_type, queried_type, name,
- num_type_arguments, AllMemberTypes,
- AllBindingFlags, loc);
+ AllMemberTypes, AllBindingFlags, loc);
}
public static Expression MemberLookupFinal (EmitContext ec, Type qualifier_type,
Type queried_type, string name,
- int num_type_arguments, MemberTypes mt,
- BindingFlags bf, Location loc)
+ MemberTypes mt, BindingFlags bf,
+ Location loc)
{
Expression e;
int errors = Report.Errors;
e = MemberLookup (ec, ec.ContainerType, qualifier_type, queried_type,
- name, num_type_arguments, mt, bf, loc);
-
- if (e != null)
- return e;
+ name, mt, bf, loc);
- // Error has already been reported.
- if (errors < Report.Errors)
- return null;
+ if (e == null && errors == Report.Errors)
+ // No errors were reported by MemberLookup, but there was an error.
+ MemberLookupFailed (ec, qualifier_type, queried_type, name,
+ null, loc);
- MemberLookupFailed (ec, qualifier_type, queried_type, name,
- num_type_arguments, null, loc);
- return null;
+ return e;
}
public static void MemberLookupFailed (EmitContext ec, Type qualifier_type,
Type queried_type, string name,
- int num_type_arguments, string class_name,
- Location loc)
- {
+ string class_name, Location loc)
+ {
+ if (almostMatchedMembers.Count != 0) {
+ if (qualifier_type == null) {
+ foreach (MemberInfo m in almostMatchedMembers)
+ Report.Error (38, loc,
+ "Cannot access non-static member `{0}' via nested type `{1}'",
+ TypeManager.GetFullNameSignature (m),
+ TypeManager.CSharpName (ec.ContainerType));
+ return;
+ }
+
+
+ if (qualifier_type != ec.ContainerType) {
+ // Although a derived class can access protected members of
+ // its base class it cannot do so through an instance of the
+ // base class (CS1540). If the qualifier_type is a parent of the
+ // ec.ContainerType and the lookup succeeds with the latter one,
+ // then we are in this situation.
+ foreach (MemberInfo m in almostMatchedMembers)
+ Report.Error (1540, loc,
+ "Cannot access protected member `{0}' via a qualifier of type `{1}';"
+ + " the qualifier must be of type `{2}' (or derived from it)",
+ TypeManager.GetFullNameSignature (m),
+ TypeManager.CSharpName (qualifier_type),
+ TypeManager.CSharpName (ec.ContainerType));
+ return;
+ }
+ almostMatchedMembers.Clear ();
+ }
+
MemberInfo[] mi = TypeManager.MemberLookup (queried_type, null, queried_type,
- -1, AllMemberTypes, AllBindingFlags |
- BindingFlags.NonPublic, name);
+ AllMemberTypes, AllBindingFlags |
+ BindingFlags.NonPublic, name, null);
if (mi == null) {
if (class_name != null)
@@ -658,8 +703,8 @@ namespace Mono.CSharp {
}
if (TypeManager.MemberLookup (queried_type, null, queried_type,
- 0, AllMemberTypes, AllBindingFlags |
- BindingFlags.NonPublic, name) == null) {
+ AllMemberTypes, AllBindingFlags |
+ BindingFlags.NonPublic, name, null) == null) {
if ((mi.Length == 1) && (mi [0] is Type)) {
Type t = (Type) mi [0];
@@ -672,42 +717,15 @@ namespace Mono.CSharp {
}
}
- if ((qualifier_type != null) && (qualifier_type != ec.ContainerType) &&
- ec.ContainerType.IsSubclassOf (qualifier_type)) {
- // Although a derived class can access protected members of
- // its base class it cannot do so through an instance of the
- // base class (CS1540). If the qualifier_type is a parent of the
- // ec.ContainerType and the lookup succeeds with the latter one,
- // then we are in this situation.
- mi = TypeManager.MemberLookup (
- ec.ContainerType, ec.ContainerType, ec.ContainerType,
- 0, AllMemberTypes, AllBindingFlags, name);
-
- if (mi != null) {
- Report.Error (
- 1540, loc, "Cannot access protected member `" +
- TypeManager.CSharpName (qualifier_type) + "." +
- name + "' " + "via a qualifier of type `" +
- TypeManager.CSharpName (qualifier_type) + "'; the " +
- "qualifier must be of type `" +
- TypeManager.CSharpName (ec.ContainerType) + "' " +
- "(or derived from it)");
- return;
- }
- }
if (qualifier_type != null)
- Report.Error (
- 122, loc, "`" + TypeManager.CSharpName (qualifier_type) + "." +
- name + "' is inaccessible due to its protection level");
+ Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", TypeManager.CSharpName (qualifier_type) + "." + name);
else if (name == ".ctor") {
Report.Error (143, loc, String.Format ("The type {0} has no constructors defined",
TypeManager.CSharpName (queried_type)));
} else {
- Report.Error (
- 122, loc, "`" + name + "' is inaccessible due to its " +
- "protection level");
+ Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", name);
}
}
@@ -747,7 +765,8 @@ namespace Mono.CSharp {
ArrayList arguments = new ArrayList ();
arguments.Add (new Argument (e, Argument.AType.Expression));
- method = Invocation.OverloadResolve (ec, (MethodGroupExpr) operator_group, arguments, loc);
+ method = Invocation.OverloadResolve (
+ ec, (MethodGroupExpr) operator_group, arguments, false, loc);
if (method == null)
return null;
@@ -1248,13 +1267,6 @@ namespace Mono.CSharp {
return 0;
}
- //
- // Default implementation of IAssignMethod.CacheTemporaries
- //
- public void CacheTemporaries (EmitContext ec)
- {
- }
-
static void Error_NegativeArrayIndex (Location loc)
{
Report.Error (284, loc, "Can not create array with a negative size");
@@ -1545,6 +1557,10 @@ namespace Mono.CSharp {
{
return Child.ConvertToInt ();
}
+
+ public override bool IsZeroInteger {
+ get { return Child.IsZeroInteger; }
+ }
}
///
@@ -1558,11 +1574,13 @@ namespace Mono.CSharp {
public BoxedCast (Expression expr)
: base (expr, TypeManager.object_type)
{
+ eclass = ExprClass.Value;
}
public BoxedCast (Expression expr, Type target_type)
: base (expr, target_type)
{
+ eclass = ExprClass.Value;
}
public override Expression DoResolve (EmitContext ec)
@@ -1601,9 +1619,13 @@ namespace Mono.CSharp {
ILGenerator ig = ec.ig;
base.Emit (ec);
- ig.Emit (OpCodes.Unbox, t);
+ if (t.IsGenericParameter)
+ ig.Emit (OpCodes.Unbox_Any, t);
+ else {
+ ig.Emit (OpCodes.Unbox, t);
- LoadFromPtr (ig, t);
+ LoadFromPtr (ig, t);
+ }
}
}
@@ -1886,9 +1908,14 @@ namespace Mono.CSharp {
{
base.Emit (ec);
- ec.ig.Emit (OpCodes.Castclass, type);
- }
-
+ if (child.Type.IsGenericParameter)
+ ec.ig.Emit (OpCodes.Box, child.Type);
+
+ if (type.IsGenericParameter)
+ ec.ig.Emit (OpCodes.Unbox_Any, type);
+ else
+ ec.ig.Emit (OpCodes.Castclass, type);
+ }
}
///
@@ -1921,7 +1948,7 @@ namespace Mono.CSharp {
///
public class SimpleName : Expression {
public string Name;
- public int NumTypeArguments;
+ public readonly TypeArguments Arguments;
//
// If true, then we are a simple name, not composed with a ".
@@ -1942,10 +1969,10 @@ namespace Mono.CSharp {
is_base = true;
}
- public SimpleName (string name, int num_type_arguments, Location l)
+ public SimpleName (string name, TypeArguments args, Location l)
{
Name = name;
- NumTypeArguments = num_type_arguments;
+ Arguments = args;
loc = l;
is_base = true;
}
@@ -1984,26 +2011,26 @@ namespace Mono.CSharp {
public override Expression DoResolve (EmitContext ec)
{
- return SimpleNameResolve (ec, null, false);
+ return SimpleNameResolve (ec, null, false, false);
}
public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
{
- return SimpleNameResolve (ec, right_side, false);
+ return SimpleNameResolve (ec, right_side, false, false);
}
- public Expression DoResolveAllowStatic (EmitContext ec)
+ public Expression DoResolveAllowStatic (EmitContext ec, bool intermediate)
{
- return SimpleNameResolve (ec, null, true);
+ return SimpleNameResolve (ec, null, true, intermediate);
}
public override Expression ResolveAsTypeStep (EmitContext ec)
{
DeclSpace ds = ec.DeclSpace;
NamespaceEntry ns = ds.NamespaceEntry;
- Type t;
- string alias_value;
+ TypeExpr t;
+ IAlias alias_value;
//
// Since we are cheating: we only do the Alias lookup for
@@ -2020,7 +2047,7 @@ namespace Mono.CSharp {
if (ec.ResolvingTypeTree){
int errors = Report.Errors;
- Type dt = ds.FindType (loc, Name, NumTypeArguments);
+ Type dt = ds.FindType (loc, Name);
if (Report.Errors != errors)
return null;
@@ -2029,8 +2056,10 @@ namespace Mono.CSharp {
return new TypeExpression (dt, loc);
if (alias_value != null){
- if ((t = RootContext.LookupType (ds, alias_value, true, NumTypeArguments, loc)) != null)
- return new TypeExpression (t, loc);
+ if (alias_value.IsType)
+ return alias_value.Type;
+ if ((t = RootContext.LookupType (ds, alias_value.Name, true, loc)) != null)
+ return t;
}
}
@@ -2038,11 +2067,13 @@ namespace Mono.CSharp {
// First, the using aliases
//
if (alias_value != null){
- if ((t = RootContext.LookupType (ds, alias_value, true, loc)) != null)
- return new TypeExpression (t, loc);
+ if (alias_value.IsType)
+ return alias_value.Type;
+ if ((t = RootContext.LookupType (ds, alias_value.Name, true, loc)) != null)
+ return t;
// we have alias value, but it isn't Type, so try if it's namespace
- return new SimpleName (alias_value, loc);
+ return new SimpleName (alias_value.Name, loc);
}
//
@@ -2050,14 +2081,41 @@ namespace Mono.CSharp {
// or a namespace.
//
- if ((t = RootContext.LookupType (ds, Name, true, NumTypeArguments, loc)) != null)
- return new TypeExpression (t, loc);
+ if ((t = RootContext.LookupType (ds, Name, true, loc)) != null)
+ return t;
// No match, maybe our parent can compose us
// into something meaningful.
return this;
}
+ Expression SimpleNameResolve (EmitContext ec, Expression right_side,
+ bool allow_static, bool intermediate)
+ {
+ Expression e = DoSimpleNameResolve (ec, right_side, allow_static, intermediate);
+ if (e == null)
+ return null;
+
+ Block current_block = ec.CurrentBlock;
+ if (current_block != null){
+ LocalInfo vi = current_block.GetLocalInfo (Name);
+ if (is_base &&
+ current_block.IsVariableNameUsedInChildBlock(Name)) {
+ Report.Error (135, Location,
+ "'{0}' has a different meaning in a " +
+ "child block", Name);
+ return null;
+ }
+ }
+
+ if (e.Type != null && e.Type.IsPointer && !ec.InUnsafe) {
+ UnsafeError (loc);
+ return null;
+ }
+
+ return e;
+ }
+
///
/// 7.5.2: Simple Names.
///
@@ -2075,7 +2133,7 @@ namespace Mono.CSharp {
/// Type is both an instance variable and a Type; Type.GetType
/// is the static method not an instance method of type.
///
- Expression SimpleNameResolve (EmitContext ec, Expression right_side, bool allow_static)
+ Expression DoSimpleNameResolve (EmitContext ec, Expression right_side, bool allow_static, bool intermediate)
{
Expression e = null;
@@ -2123,8 +2181,7 @@ namespace Mono.CSharp {
if (lookup_ds.TypeBuilder == null)
break;
- e = MemberLookup (ec, lookup_ds.TypeBuilder,
- Name, NumTypeArguments, loc);
+ e = MemberLookup (ec, lookup_ds.TypeBuilder, Name, loc);
if (e != null)
break;
@@ -2132,8 +2189,7 @@ namespace Mono.CSharp {
} while (lookup_ds != null);
if (e == null && ec.ContainerType != null)
- e = MemberLookup (ec, ec.ContainerType,
- Name, NumTypeArguments, loc);
+ e = MemberLookup (ec, ec.ContainerType, Name, loc);
if (e == null) {
//
@@ -2144,9 +2200,12 @@ namespace Mono.CSharp {
//
NamespaceEntry ns = ec.DeclSpace.NamespaceEntry;
if (is_base && ns != null){
- string alias_value = ns.LookupAlias (Name);
+ IAlias alias_value = ns.LookupAlias (Name);
if (alias_value != null){
- Name = alias_value;
+ if (alias_value.IsType)
+ return alias_value.Type;
+
+ Name = alias_value.Name;
Type t;
if ((t = TypeManager.LookupType (Name)) != null)
@@ -2173,26 +2232,34 @@ namespace Mono.CSharp {
if (me == null)
return e;
+ if (Arguments != null) {
+ MethodGroupExpr mg = me as MethodGroupExpr;
+ if (mg == null)
+ return null;
+
+ return mg.ResolveGeneric (ec, Arguments);
+ }
+
// This fails if ResolveMemberAccess() was unable to decide whether
// it's a field or a type of the same name.
+
if (!me.IsStatic && (me.InstanceExpression == null))
return e;
if (!me.IsStatic &&
- TypeManager.IsNestedChildOf (me.InstanceExpression.Type, me.DeclaringType) &&
- !me.InstanceExpression.Type.IsSubclassOf (me.DeclaringType)) {
+ TypeManager.IsSubclassOrNestedChildOf (me.InstanceExpression.Type, me.DeclaringType) &&
+ me.InstanceExpression.Type != me.DeclaringType &&
+ !TypeManager.IsSubclassOf (me.InstanceExpression.Type, me.DeclaringType) &&
+ (!intermediate || !MemberAccess.IdenticalNameAndTypeName (ec, this, e, loc))) {
Error (38, "Cannot access nonstatic member `" + me.Name + "' of " +
"outer type `" + me.DeclaringType + "' via nested type `" +
me.InstanceExpression.Type + "'");
return null;
}
- if (right_side != null)
- e = e.DoResolveLValue (ec, right_side);
- else
- e = e.DoResolve (ec);
-
- return e;
+ return (right_side != null)
+ ? e.DoResolveLValue (ec, right_side)
+ : e.DoResolve (ec);
}
if (ec.IsStatic || ec.IsFieldInitializer){
@@ -2225,7 +2292,7 @@ namespace Mono.CSharp {
///
/// Fully resolved expression that evaluates to a type
///
- public abstract class TypeExpr : Expression {
+ public abstract class TypeExpr : Expression, IAlias {
override public Expression ResolveAsTypeStep (EmitContext ec)
{
TypeExpr t = DoResolveAsTypeStep (ec);
@@ -2276,6 +2343,7 @@ namespace Mono.CSharp {
{
if (Type == TypeManager.enum_type ||
(Type == TypeManager.value_type && RootContext.StdLib) ||
+ Type == TypeManager.multicast_delegate_type ||
Type == TypeManager.delegate_type ||
Type == TypeManager.array_type)
return false;
@@ -2290,11 +2358,6 @@ namespace Mono.CSharp {
}
}
- public virtual TypeExpr[] GetInterfaces ()
- {
- return TypeManager.GetInterfaces (Type);
- }
-
public abstract TypeExpr DoResolveAsTypeStep (EmitContext ec);
public virtual Type ResolveType (EmitContext ec)
@@ -2319,13 +2382,28 @@ namespace Mono.CSharp {
return Type == tobj.Type;
}
+ public override int GetHashCode ()
+ {
+ return Type.GetHashCode ();
+ }
+
public override string ToString ()
{
return Name;
}
+
+ bool IAlias.IsType {
+ get { return true; }
+ }
+
+ TypeExpr IAlias.Type {
+ get {
+ return this;
+ }
+ }
}
- public class TypeExpression : TypeExpr {
+ public class TypeExpression : TypeExpr, IAlias {
public TypeExpression (Type t, Location l)
{
Type = t;
@@ -2343,6 +2421,12 @@ namespace Mono.CSharp {
return Type.ToString ();
}
}
+
+ string IAlias.Name {
+ get {
+ return Type.FullName != null ? Type.FullName : Type.Name;
+ }
+ }
}
///
@@ -2360,8 +2444,17 @@ namespace Mono.CSharp {
public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
{
- if (type == null)
- type = RootContext.LookupType (ec.DeclSpace, name, false, Location.Null);
+ if (type == null) {
+ TypeExpr texpr = RootContext.LookupType (
+ ec.DeclSpace, name, false, Location.Null);
+ if (texpr == null)
+ return null;
+
+ type = texpr.ResolveType (ec);
+ if (type == null)
+ return null;
+ }
+
return this;
}
@@ -2372,6 +2465,109 @@ namespace Mono.CSharp {
}
}
+ ///
+ /// Represents an "unbound generic type", ie. typeof (Foo<>).
+ /// See 14.5.11.
+ ///
+ public class UnboundTypeExpression : TypeLookupExpression {
+ public UnboundTypeExpression (string name)
+ : base (name)
+ { }
+ }
+
+ public class TypeAliasExpression : TypeExpr, IAlias {
+ TypeExpr texpr;
+ TypeArguments args;
+ string name;
+
+ public TypeAliasExpression (TypeExpr texpr, TypeArguments args, Location l)
+ {
+ this.texpr = texpr;
+ this.args = args;
+ loc = texpr.Location;
+
+ eclass = ExprClass.Type;
+ if (args != null)
+ name = texpr.Name + "<" + args.ToString () + ">";
+ else
+ name = texpr.Name;
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
+ {
+ Type type = texpr.ResolveType (ec);
+ if (type == null)
+ return null;
+
+ int num_args = TypeManager.GetNumberOfTypeArguments (type);
+
+ if (args != null) {
+ if (num_args == 0) {
+ Report.Error (308, loc,
+ "The non-generic type `{0}' cannot " +
+ "be used with type arguments.",
+ TypeManager.CSharpName (type));
+ return null;
+ }
+
+ ConstructedType ctype = new ConstructedType (type, args, loc);
+ return ctype.ResolveAsTypeTerminal (ec);
+ } else if (num_args > 0) {
+ Report.Error (305, loc,
+ "Using the generic type `{0}' " +
+ "requires {1} type arguments",
+ TypeManager.GetFullName (type), num_args);
+ return null;
+ }
+
+ return new TypeExpression (type, loc);
+ }
+
+ public override Type ResolveType (EmitContext ec)
+ {
+ TypeExpr t = ResolveAsTypeTerminal (ec);
+ if (t == null)
+ return null;
+
+ type = t.ResolveType (ec);
+ return type;
+ }
+
+ public override bool CheckAccessLevel (DeclSpace ds)
+ {
+ return texpr.CheckAccessLevel (ds);
+ }
+
+ public override bool AsAccessible (DeclSpace ds, int flags)
+ {
+ return texpr.AsAccessible (ds, flags);
+ }
+
+ public override bool IsClass {
+ get { return texpr.IsClass; }
+ }
+
+ public override bool IsValueType {
+ get { return texpr.IsValueType; }
+ }
+
+ public override bool IsInterface {
+ get { return texpr.IsInterface; }
+ }
+
+ public override bool IsSealed {
+ get { return texpr.IsSealed; }
+ }
+
+ public override bool IsAttribute {
+ get { return texpr.IsAttribute; }
+ }
+ }
+
///
/// MethodGroup Expression.
///
@@ -2381,6 +2577,9 @@ namespace Mono.CSharp {
public MethodBase [] Methods;
Expression instance_expression = null;
bool is_explicit_impl = false;
+ bool has_type_arguments = false;
+ bool identical_type_name = false;
+ bool is_base;
public MethodGroupExpr (MemberInfo [] mi, Location l)
{
@@ -2445,6 +2644,35 @@ namespace Mono.CSharp {
}
}
+ public bool HasTypeArguments {
+ get {
+ return has_type_arguments;
+ }
+
+ set {
+ has_type_arguments = value;
+ }
+ }
+
+ public bool IdenticalTypeName {
+ get {
+ return identical_type_name;
+ }
+
+ set {
+ identical_type_name = value;
+ }
+ }
+
+ public bool IsBase {
+ get {
+ return is_base;
+ }
+ set {
+ is_base = value;
+ }
+ }
+
public string Name {
get {
//return Methods [0].Name;
@@ -2532,6 +2760,55 @@ namespace Mono.CSharp {
{
return RemoveMethods (false);
}
+
+ public Expression ResolveGeneric (EmitContext ec, TypeArguments args)
+ {
+ if (args.Resolve (ec) == false)
+ return null;
+
+ Type[] atypes = args.Arguments;
+
+ int first_count = 0;
+ MethodInfo first = null;
+
+ ArrayList list = new ArrayList ();
+ foreach (MethodBase mb in Methods) {
+ MethodInfo mi = mb as MethodInfo;
+ if ((mi == null) || !mi.HasGenericParameters)
+ continue;
+
+ Type[] gen_params = mi.GetGenericArguments ();
+
+ if (first == null) {
+ first = mi;
+ first_count = gen_params.Length;
+ }
+
+ if (gen_params.Length != atypes.Length)
+ continue;
+
+ list.Add (mi.BindGenericParameters (atypes));
+ }
+
+ if (list.Count > 0) {
+ MethodGroupExpr new_mg = new MethodGroupExpr (list, Location);
+ new_mg.InstanceExpression = InstanceExpression;
+ new_mg.HasTypeArguments = true;
+ return new_mg;
+ }
+
+ if (first != null)
+ Report.Error (
+ 305, loc, "Using the generic method `{0}' " +
+ "requires {1} type arguments", Name,
+ first_count);
+ else
+ Report.Error (
+ 308, loc, "The non-generic method `{0}' " +
+ "cannot be used with type arguments", Name);
+
+ return null;
+ }
}
///
@@ -2542,6 +2819,10 @@ namespace Mono.CSharp {
Expression instance_expr;
VariableInfo variable_info;
+ LocalTemporary temp;
+ bool prepared;
+ bool is_field_initializer;
+
public FieldExpr (FieldInfo fi, Location l)
{
FieldInfo = fi;
@@ -2584,6 +2865,16 @@ namespace Mono.CSharp {
}
}
+ public bool IsFieldInitializer {
+ get {
+ return is_field_initializer;
+ }
+
+ set {
+ is_field_initializer = value;
+ }
+ }
+
public VariableInfo VariableInfo {
get {
return variable_info;
@@ -2611,6 +2902,19 @@ namespace Mono.CSharp {
return null;
}
+ ObsoleteAttribute oa;
+ FieldBase f = TypeManager.GetField (FieldInfo);
+ if (f != null) {
+ oa = f.GetObsoleteAttribute (ec.DeclSpace);
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, f.GetSignatureForError (), loc);
+ // To be sure that type is external because we do not register generated fields
+ } else if (!(FieldInfo.DeclaringType is TypeBuilder)) {
+ oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
+ if (oa != null)
+ AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc);
+ }
+
// If the instance expression is a local variable or parameter.
IVariable var = instance_expr as IVariable;
if ((var == null) || (var.VariableInfo == null))
@@ -2671,7 +2975,8 @@ namespace Mono.CSharp {
Report_AssignToReadonly (false);
Type ctype;
- if (ec.TypeContainer.CurrentType != null)
+ if (!is_field_initializer &&
+ (ec.TypeContainer.CurrentType != null))
ctype = ec.TypeContainer.CurrentType.ResolveType (ec);
else
ctype = ec.ContainerType;
@@ -2693,8 +2998,8 @@ namespace Mono.CSharp {
return true;
}
-
- override public void Emit (EmitContext ec)
+
+ public void Emit (EmitContext ec, bool leave_copy)
{
ILGenerator ig = ec.ig;
bool is_volatile = false;
@@ -2714,66 +3019,52 @@ namespace Mono.CSharp {
ig.Emit (OpCodes.Volatile);
ig.Emit (OpCodes.Ldsfld, FieldInfo);
- return;
- }
-
- if (instance_expr.Type.IsValueType){
- IMemoryLocation ml;
- LocalTemporary tempo = null;
-
- if (!(instance_expr is IMemoryLocation)){
- tempo = new LocalTemporary (ec, instance_expr.Type);
-
- if (ec.RemapToProxy)
- ec.EmitThis ();
-
- InstanceExpression.Emit (ec);
- tempo.Store (ec);
- ml = tempo;
- } else
- ml = (IMemoryLocation) instance_expr;
-
- ml.AddressOf (ec, AddressOp.Load);
} else {
- if (ec.RemapToProxy)
- ec.EmitThis ();
- else
- instance_expr.Emit (ec);
+ if (!prepared)
+ EmitInstance (ec);
+
+ if (is_volatile)
+ ig.Emit (OpCodes.Volatile);
+
+ ig.Emit (OpCodes.Ldfld, FieldInfo);
+ }
+
+ if (leave_copy) {
+ ec.ig.Emit (OpCodes.Dup);
+ if (!FieldInfo.IsStatic) {
+ temp = new LocalTemporary (ec, this.Type);
+ temp.Store (ec);
+ }
}
- if (is_volatile)
- ig.Emit (OpCodes.Volatile);
-
- ig.Emit (OpCodes.Ldfld, FieldInfo);
}
- public void EmitAssign (EmitContext ec, Expression source)
+ public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
{
FieldAttributes fa = FieldInfo.Attributes;
bool is_static = (fa & FieldAttributes.Static) != 0;
bool is_readonly = (fa & FieldAttributes.InitOnly) != 0;
ILGenerator ig = ec.ig;
+ prepared = prepare_for_load;
if (is_readonly && !ec.IsConstructor){
Report_AssignToReadonly (!is_static);
return;
}
- if (!is_static){
- Expression instance = instance_expr;
-
- if (instance.Type.IsValueType){
- IMemoryLocation ml = (IMemoryLocation) instance;
-
- ml.AddressOf (ec, AddressOp.Store);
- } else {
- if (ec.RemapToProxy)
- ec.EmitThis ();
- else
- instance.Emit (ec);
- }
+ if (!is_static) {
+ EmitInstance (ec);
+ if (prepare_for_load)
+ ig.Emit (OpCodes.Dup);
}
source.Emit (ec);
+ if (leave_copy) {
+ ec.ig.Emit (OpCodes.Dup);
+ if (!FieldInfo.IsStatic) {
+ temp = new LocalTemporary (ec, this.Type);
+ temp.Store (ec);
+ }
+ }
if (FieldInfo is FieldBuilder){
FieldBase f = TypeManager.GetField (FieldInfo);
@@ -2789,6 +3080,29 @@ namespace Mono.CSharp {
ig.Emit (OpCodes.Stsfld, FieldInfo);
else
ig.Emit (OpCodes.Stfld, FieldInfo);
+
+ if (temp != null)
+ temp.Emit (ec);
+ }
+
+ void EmitInstance (EmitContext ec)
+ {
+ if (instance_expr.Type.IsValueType) {
+ if (instance_expr is IMemoryLocation) {
+ ((IMemoryLocation) instance_expr).AddressOf (ec, AddressOp.LoadStore);
+ } else {
+ LocalTemporary t = new LocalTemporary (ec, instance_expr.Type);
+ instance_expr.Emit (ec);
+ t.Store (ec);
+ t.AddressOf (ec, AddressOp.Store);
+ }
+ } else
+ instance_expr.Emit (ec);
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ Emit (ec, false);
}
public void AddressOf (EmitContext ec, AddressOp mode)
@@ -2840,19 +3154,7 @@ namespace Mono.CSharp {
if (FieldInfo.IsStatic){
ig.Emit (OpCodes.Ldsflda, FieldInfo);
} else {
- //
- // 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 if (instance_expr.Type.IsValueType && instance_expr is IMemoryLocation){
- IMemoryLocation ml = (IMemoryLocation) instance_expr;
-
- ml.AddressOf (ec, AddressOp.LoadStore);
- } else
- instance_expr.Emit (ec);
+ EmitInstance (ec);
ig.Emit (OpCodes.Ldflda, FieldInfo);
}
}
@@ -2891,6 +3193,8 @@ namespace Mono.CSharp {
bool must_do_cs1540_check;
Expression instance_expr;
+ LocalTemporary temp;
+ bool prepared;
public PropertyExpr (EmitContext ec, PropertyInfo pi, Location l)
{
@@ -2953,75 +3257,104 @@ namespace Mono.CSharp {
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,
- 0, 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, null);
- //
- // 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;
}
//
@@ -3030,18 +3363,16 @@ namespace Mono.CSharp {
//
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;
if (setter == null && getter == null){
- Error (122, "`" + PropertyInfo.Name + "' " +
- "is inaccessible because of its protection level");
-
+ Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", PropertyInfo.Name);
}
}
@@ -3077,6 +3408,16 @@ namespace Mono.CSharp {
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
@@ -3128,6 +3469,14 @@ namespace Mono.CSharp {
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;
@@ -3139,11 +3488,53 @@ namespace Mono.CSharp {
PropertyInfo.DeclaringType + "." +PropertyInfo.Name);
return null;
}
+
+ //
+ // Check that we are not making changes to a temporary memory location
+ //
+ if (instance_expr != null && instance_expr.Type.IsValueType && !(instance_expr is IMemoryLocation)) {
+ // FIXME: Provide better error reporting.
+ Error (1612, "Cannot modify expression because it is not a variable.");
+ return null;
+ }
+
return this;
}
- override public void Emit (EmitContext ec)
+
+
+ public override void Emit (EmitContext ec)
+ {
+ Emit (ec, false);
+ }
+
+ void EmitInstance (EmitContext ec)
{
+ if (is_static)
+ return;
+
+ if (instance_expr.Type.IsValueType) {
+ if (instance_expr is IMemoryLocation) {
+ ((IMemoryLocation) instance_expr).AddressOf (ec, AddressOp.LoadStore);
+ } else {
+ LocalTemporary t = new LocalTemporary (ec, instance_expr.Type);
+ instance_expr.Emit (ec);
+ t.Store (ec);
+ t.AddressOf (ec, AddressOp.Store);
+ }
+ } else
+ instance_expr.Emit (ec);
+
+ if (prepared)
+ ec.ig.Emit (OpCodes.Dup);
+ }
+
+
+ public void Emit (EmitContext ec, bool leave_copy)
+ {
+ if (!prepared)
+ EmitInstance (ec);
+
//
// Special case: length of single dimension array property is turned into ldlen
//
@@ -3155,28 +3546,50 @@ namespace Mono.CSharp {
// System.Array.Length can be called, but the Type does not
// support invoking GetArrayRank, so test for that case first
//
- if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)){
- instance_expr.Emit (ec);
+ if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)) {
ec.ig.Emit (OpCodes.Ldlen);
ec.ig.Emit (OpCodes.Conv_I4);
return;
}
}
- Invocation.EmitCall (ec, IsBase, IsStatic, instance_expr, getter, null, loc);
+ Invocation.EmitCall (ec, IsBase, IsStatic, new EmptyAddressOf (), getter, null, loc);
+
+ if (!leave_copy)
+ return;
+ ec.ig.Emit (OpCodes.Dup);
+ if (!is_static) {
+ temp = new LocalTemporary (ec, this.Type);
+ temp.Store (ec);
+ }
}
//
// Implements the IAssignMethod interface for assignments
//
- public void EmitAssign (EmitContext ec, Expression source)
+ public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
{
- Argument arg = new Argument (source, Argument.AType.Expression);
- ArrayList args = new ArrayList ();
+ prepared = prepare_for_load;
+
+ EmitInstance (ec);
- args.Add (arg);
- Invocation.EmitCall (ec, IsBase, IsStatic, instance_expr, setter, args, loc);
+ source.Emit (ec);
+ if (leave_copy) {
+ ec.ig.Emit (OpCodes.Dup);
+ if (!is_static) {
+ temp = new LocalTemporary (ec, this.Type);
+ temp.Store (ec);
+ }
+ }
+
+ ArrayList args = new ArrayList (1);
+ args.Add (new Argument (new EmptyAddressOf (), Argument.AType.Expression));
+
+ Invocation.EmitCall (ec, IsBase, IsStatic, new EmptyAddressOf (), setter, args, loc);
+
+ if (temp != null)
+ temp.Emit (ec);
}
override public void EmitStatement (EmitContext ec)
@@ -3191,7 +3604,7 @@ namespace Mono.CSharp {
///
public class EventExpr : Expression, IMemberExpr {
public readonly EventInfo EventInfo;
- public Expression instance_expr;
+ Expression instance_expr;
bool is_static;
MethodInfo add_accessor, remove_accessor;