**** Merged r39626-39898 from MCS ****
authorMartin Baulig <martin@novell.com>
Wed, 16 Mar 2005 12:56:33 +0000 (12:56 -0000)
committerMartin Baulig <martin@novell.com>
Wed, 16 Mar 2005 12:56:33 +0000 (12:56 -0000)
svn path=/trunk/mcs/; revision=41894

mcs/gmcs/AssemblyInfo.cs
mcs/gmcs/ChangeLog
mcs/gmcs/attribute.cs
mcs/gmcs/class.cs
mcs/gmcs/const.cs
mcs/gmcs/cs-parser.jay
mcs/gmcs/ecore.cs
mcs/gmcs/expression.cs
mcs/gmcs/location.cs
mcs/gmcs/namespace.cs

index 8275cebbcb161304528011dad83b1966fcb29227..92c4dc0e1f2cbf61c9204dd1b9050f564cf4de32 100644 (file)
@@ -1,7 +1,7 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-[assembly: AssemblyVersion("1.1.3")]
+[assembly: AssemblyVersion("1.1.4")]
 [assembly: AssemblyTitle ("Mono C# Compiler")]
 [assembly: AssemblyDescription ("Mono C# Compiler with Generics")]
 [assembly: AssemblyCopyright ("2001, 2002, 2003 Ximian, Inc.")]
index dbdb0b8674c352f0d4ac8d7b7cf2025f6221eea5..a1ee0572b552fa3b0168f4c4f4f16ab0b917dfc3 100644 (file)
@@ -1,3 +1,59 @@
+2005-02-01  Raja R Harinath  <rharinath@novell.com>
+
+       * namespace.cs (NamespaceEntry.NamespaceEntry): Simplify, and
+       split into two.
+       (NamespaceEntry.ImplicitParent): Compute on demand.
+       (NamespaceEntry.Doppelganger): New implicit namespace-entry that
+       parallels the current.
+       (NamespaceEntry.LookupForUsing): Use it.
+       (NamespaceEntry.Lookup): If the current namespace-entry is
+       implicit, don't search aliases and using tables.
+
+2005-02-01  Raja R Harinath  <rharinath@novell.com>
+
+       Fix #31984.
+       * class.cs (TypeContainer.DoDefineMembers): Don't initialize
+       BaseCache here.
+       (TypeContainer.BaseCache): Compute on demand.
+       (TypeContainer.FindMembers): Define constants and types if they're
+       not already created.
+       (FieldMember.Define): Move resetting of ec.InUnsafe before error
+       check.
+       * const.cs (Constant.Define): Make idempotent.
+
+2005-01-29  Miguel de Icaza  <miguel@novell.com>
+
+       * pending.cs: Produce better code (no nops produced by using Ldarg
+       + value).
+       
+       * pending.cs (PendingImplementation.DefineProxy): It was not `arg
+       i - 1' it should be arg + 1.
+
+       Fixes bug #71819.
+
+2005-01-28  Raja R Harinath  <rharinath@novell.com>
+
+       * attribute.cs (Attribute.CheckAttributeType): Make private
+       non-virtual.
+       (Attribute.ResolveType): Make virtual.
+       (GlobalAttribute.ResolveType,GlobalAttribute.Resolve): Simplify
+       handling of RootContext.Tree.Types.
+
+2005-01-27  Raja R Harinath  <rharinath@novell.com>
+
+       Update attribute-handling to use the SimpleName/MemberAccess
+       mechanisms.
+       * cs-parser.jay (attribute): Pass in an expression to the
+       constructors of Attribute and GlobalAttribute.
+       * attribute.cs (Attribute): Take an expression for the name.
+       (Attribute.ResolvePossibleAttributeTypes): New.  Resolves the
+       passed in attribute name expression.
+       (Attribute.CheckAttributeType): Use it.
+       * ecore.cs (FullNamedExpression.ResolveAsTypeStep): New.
+       * expression.cs (MemberAccess.ResolveAsTypeStep): Move body to ...
+       (MemberAccess.ResolveNamespaceOrType): ... here.  Add 'silent'
+       argument to prevent error messages if the lookup fails.
+
 2005-01-27  Marek Safar  <marek.safar@seznam.cz>
 
        * expression.cs (Indirection): Implemented IVariable interface
index 30d6a61dcced525a185d747c6f7662f4d3588d41..6065ba14d69ca9578a14de2ed11e97da296d34e1 100644 (file)
@@ -72,6 +72,9 @@ namespace Mono.CSharp {
                public AttributeTargets Target;
 
                public readonly string    Name;
+               public readonly Expression LeftExpr;
+               public readonly string Identifier;
+
                public readonly ArrayList Arguments;
 
                public readonly Location Location;
@@ -102,9 +105,11 @@ namespace Mono.CSharp {
 
                static PtrHashtable usage_attr_cache = new PtrHashtable ();
                
-               public Attribute (string target, string name, ArrayList args, Location loc)
+               public Attribute (string target, Expression left_expr, string identifier, ArrayList args, Location loc)
                {
-                       Name = name;
+                       LeftExpr = left_expr;
+                       Identifier = identifier;
+                       Name = LeftExpr == null ? identifier : LeftExpr + "." + identifier;
                        Arguments = args;
                        Location = loc;
                        ExplicitTarget = target;
@@ -114,7 +119,7 @@ namespace Mono.CSharp {
                {
                        Report.Error (617, Location, "Invalid attribute argument: '{0}'.  Argument must be fields " +
                                      "fields which are not readonly, static or const;  or read-write instance properties.",
-                                     Name);
+                                     name);
                }
 
                static void Error_AttributeArgumentNotValid (string extra, Location loc)
@@ -155,26 +160,49 @@ namespace Mono.CSharp {
                                       "Could not find a constructor for this argument list.");
                }
 
+               void ResolvePossibleAttributeTypes (EmitContext ec, out Type t1, out Type t2)
+               {
+                       t1 = null;
+                       t2 = null;
+
+                       FullNamedExpression n1 = null;
+                       FullNamedExpression n2 = null;
+                       string IdentifierAttribute = Identifier + "Attribute";
+                       if (LeftExpr == null) {
+                               n1 = new SimpleName (Identifier, Location).ResolveAsTypeStep (ec);
+
+                               // FIXME: Shouldn't do this for quoted attributes: [@A]
+                               n2 = new SimpleName (IdentifierAttribute, Location).ResolveAsTypeStep (ec);
+                       } else {
+                               FullNamedExpression l = LeftExpr.ResolveAsTypeStep (ec);
+                               if (l == null) {
+                                       Report.Error (246, Location, "Couldn't find namespace or type '{0}'", LeftExpr);
+                                       return;
+                               }
+                               n1 = new MemberAccess (l, Identifier, Location).ResolveNamespaceOrType (ec, true);
+
+                               // FIXME: Shouldn't do this for quoted attributes: [X.@A]
+                               n2 = new MemberAccess (l, IdentifierAttribute, Location).ResolveNamespaceOrType (ec, true);
+                       }
+
+                       TypeExpr te1 = n1 == null ? null : n1 as TypeExpr;
+                       TypeExpr te2 = n2 == null ? null : n2 as TypeExpr;                      
+
+                       if (te1 != null)
+                               t1 = te1.ResolveType (ec);
+                       if (te2 != null)
+                               t2 = te2.ResolveType (ec);
+               }
+
                /// <summary>
                 ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
                 /// </summary>
-               protected virtual Type CheckAttributeType (EmitContext ec)
+               Type CheckAttributeType (EmitContext ec)
                {
-                       string NameAttribute = Name + "Attribute";
-                       FullNamedExpression n1 = ec.ResolvingTypeTree
-                               ? ec.DeclSpace.FindType (Location, Name)
-                               : ec.DeclSpace.LookupType (Name, true, Location);
+                       Type t1, t2;
+                       ResolvePossibleAttributeTypes (ec, out t1, out t2);
 
-                       // FIXME: Shouldn't do this for quoted attributes: [@A]
-                       FullNamedExpression n2 = ec.ResolvingTypeTree
-                               ? ec.DeclSpace.FindType (Location, NameAttribute)
-                               : ec.DeclSpace.LookupType (NameAttribute, true, Location);
-
-                       TypeExpr e1 = n1 == null ? null : n1 as TypeExpr;
-                       TypeExpr e2 = n2 == null ? null : n2 as TypeExpr;                       
-
-                       Type t1 = e1 == null ? null : e1.ResolveType (ec);
-                       Type t2 = e2 == null ? null : e2.ResolveType (ec);
+                       string NameAttribute = Name + "Attribute";
 
                        String err0616 = null;
                        if (t1 != null && ! t1.IsSubclassOf (TypeManager.attribute_type)) {
@@ -210,7 +238,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public Type ResolveType (EmitContext ec)
+               public virtual Type ResolveType (EmitContext ec)
                {
                        if (Type == null)
                                Type = CheckAttributeType (ec);
@@ -1191,52 +1219,46 @@ namespace Mono.CSharp {
        {
                public readonly NamespaceEntry ns;
 
-               public GlobalAttribute (TypeContainer container, string target, string name, ArrayList args, Location loc):
-                       base (target, name, args, loc)
+               public GlobalAttribute (TypeContainer container, string target, 
+                                       Expression left_expr, string identifier, ArrayList args, Location loc):
+                       base (target, left_expr, identifier, args, loc)
                {
                        ns = container.NamespaceEntry;
                }
 
-               protected override Type CheckAttributeType (EmitContext ec)
+               void Enter ()
                {
                        // RootContext.Tree.Types has a single NamespaceEntry which gets overwritten
                        // each time a new file is parsed.  However, we need to use the NamespaceEntry
                        // in effect where the attribute was used.  Since code elsewhere cannot assume
                        // that the NamespaceEntry is right, just overwrite it.
                        //
-                       // Precondition: RootContext.Tree.Types == null || RootContext.Tree.Types == ns.
-                       //               The second case happens when we are recursively invoked from inside Emit.
-
-                       NamespaceEntry old = null;
-                       if (ec.DeclSpace == RootContext.Tree.Types) {
-                               old = ec.DeclSpace.NamespaceEntry;
-                               ec.DeclSpace.NamespaceEntry = ns;
-                               if (old != null && old != ns)
-                                       throw new InternalErrorException (Location + " non-null NamespaceEntry " + old);
-                       }
+                       // Precondition: RootContext.Tree.Types == null
 
-                       Type retval = base.CheckAttributeType (ec);
+                       if (RootContext.Tree.Types.NamespaceEntry != null)
+                               throw new InternalErrorException (Location + " non-null NamespaceEntry");
 
-                       if (ec.DeclSpace == RootContext.Tree.Types)
-                               ec.DeclSpace.NamespaceEntry = old;
+                       RootContext.Tree.Types.NamespaceEntry = ns;
+               }
 
+               void Leave ()
+               {
+                       RootContext.Tree.Types.NamespaceEntry = null;
+               }
+
+               public override Type ResolveType (EmitContext ec)
+               {
+                       Enter ();
+                       Type retval = base.ResolveType (ec);
+                       Leave ();
                        return retval;
                }
 
                public override CustomAttributeBuilder Resolve (EmitContext ec)
                {
-                       if (ec.DeclSpace == RootContext.Tree.Types) {
-                               NamespaceEntry old = ec.DeclSpace.NamespaceEntry;
-                               ec.DeclSpace.NamespaceEntry = ns;
-                               if (old != null)
-                                       throw new InternalErrorException (Location + " non-null NamespaceEntry " + old);
-                       }
-
+                       Enter ();
                        CustomAttributeBuilder retval = base.Resolve (ec);
-
-                       if (ec.DeclSpace == RootContext.Tree.Types)
-                               ec.DeclSpace.NamespaceEntry = null;
-
+                       Leave ();
                        return retval;
                }
        }
index c1add900dd8c2dbce7cba2276307f702e2407c6d..fe7b8904c9ea022ef294fa2d66e4cedb3fc92bc2 100644 (file)
@@ -1470,15 +1470,6 @@ namespace Mono.CSharp {
 
                protected virtual bool DoDefineMembers ()
                {
-                       //
-                       // We need to be able to use the member cache while we are checking/defining
-                       //
-                       if (TypeBuilder.BaseType != null)
-                               base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
-
-                       if (TypeBuilder.IsInterface)
-                               base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
-
                        if (IsTopLevel) {
                                if ((ModFlags & Modifiers.NEW) != 0)
                                        Error_KeywordNotAllowed (Location);
@@ -1799,6 +1790,10 @@ namespace Mono.CSharp {
                                                        continue;
 
                                                FieldBuilder fb = con.FieldBuilder;
+                                               if (fb == null) {
+                                                       if (con.Define ())
+                                                               fb = con.FieldBuilder;
+                                               }
                                                if (fb != null && filter (fb, criteria) == true) {
                                                        if (members == null)
                                                                members = new ArrayList ();
@@ -1986,6 +1981,9 @@ namespace Mono.CSharp {
                                                        continue;
 
                                                TypeBuilder tb = t.TypeBuilder;
+                                               if (tb == null)
+                                                       tb = t.DefineType ();
+
                                                if (tb != null && (filter (tb, criteria) == true)) {
                                                        if (members == null)
                                                                members = new ArrayList ();
@@ -2588,6 +2586,12 @@ namespace Mono.CSharp {
 
                public virtual MemberCache BaseCache {
                        get {
+                               if (base_cache != null)
+                                       return base_cache;
+                               if (TypeBuilder.BaseType != null)
+                                       base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
+                               if (TypeBuilder.IsInterface)
+                                       base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
                                return base_cache;
                        }
                }
@@ -5661,9 +5665,9 @@ namespace Mono.CSharp {
                        }
 
                        if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
-                               Report.SymbolRelatedToPreviousError (conflict_symbol);
-                               Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
-                       }
+                               Report.SymbolRelatedToPreviousError (conflict_symbol);
+                               Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+                       }
 
                        return true;
                }
@@ -5762,13 +5766,13 @@ namespace Mono.CSharp {
                        
                        MemberType = texpr.Type;
 
+                       ec.InUnsafe = old_unsafe;
+
                        if (MemberType == TypeManager.void_type) {
                                Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
                                return false;
                        }
 
-                       ec.InUnsafe = old_unsafe;
-
                        if (!CheckBase ())
                                return false;
                        
index 1c15f85ecaa87a95376b2a3753923b132a7a94c5..337d988aba63e86cf85abcf20abfa1d78295bf72 100644 (file)
@@ -67,6 +67,10 @@ namespace Mono.CSharp {
                /// </summary>
                public override bool Define ()
                {
+                       // Make Define () idempotent.
+                       if (FieldBuilder != null)
+                               return true;
+
                        if (!base.Define ())
                                return false;
 
index 99aad5441001bd25e6e6374e4339e1bb151453ce..1c6a364090d44298ab2f4734512be6d9d419bac9 100644 (file)
@@ -622,19 +622,23 @@ attribute
          }
          opt_attribute_arguments
          {
+               Location loc = (Location) $2;
                MemberName mname = (MemberName) $1;
                if (mname.IsGeneric) {
                        Report.Error (404, lexer.Location,
                                      "'<' unexpected: attributes cannot be generic");
                }
 
-               string name = mname.GetName ();
+               MemberName left = mname.Left;
+               string identifier = mname.Name;
+
+               Expression left_expr = left == null ? null : left.GetTypeExpression (loc);
+
                if (current_attr_target == "assembly" || current_attr_target == "module")
                        $$ = new GlobalAttribute (current_container, current_attr_target,
-                                                 name, (ArrayList) $3, (Location) $2);
+                                                 left_expr, identifier, (ArrayList) $3, loc);
                else
-                       $$ = new Attribute (current_attr_target, name, (ArrayList) $3,
-                                           (Location) $2);
+                       $$ = new Attribute (current_attr_target, left_expr, identifier, (ArrayList) $3, loc);
          }
        ;
 
index 34599835cdef8aefd0b0be44cc4da4a299f1c6d9..31f0ecbb4c7a8c7854d02ceedde4eca4211a6fc8 100644 (file)
@@ -2278,6 +2278,11 @@ namespace Mono.CSharp {
        ///   section 10.8.1 (Fully Qualified Names).
        /// </summary>
        public abstract class FullNamedExpression : Expression {
+               public override FullNamedExpression ResolveAsTypeStep (EmitContext ec)
+               {
+                       return this;
+               }
+
                public abstract string FullName {
                        get;
                }
index c521f95b1d9d1c8706e96f832c19dd4e40bf5225..150b9cb0bb393cd78210b7fb2b1b797c939fa818 100644 (file)
@@ -7640,6 +7640,11 @@ namespace Mono.CSharp {
                }
 
                public override FullNamedExpression ResolveAsTypeStep (EmitContext ec)
+               {
+                       return ResolveNamespaceOrType (ec, false);
+               }
+
+               public FullNamedExpression ResolveNamespaceOrType (EmitContext ec, bool silent)
                {
                        FullNamedExpression new_expr = expr.ResolveAsTypeStep (ec);
 
@@ -7653,7 +7658,7 @@ namespace Mono.CSharp {
                                FullNamedExpression retval = ns.Lookup (ec.DeclSpace, lookup_id, loc);
                                if ((retval != null) && (args != null))
                                        retval = new ConstructedType (retval, args, loc).ResolveAsTypeStep (ec);
-                               if (retval == null)
+                               if (!silent && retval == null)
                                        Report.Error (234, loc, "The type or namespace name `{0}' could not be found in namespace `{1}'", Identifier, ns.FullName);
                                return retval;
                        }
@@ -7672,7 +7677,7 @@ namespace Mono.CSharp {
 
                        Expression member_lookup;
                        member_lookup = MemberLookupFinal (ec, expr_type, expr_type, lookup_id, loc);
-                       if (member_lookup == null) {
+                       if (!silent && member_lookup == null) {
                                Report.Error (234, loc, "The type name `{0}' could not be found in type `{1}'", 
                                              Identifier, new_expr.FullName);
                                return null;
index 3b81e8e68327edd1a41a6b0be0047823658285ff..ccbc084035900a9872201487faa1bfefecd4b31c 100644 (file)
@@ -57,7 +57,7 @@ namespace Mono.CSharp {
        ///   in 8 bits (and say, map anything after char 255 to be `255+').
        /// </remarks>
        public struct Location {
-               public int token; 
+               int token; 
 
                static ArrayList source_list;
                static Hashtable source_files;
index ec0a8347be7f965ea04df864df213b262a8c2377..a3992fc81f52203410e2bb2f212cac8adfa7c266 100644 (file)
@@ -297,32 +297,42 @@ namespace Mono.CSharp {
                }
 
                public NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, Location loc)
-                       : this (parent, file, name, false, loc)
-               { }
-
-               protected NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, bool is_implicit, Location loc)
                {
                        this.parent = parent;
                        this.file = file;
-                       this.IsImplicit = is_implicit;
+                       this.IsImplicit = false;
                        this.ID = ++next_id;
 
-                       if (!is_implicit && (parent != null))
+                       if (parent != null)
                                ns = parent.NS.GetNamespace (name, true);
                        else if (name != null)
                                ns = Namespace.LookupNamespace (name, true);
                        else
                                ns = Namespace.Root;
                        ns.AddNamespaceEntry (this);
+                       this.FullName = ns.Name;
+               }
 
-                       if ((parent != null) && (parent.NS != ns.Parent))
-                               implicit_parent = new NamespaceEntry (parent, file, ns.Parent.Name, true, loc);
-                       else
-                               implicit_parent = parent;
 
+               private NamespaceEntry (NamespaceEntry parent, SourceFile file, Namespace ns)
+               {
+                       this.parent = parent;
+                       this.file = file;
+                       this.IsImplicit = true;
+                       this.ID = ++next_id;
+                       this.ns = ns;
                        this.FullName = ns.Name;
                }
 
+               NamespaceEntry doppelganger;
+               NamespaceEntry Doppelganger {
+                       get {
+                               if (!IsImplicit && doppelganger == null)
+                                       doppelganger = new NamespaceEntry (ImplicitParent, file, ns);
+                               return doppelganger;
+                       }
+               }
+
                static int next_id = 0;
                public readonly string FullName;
                public readonly int ID;
@@ -342,6 +352,13 @@ namespace Mono.CSharp {
 
                public NamespaceEntry ImplicitParent {
                        get {
+                               if (parent == null)
+                                       return null;
+                               if (implicit_parent == null) {
+                                       implicit_parent = (parent.NS == ns.Parent)
+                                               ? parent
+                                               : new NamespaceEntry (parent, file, ns.Parent);
+                               }
                                return implicit_parent;
                        }
                }
@@ -424,10 +441,7 @@ namespace Mono.CSharp {
                                rest = dotted_name.Substring (pos + 1);
                        }
 
-                       FullNamedExpression o = NS.Lookup (null, simple_name, loc);
-                       if (o == null && ImplicitParent != null)
-                               o = ImplicitParent.LookupNamespaceOrType (null, simple_name, loc);
-
+                       FullNamedExpression o = Doppelganger.LookupNamespaceOrType (null, simple_name, loc);
                        if (o == null || rest == null)
                                return o;
 
@@ -455,7 +469,6 @@ namespace Mono.CSharp {
                private FullNamedExpression Lookup (DeclSpace ds, string name, Location loc)
                {
                        FullNamedExpression o;
-                       Namespace ns;
 
                        //
                        // If name is of the form `N.I', first lookup `N', then search a member `I' in it.
@@ -467,14 +480,15 @@ namespace Mono.CSharp {
                        //
                        int pos = name.IndexOf ('.');
                        if (pos >= 0) {
+                               //throw new InternalErrorException ("Only simple names should come here");
                                string first = name.Substring (0, pos);
                                string last = name.Substring (pos + 1);
 
                                o = Lookup (ds, first, loc);
                                if (o == null)
                                        return null;
-
-                               ns = o as Namespace;
+                               
+                               Namespace ns = o as Namespace;
                                if (ns != null) {
                                        o = ns.Lookup (ds, last, loc);
                                        return o;
@@ -494,6 +508,9 @@ namespace Mono.CSharp {
                        if (o != null)
                                return o;
 
+                       if (IsImplicit)
+                               return null;
+
                        //
                        // Check aliases.
                        //
@@ -501,9 +518,6 @@ namespace Mono.CSharp {
                        if (o != null)
                                return o;
 
-                       if (name.IndexOf ('.') > 0)
-                               return null;
-
                        //
                        // Check using entries.
                        //