Author: martin
Date: 2005-03-21 13:11:45 -0500 (Mon, 21 Mar 2005)
New Revision: 42051

Modified:
   trunk/mcs/gmcs/ChangeLog
   trunk/mcs/gmcs/class.cs
   trunk/mcs/gmcs/const.cs
   trunk/mcs/gmcs/cs-parser.jay
   trunk/mcs/gmcs/namespace.cs
Log:
**** Merged r39917-r39971 from MCS ****


Modified: trunk/mcs/gmcs/ChangeLog
===================================================================
--- trunk/mcs/gmcs/ChangeLog    2005-03-21 17:10:19 UTC (rev 42050)
+++ trunk/mcs/gmcs/ChangeLog    2005-03-21 18:11:45 UTC (rev 42051)
@@ -1,3 +1,58 @@
+2005-02-02  Raja R Harinath  <[EMAIL PROTECTED]>
+
+       Fix a crasher in a variant of #31984.
+       * const.cs (Constant.CheckBase): New override that defers the
+       new-or-override check in case the base type hasn't been populated
+       yet.
+       (Constant.Define): Ensure the new-or-override check is performed.
+
+2005-02-01  Duncan Mak  <[EMAIL PROTECTED]>
+
+       * const.cs (LookupConstantValue): Check that `ce' is not null
+       before calling GetValue ().
+
+2005-02-01  Raja R Harinath  <[EMAIL PROTECTED]>
+
+       Fix test-334.cs (#69519).
+       * cs-parser.jay (using_alias_directive): Pass in an expression to
+       NamespaceEntry.UsingAlias.
+       (using_namespace_directive): Pass in an expression to
+       NamespaceEntry.Using.
+       (namespace_name): Don't flatten to a string.
+       * namespace.cs (NamespaceEntry.AliasEntry): Store an expression.
+       (NamespaceEntry.AliasEntry.Resolve): Lookup using
+       ResolveAsTypeStep.
+       (NamespaceEntry.UsingEntry): Likewise.
+       (NamespaceEntry.Using,NamespaceEntry.UsingAlias): Update to
+       changes.
+       (NamespaceEntry.LookupForUsing): Remove.
+       (NamespaceEntry.LookupNamespaceOrType): Add support for dotted
+       names.
+       (NamespaceEntry.Lookup): Remove support for dotted names.
+
+2005-02-01  Raja R Harinath  <[EMAIL PROTECTED]>
+
+       * 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  <[EMAIL PROTECTED]>
+
+       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  <[EMAIL PROTECTED]>
 
        * pending.cs: Produce better code (no nops produced by using Ldarg

Modified: trunk/mcs/gmcs/class.cs
===================================================================
--- trunk/mcs/gmcs/class.cs     2005-03-21 17:10:19 UTC (rev 42050)
+++ trunk/mcs/gmcs/class.cs     2005-03-21 18:11:45 UTC (rev 42051)
@@ -1470,15 +1470,6 @@
 
                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 @@
                                                        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 @@
                                                        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 @@
 
                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 @@
                        }
 
                        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 @@
                        
                        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;
                        

Modified: trunk/mcs/gmcs/const.cs
===================================================================
--- trunk/mcs/gmcs/const.cs     2005-03-21 17:10:19 UTC (rev 42050)
+++ trunk/mcs/gmcs/const.cs     2005-03-21 18:11:45 UTC (rev 42051)
@@ -62,11 +62,25 @@
                }
 #endif
 
+               protected override bool CheckBase ()
+               {
+                       // Constant.Define can be called when the parent type 
hasn't yet been populated
+                       // and it's base types need not have been populated.  
So, we defer this check
+                       // to the second time Define () is called on this 
member.
+                       if (Parent.BaseCache == null)
+                               return true;
+                       return base.CheckBase ();
+               }
+
                /// <summary>
                ///   Defines the constant in the @parent
                /// </summary>
                public override bool Define ()
                {
+                       // Make Define () idempotent, but ensure that the error 
check happens.
+                       if (FieldBuilder != null)
+                               return base.CheckBase ();
+
                        if (!base.Define ())
                                return false;
 
@@ -248,8 +262,10 @@
                                }
                                Expr = ce;
                        }
-                       ConstantValue = ce.GetValue ();
 
+                       if (ce != null)
+                               ConstantValue = ce.GetValue ();
+
                        if (MemberType.IsEnum){
                                //
                                // This sadly does not work for our 
user-defined enumerations types ;-(

Modified: trunk/mcs/gmcs/cs-parser.jay
===================================================================
--- trunk/mcs/gmcs/cs-parser.jay        2005-03-21 17:10:19 UTC (rev 42050)
+++ trunk/mcs/gmcs/cs-parser.jay        2005-03-21 18:11:45 UTC (rev 42051)
@@ -338,7 +338,8 @@
        : USING IDENTIFIER ASSIGN 
          namespace_or_type_name SEMICOLON
          {
-               current_namespace.UsingAlias ((string) $2, (MemberName) $4, 
lexer.Location);
+               MemberName name = (MemberName) $4;
+               current_namespace.UsingAlias ((string) $2, 
name.GetTypeExpression (lexer.Location), lexer.Location);
          }
        | USING error {
                CheckIdentifierToken (yyToken);
@@ -348,7 +349,8 @@
 using_namespace_directive
        : USING namespace_name SEMICOLON 
          {
-               current_namespace.Using ((string) $2, lexer.Location);
+               MemberName ns_name = (MemberName) $2;
+               current_namespace.Using (ns_name.GetTypeExpression 
(lexer.Location), lexer.Location);
           }
        ;
 
@@ -401,7 +403,7 @@
                if (name.TypeArguments != null)
                        syntax_error (lexer.Location, "namespace name 
expected");
 
-               $$ = name.GetName ();
+               $$ = name;
          }
        ;
 

Modified: trunk/mcs/gmcs/namespace.cs
===================================================================
--- trunk/mcs/gmcs/namespace.cs 2005-03-21 17:10:19 UTC (rev 42050)
+++ trunk/mcs/gmcs/namespace.cs 2005-03-21 18:11:45 UTC (rev 42051)
@@ -229,37 +229,40 @@
                // exist.
                //
                public class UsingEntry {
-                       public readonly string Name;
+                       public Expression Name;
                        public readonly NamespaceEntry NamespaceEntry;
                        public readonly Location Location;
                        
-                       public UsingEntry (NamespaceEntry entry, string name, 
Location loc)
+                       public UsingEntry (NamespaceEntry entry, Expression 
name, Location loc)
                        {
                                Name = name;
                                NamespaceEntry = entry;
                                Location = loc;
                        }
 
-                       Namespace resolved_ns;
+                       internal FullNamedExpression resolved;
 
                        public Namespace Resolve ()
                        {
-                               if (resolved_ns != null)
-                                       return resolved_ns;
+                               if (resolved != null)
+                                       return resolved as Namespace;
 
-                               FullNamedExpression resolved = 
NamespaceEntry.LookupForUsing (Name, Location);
-                               resolved_ns = resolved as Namespace;
-                               return resolved_ns;
+                               DeclSpace root = RootContext.Tree.Types;
+                               root.NamespaceEntry = NamespaceEntry;
+                               resolved = Name.ResolveAsTypeStep 
(root.EmitContext);
+                               root.NamespaceEntry = null;
+
+                               return resolved as Namespace;
                        }
                }
 
                public class AliasEntry {
                        public readonly string Name;
-                       public readonly MemberName Alias;
+                       public readonly Expression Alias;
                        public readonly NamespaceEntry NamespaceEntry;
                        public readonly Location Location;
                        
-                       public AliasEntry (NamespaceEntry entry, string name, 
MemberName alias, Location loc)
+                       public AliasEntry (NamespaceEntry entry, string name, 
Expression alias, Location loc)
                        {
                                Name = name;
                                Alias = alias;
@@ -274,55 +277,62 @@
                                if (resolved != null)
                                        return resolved;
 
-                               //
-                               // GENERICS: Cope with the expression and not 
with the string
-                               // this will fail with `using A = Stack<int>'
-                               //
-                               
-                               string alias = Alias.GetTypeName ();
+                               DeclSpace root = RootContext.Tree.Types;
+                               root.NamespaceEntry = NamespaceEntry;
+                               resolved = Alias.ResolveAsTypeStep 
(root.EmitContext);
+                               root.NamespaceEntry = null;
 
-                               resolved = NamespaceEntry.LookupForUsing 
(alias, Location);
-                               if (resolved == null)
-                                       return null;
-
-                               if (Alias.TypeArguments == null)
-                                       return resolved;
-
-                               EmitContext ec = 
RootContext.Tree.Types.EmitContext;
-                               resolved = new TypeAliasExpression (resolved, 
Alias.TypeArguments, Location);
-                               resolved = resolved.ResolveAsTypeStep (ec);
-
                                return resolved;
                        }
                }
 
                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;
                }
 
+               //
+               // According to section 16.3.1 (using-alias-directive), the 
namespace-or-type-name is
+               // resolved as if the immediately containing namespace body has 
no using-directives.
+               //
+               // Section 16.3.2 says that the same rule is applied when 
resolving the namespace-name
+               // in the using-namespace-directive.
+               //
+               // To implement these rules, the expressions in the using 
directives are resolved using 
+               // the "doppelganger" (ghostly bodiless duplicate).
+               //
+               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 @@
 
                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;
                        }
                }
@@ -354,32 +371,34 @@
                /// <summary>
                ///   Records a new namespace for resolving name references
                /// </summary>
-               public void Using (string ns, Location loc)
+               public void Using (Expression ns, Location loc)
                {
+                       string name = ns.ToString ();
                        if (DeclarationFound){
                                Report.Error (1529, loc, "A using clause must 
precede all other namespace elements");
                                return;
                        }
 
-                       if (ns == FullName)
+                       if (name == FullName)
                                return;
                        
                        if (using_clauses == null)
                                using_clauses = new ArrayList ();
 
                        foreach (UsingEntry old_entry in using_clauses) {
-                               if (old_entry.Name == ns) {
+                               if (old_entry.Name.ToString () == name) {
                                        if (RootContext.WarningLevel >= 3)
-                                               Report.Warning (105, loc, "The 
using directive for '{0}' appeared previously in this namespace", ns);
+                                               Report.Warning (105, loc, "The 
using directive for '{0}' appeared previously in this namespace", name);
                                                return;
                                        }
                                }
-                       
-                       UsingEntry ue = new UsingEntry (this, ns, loc);
+
+
+                       UsingEntry ue = new UsingEntry (Doppelganger, ns, loc);
                        using_clauses.Add (ue);
                }
 
-               public void UsingAlias (string name, MemberName alias, Location 
loc)
+               public void UsingAlias (string name, Expression alias, Location 
loc)
                {
                        if (DeclarationFound){
                                Report.Error (1529, loc, "A using clause must 
precede all other namespace elements");
@@ -395,7 +414,7 @@
                                return;
                        }
 
-                       aliases [name] = new AliasEntry (this, name, alias, 
loc);
+                       aliases [name] = new AliasEntry (Doppelganger, name, 
alias, loc);
                }
 
                public FullNamedExpression LookupAlias (string alias)
@@ -407,93 +426,51 @@
                        return entry == null ? null : entry.Resolve ();
                }
 
-               //
-               // According to section 16.3.1 (using-alias-directive), the 
namespace-or-type-name is 
-               // resolved as if the immediately containing namespace body has 
no using-directives.
-               //
-               // Section 16.3.2 says that the same rule is applied when 
resolving the namespace-name
-               // in the using-namespace-directive.
-               //
-               public FullNamedExpression LookupForUsing (string dotted_name, 
Location loc)
+               public FullNamedExpression LookupNamespaceOrType (DeclSpace ds, 
string name, Location loc)
                {
-                       int pos = dotted_name.IndexOf ('.');
-                       string simple_name = dotted_name;
+                       FullNamedExpression resolved = null;
                        string rest = null;
+
+                       // If name is of the form `N.I', first lookup `N', then 
search a member `I' in it.
+                       int pos = name.IndexOf ('.');
                        if (pos >= 0) {
-                               simple_name = dotted_name.Substring (0, pos);
-                               rest = dotted_name.Substring (pos + 1);
+                               rest = name.Substring (pos + 1);
+                               name = name.Substring (0, pos);
                        }
 
-                       FullNamedExpression o = NS.Lookup (null, simple_name, 
loc);
-                       if (o == null && ImplicitParent != null)
-                               o = ImplicitParent.LookupNamespaceOrType (null, 
simple_name, loc);
+                       for (NamespaceEntry curr_ns = this; curr_ns != null; 
curr_ns = curr_ns.ImplicitParent) {
+                               if ((resolved = curr_ns.Lookup (ds, name, loc)) 
!= null)
+                                       break;
+                       }
 
-                       if (o == null || rest == null)
-                               return o;
+                       if (resolved == null || rest == null)
+                               return resolved;
 
-                       Namespace ns = o as Namespace;
+                       Namespace ns = resolved as Namespace;
                        if (ns != null)
-                               return ns.Lookup (null, rest, loc);
-                       
-                       Type nested = TypeManager.LookupType (o.FullName + "." 
+ rest);
-                       if (nested == null)
+                               return ns.Lookup (ds, rest, loc);
+
+                       Type nested = TypeManager.LookupType (resolved.FullName 
+ "." + rest);
+                       if ((nested == null) || ((ds != null) && 
!ds.CheckAccessLevel (nested)))
                                return null;
 
                        return new TypeExpression (nested, Location.Null);
                }
 
-               public FullNamedExpression LookupNamespaceOrType (DeclSpace ds, 
string name, Location loc)
-               {
-                       FullNamedExpression resolved = null;
-                       for (NamespaceEntry curr_ns = this; curr_ns != null; 
curr_ns = curr_ns.ImplicitParent) {
-                               if ((resolved = curr_ns.Lookup (ds, name, loc)) 
!= null)
-                                       break;
-                       }
-                       return resolved;
-               }
-
                private FullNamedExpression Lookup (DeclSpace ds, string name, 
Location loc)
                {
-                       FullNamedExpression o;
-                       Namespace ns;
+                       // Precondition: Only simple names (no dots) will be 
looked up with this function.
 
                        //
-                       // If name is of the form `N.I', first lookup `N', then 
search a member `I' in it.
-                       //
-                       // FIXME: Remove this block.  Only simple names should 
come here.
-                       //        The bug: The loop in LookupNamespaceOrType 
continues if 
-                       //        the lookup for N succeeds but the nested 
lookup for I fails.
-                       //        This is one part of #52697.
-                       //
-                       int pos = name.IndexOf ('.');
-                       if (pos >= 0) {
-                               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;
-                               if (ns != null) {
-                                       o = ns.Lookup (ds, last, loc);
-                                       return o;
-                               }
-
-                               Type nested = TypeManager.LookupType 
(o.FullName + "." + last);
-                               if ((nested == null) || ((ds != null) && 
!ds.CheckAccessLevel (nested)))
-                                       return null;
-
-                               return new TypeExpression (nested, 
Location.Null);
-                       }
-
-                       //
                        // Check whether it's in the namespace.
                        //
-                       o = NS.Lookup (ds, name, loc);
+                       FullNamedExpression o = NS.Lookup (ds, name, loc);
                        if (o != null)
                                return o;
 
+                       if (IsImplicit)
+                               return null;
+
                        //
                        // Check aliases.
                        //
@@ -501,9 +478,6 @@
                        if (o != null)
                                return o;
 
-                       if (name.IndexOf ('.') > 0)
-                               return null;
-
                        //
                        // Check using entries.
                        //
@@ -561,7 +535,7 @@
                        if (using_clauses != null) {
                                using_list = new string [using_clauses.Count];
                                for (int i = 0; i < using_clauses.Count; i++)
-                                       using_list [i] = ((UsingEntry) 
using_clauses [i]).Name;
+                                       using_list [i] = ((UsingEntry) 
using_clauses [i]).Name.ToString ();
                        } else {
                                using_list = new string [0];
                        }
@@ -629,8 +603,8 @@
                                        if (ue.Resolve () != null)
                                                continue;
 
-                                       if (LookupForUsing (ue.Name, 
ue.Location) == null)
-                                               error246 (ue.Location, ue.Name);
+                                       if (ue.resolved == null)
+                                               error246 (ue.Location, 
ue.Name.ToString ());
                                        else
                                                Report.Error (138, ue.Location, 
"The using keyword only lets you specify a namespace, " +
                                                              "`" + ue.Name + 
"' is a class not a namespace.");
@@ -645,7 +619,7 @@
                                        if (alias.Resolve () != null)
                                                continue;
 
-                                       error246 (alias.Location, 
alias.Alias.GetTypeName ());
+                                       error246 (alias.Location, 
alias.Alias.ToString ());
                                }
                        }
                }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to