diff dmd/module.c @ 1587:def7a1d494fd

Merge DMD 1.051
author Christian Kamm <kamm incasoftware de>
date Fri, 06 Nov 2009 23:58:01 +0100
parents 68dea5bae9e9
children 44b145be2ef5
line wrap: on
line diff
--- a/dmd/module.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/module.c	Fri Nov 06 23:58:01 2009 +0100
@@ -95,7 +95,7 @@
     searchCacheSymbol = NULL;
     searchCacheFlags = 0;
     semanticstarted = 0;
-    semanticdone = 0;
+    semanticRun = 0;
     decldefs = NULL;
     vmoduleinfo = NULL;
 #if IN_DMD
@@ -123,6 +123,7 @@
 
     macrotable = NULL;
     escapetable = NULL;
+    safe = FALSE;
 #if IN_DMD
     doppelganger = 0;
     cov = NULL;
@@ -661,9 +662,65 @@
     }
 }
 
-void Module::semantic(Scope* unused_sc)
-{   int i;
+void Module::importAll(Scope *prevsc)
+{
+    //printf("+Module::importAll(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
+
+    if (scope)
+	return;			// already done
+
+    /* Note that modules get their own scope, from scratch.
+     * This is so regardless of where in the syntax a module
+     * gets imported, it is unaffected by context.
+     * Ignore prevsc.
+     */
+    Scope *sc = Scope::createGlobal(this);	// create root scope
+
+    // Add import of "object" if this module isn't "object"
+    if (ident != Id::object)
+    {
+	if (members->dim == 0 || ((Dsymbol *)members->data[0])->ident != Id::object)
+	{
+	    Import *im = new Import(0, NULL, Id::object, NULL, 0);
+	    members->shift(im);
+	}
+    }
 
+    if (!symtab)
+    {
+	// Add all symbols into module's symbol table
+	symtab = new DsymbolTable();
+	for (int i = 0; i < members->dim; i++)
+	{
+	    Dsymbol *s = (Dsymbol *)members->data[i];
+	    s->addMember(NULL, sc->scopesym, 1);
+	}
+    }
+    // anything else should be run after addMember, so version/debug symbols are defined
+
+    /* Set scope for the symbols so that if we forward reference
+     * a symbol, it can possibly be resolved on the spot.
+     * If this works out well, it can be extended to all modules
+     * before any semantic() on any of them.
+     */
+    setScope(sc);		// remember module scope for semantic
+    for (int i = 0; i < members->dim; i++)
+    {	Dsymbol *s = (Dsymbol *)members->data[i];
+	s->setScope(sc);
+    }
+
+    for (int i = 0; i < members->dim; i++)
+    {
+	Dsymbol *s = (Dsymbol *)members->data[i];
+	s->importAll(sc);
+    }
+
+    sc = sc->pop();
+    sc->pop();		// 2 pops because Scope::createGlobal() created 2
+}
+
+void Module::semantic(Scope *unused_sc)
+{
     if (semanticstarted)
 	return;
 
@@ -673,10 +730,15 @@
     // Note that modules get their own scope, from scratch.
     // This is so regardless of where in the syntax a module
     // gets imported, it is unaffected by context.
-    Scope *sc = Scope::createGlobal(this);	// create root scope
+    Scope *sc = scope;			// see if already got one from importAll()
+    if (!sc)
+    {	printf("test2\n");
+	Scope::createGlobal(this);	// create root scope
+    }
 
     //printf("Module = %p, linkage = %d\n", sc->scopesym, sc->linkage);
 
+#if 0
     // Add import of "object" if this module isn't "object"
     if (ident != Id::object)
     {
@@ -686,26 +748,36 @@
 
     // Add all symbols into module's symbol table
     symtab = new DsymbolTable();
-    for (i = 0; i < members->dim; i++)
-    {	Dsymbol *s;
-
-	s = (Dsymbol *)members->data[i];
+    for (int i = 0; i < members->dim; i++)
+    {	Dsymbol *s = (Dsymbol *)members->data[i];
 	s->addMember(NULL, sc->scopesym, 1);
     }
 
+    /* Set scope for the symbols so that if we forward reference
+     * a symbol, it can possibly be resolved on the spot.
+     * If this works out well, it can be extended to all modules
+     * before any semantic() on any of them.
+     */
+    for (int i = 0; i < members->dim; i++)
+    {	Dsymbol *s = (Dsymbol *)members->data[i];
+	s->setScope(sc);
+    }
+#endif
+
     // Pass 1 semantic routines: do public side of the definition
-    for (i = 0; i < members->dim; i++)
-    {	Dsymbol *s;
+    for (int i = 0; i < members->dim; i++)
+    {	Dsymbol *s = (Dsymbol *)members->data[i];
 
-	s = (Dsymbol *)members->data[i];
 	//printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars());
 	s->semantic(sc);
 	runDeferredSemantic();
     }
 
-    sc = sc->pop();
-    sc->pop();
-    semanticdone = semanticstarted;
+    if (!scope)
+    {	sc = sc->pop();
+	sc->pop();		// 2 pops because Scope::createGlobal() created 2
+    }
+    semanticRun = semanticstarted;
     //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
 }
 
@@ -744,7 +816,7 @@
 
     sc = sc->pop();
     sc->pop();
-    semanticdone = semanticstarted;
+    semanticRun = semanticstarted;
     //printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent);
 }
 
@@ -774,12 +846,11 @@
 
     sc = sc->pop();
     sc->pop();
-    semanticdone = semanticstarted;
+    semanticRun = semanticstarted;
 }
 
 void Module::inlineScan()
-{   int i;
-
+{
     if (semanticstarted >= 4)
 	return;
     assert(semanticstarted == 3);
@@ -790,16 +861,14 @@
     // gets imported, it is unaffected by context.
     //printf("Module = %p\n", sc.scopesym);
 
-    for (i = 0; i < members->dim; i++)
-    {	Dsymbol *s;
-
-	s = (Dsymbol *)members->data[i];
+    for (int i = 0; i < members->dim; i++)
+    {	Dsymbol *s = (Dsymbol *)members->data[i];
 	//if (global.params.verbose)
 	    //printf("inline scan symbol %s\n", s->toChars());
 
 	s->inlineScan();
     }
-    semanticdone = semanticstarted;
+    semanticRun = semanticstarted;
 }
 
 /****************************************************
@@ -844,6 +913,7 @@
 {
     /* Since modules can be circularly referenced,
      * need to stop infinite recursive searches.
+     * This is done with the cache.
      */
 
     //printf("%s Module::search('%s', flags = %d) insearch = %d\n", toChars(), ident->toChars(), flags, insearch);
@@ -851,7 +921,10 @@
     if (insearch)
 	s = NULL;
     else if (searchCacheIdent == ident && searchCacheFlags == flags)
+    {
 	s = searchCacheSymbol;
+	//printf("%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n", toChars(), ident->toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol->toChars() : "null");
+    }
     else
     {
 	insearch = 1;
@@ -865,6 +938,13 @@
     return s;
 }
 
+Dsymbol *Module::symtabInsert(Dsymbol *s)
+{
+    searchCacheIdent = 0;	// symbol is inserted, so invalidate cache
+    return Package::symtabInsert(s);
+}
+
+
 /*******************************************
  * Can't run semantic on s now, try again later.
  */
@@ -1059,11 +1139,14 @@
 	    else
 	    {
 		assert(p->isPackage());
+#if TARGET_NET  //dot net needs modules and packages with same name
+#else
 		if (p->isModule())
 		{   p->error("module and package have the same name");
 		    fatal();
 		    break;
 		}
+#endif
 	    }
 	    parent = p;
 	    dst = ((Package *)p)->symtab;