diff dmd/scope.c @ 159:5acec6b2eef8 trunk

[svn r175] merged dmd 1.029
author ChristianK
date Thu, 01 May 2008 15:15:28 +0200
parents 8f704cb9969b
children a58d8f4b84df
line wrap: on
line diff
--- a/dmd/scope.c	Thu May 01 13:33:02 2008 +0200
+++ b/dmd/scope.c	Thu May 01 15:15:28 2008 +0200
@@ -1,359 +1,361 @@
-
-// Copyright (c) 1999-2005 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "root.h"
-
-#include "mars.h"
-#include "init.h"
-#include "identifier.h"
-#include "attrib.h"
-#include "dsymbol.h"
-#include "scope.h"
-#include "declaration.h"
-#include "aggregate.h"
-#include "module.h"
-#include "id.h"
-
-Scope *Scope::freelist = NULL;
-
-void *Scope::operator new(size_t size)
-{
-    if (freelist)
-    {
-	Scope *s = freelist;
-	freelist = s->enclosing;
-	//printf("freelist %p\n", s);
-	assert(s->flags & SCOPEfree);
-	s->flags &= ~SCOPEfree;
-	return s;
-    }
-
-    void *p = ::operator new(size);
-    //printf("new %p\n", p);
-    return p;
-}
-
-Scope::Scope()
-{   // Create root scope
-
-    //printf("Scope::Scope() %p\n", this);
-    this->module = NULL;
-    this->scopesym = NULL;
-    this->sd = NULL;
-    this->enclosing = NULL;
-    this->parent = NULL;
-    this->sw = NULL;
-    this->tf = NULL;
-    this->tfOfTry = NULL;
-    this->sbreak = NULL;
-    this->scontinue = NULL;
-    this->fes = NULL;
-    this->structalign = global.structalign;
-    this->func = NULL;
-    this->slabel = NULL;
-    this->linkage = LINKd;
-    this->protection = PROTpublic;
-    this->explicitProtection = 0;
-    this->stc = 0;
-    this->offset = 0;
-    this->inunion = 0;
-    this->incontract = 0;
-    this->nofree = 0;
-    this->noctor = 0;
-    this->intypeof = 0;
-    this->parameterSpecialization = 0;
-    this->callSuper = 0;
-    this->flags = 0;
-    this->anonAgg = NULL;
-    this->lastdc = NULL;
-    this->lastoffset = 0;
-    this->docbuf = NULL;
-}
-
-Scope::Scope(Scope *enclosing)
-{
-    //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
-    assert(!(enclosing->flags & SCOPEfree));
-    this->module = enclosing->module;
-    this->func   = enclosing->func;
-    this->parent = enclosing->parent;
-    this->scopesym = NULL;
-    this->sd = NULL;
-    this->sw = enclosing->sw;
-    this->tf = enclosing->tf;
-    this->tfOfTry = enclosing->tfOfTry;
-    this->sbreak = enclosing->sbreak;
-    this->scontinue = enclosing->scontinue;
-    this->fes = enclosing->fes;
-    this->structalign = enclosing->structalign;
-    this->enclosing = enclosing;
-#ifdef DEBUG
-    if (enclosing->enclosing)
-	assert(!(enclosing->enclosing->flags & SCOPEfree));
-    if (this == enclosing->enclosing)
-    {
-	printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
-    }
-    assert(this != enclosing->enclosing);
-#endif
-    this->slabel = NULL;
-    this->linkage = enclosing->linkage;
-    this->protection = enclosing->protection;
-    this->explicitProtection = enclosing->explicitProtection;
-    this->stc = enclosing->stc;
-    this->offset = 0;
-    this->inunion = enclosing->inunion;
-    this->incontract = enclosing->incontract;
-    this->nofree = 0;
-    this->noctor = enclosing->noctor;
-    this->intypeof = enclosing->intypeof;
-    this->parameterSpecialization = enclosing->parameterSpecialization;
-    this->callSuper = enclosing->callSuper;
-    this->flags = 0;
-    this->anonAgg = NULL;
-    this->lastdc = NULL;
-    this->lastoffset = 0;
-    this->docbuf = enclosing->docbuf;
-    assert(this != enclosing);
-}
-
-Scope *Scope::createGlobal(Module *module)
-{
-    Scope *sc;
-
-    sc = new Scope();
-    sc->module = module;
-    sc->scopesym = new ScopeDsymbol();
-    sc->scopesym->symtab = new DsymbolTable();
-
-    // Add top level package as member of this global scope
-    Dsymbol *m = module;
-    while (m->parent)
-	m = m->parent;
-    m->addMember(NULL, sc->scopesym, 1);
-    m->parent = NULL;			// got changed by addMember()
-
-    // Create the module scope underneath the global scope
-    sc = sc->push(module);
-    sc->parent = module;
-    return sc;
-}
-
-Scope *Scope::push()
-{
-    //printf("Scope::push()\n");
-    Scope *s = new Scope(this);
-    assert(this != s);
-    return s;
-}
-
-Scope *Scope::push(ScopeDsymbol *ss)
-{
-    //printf("Scope::push(%s)\n", ss->toChars());
-    Scope *s = push();
-    s->scopesym = ss;
-    return s;
-}
-
-Scope *Scope::pop()
-{
-    //printf("Scope::pop() %p nofree = %d\n", this, nofree);
-    Scope *enc = enclosing;
-
-    if (enclosing)
-	enclosing->callSuper |= callSuper;
-
-    if (!nofree)
-    {	enclosing = freelist;
-	freelist = this;
-	flags |= SCOPEfree;
-    }
-
-    return enc;
-}
-
-void Scope::mergeCallSuper(Loc loc, unsigned cs)
-{
-    // This does a primitive flow analysis to support the restrictions
-    // regarding when and how constructors can appear.
-    // It merges the results of two paths.
-    // The two paths are callSuper and cs; the result is merged into callSuper.
-
-    if (cs != callSuper)
-    {	int a;
-	int b;
-
-	callSuper |= cs & (CSXany_ctor | CSXlabel);
-	if (cs & CSXreturn)
-	{
-	}
-	else if (callSuper & CSXreturn)
-	{
-	    callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
-	}
-	else
-	{
-	    a = (cs        & (CSXthis_ctor | CSXsuper_ctor)) != 0;
-	    b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
-	    if (a != b)
-		error(loc, "one path skips constructor");
-	    callSuper |= cs;
-	}
-    }
-}
-
-Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
-{   Dsymbol *s;
-    Scope *sc;
-
-    //printf("Scope::search(%p, '%s')\n", this, ident->toChars());
-    if (ident == Id::empty)
-    {
-	// Look for module scope
-	for (sc = this; sc; sc = sc->enclosing)
-	{
-	    assert(sc != sc->enclosing);
-	    if (sc->scopesym)
-	    {
-		s = sc->scopesym->isModule();
-		if (s)
-		{
-		    //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
-		    if (pscopesym)
-			*pscopesym = sc->scopesym;
-		    return s;
-		}
-	    }
-	}
-	return NULL;
-    }
-
-    for (sc = this; sc; sc = sc->enclosing)
-    {
-	assert(sc != sc->enclosing);
-	if (sc->scopesym)
-	{
-	    //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
-	    s = sc->scopesym->search(loc, ident, 0);
-	    if (s)
-	    {
-		if ((global.params.warnings ||
-		    global.params.Dversion > 1) &&
-		    ident == Id::length &&
-		    sc->scopesym->isArrayScopeSymbol() &&
-		    sc->enclosing &&
-		    sc->enclosing->search(loc, ident, NULL))
-		{
-		    if (global.params.warnings)
-			fprintf(stdmsg, "warning - ");
-		    error(s->loc, "array 'length' hides other 'length' name in outer scope");
-		}
-
-		//printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
-		if (pscopesym)
-		    *pscopesym = sc->scopesym;
-		return s;
-	    }
-	}
-    }
-
-    return NULL;
-}
-
-Dsymbol *Scope::insert(Dsymbol *s)
-{   Scope *sc;
-
-    for (sc = this; sc; sc = sc->enclosing)
-    {
-	//printf("\tsc = %p\n", sc);
-	if (sc->scopesym)
-	{
-	    //printf("\t\tsc->scopesym = %p\n", sc->scopesym);
-	    if (!sc->scopesym->symtab)
-		sc->scopesym->symtab = new DsymbolTable();
-	    return sc->scopesym->symtab->insert(s);
-	}
-    }
-    assert(0);
-    return NULL;
-}
-
-/********************************************
- * Search enclosing scopes for ClassDeclaration.
- */
-
-ClassDeclaration *Scope::getClassScope()
-{   Scope *sc;
-
-    for (sc = this; sc; sc = sc->enclosing)
-    {
-	ClassDeclaration *cd;
-
-	if (sc->scopesym)
-	{
-	    cd = sc->scopesym->isClassDeclaration();
-	    if (cd)
-		return cd;
-	}
-    }
-    return NULL;
-}
-
-/********************************************
- * Search enclosing scopes for ClassDeclaration.
- */
-
-AggregateDeclaration *Scope::getStructClassScope()
-{   Scope *sc;
-
-    for (sc = this; sc; sc = sc->enclosing)
-    {
-	AggregateDeclaration *ad;
-
-	if (sc->scopesym)
-	{
-	    ad = sc->scopesym->isClassDeclaration();
-	    if (ad)
-		return ad;
-	    else
-	    {	ad = sc->scopesym->isStructDeclaration();
-		if (ad)
-		    return ad;
-	    }
-	}
-    }
-    return NULL;
-}
-
-/*******************************************
- * For TemplateDeclarations, we need to remember the Scope
- * where it was declared. So mark the Scope as not
- * to be free'd.
- */
-
-void Scope::setNoFree()
-{   Scope *sc;
-    //int i = 0;
-
-    //printf("Scope::setNoFree(this = %p)\n", this);
-    for (sc = this; sc; sc = sc->enclosing)
-    {
-	//printf("\tsc = %p\n", sc);
-	sc->nofree = 1;
-
-	assert(!(flags & SCOPEfree));
-	//assert(sc != sc->enclosing);
-	//assert(!sc->enclosing || sc != sc->enclosing->enclosing);
-	//if (++i == 10)
-	    //assert(0);
-    }
-}
+
+// Copyright (c) 1999-2005 by Digital Mars
+// All Rights Reserved
+// written by Walter Bright
+// http://www.digitalmars.com
+// License for redistribution is by either the Artistic License
+// in artistic.txt, or the GNU General Public License in gnu.txt.
+// See the included readme.txt for details.
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "root.h"
+
+#include "mars.h"
+#include "init.h"
+#include "identifier.h"
+#include "attrib.h"
+#include "dsymbol.h"
+#include "scope.h"
+#include "declaration.h"
+#include "aggregate.h"
+#include "module.h"
+#include "id.h"
+
+Scope *Scope::freelist = NULL;
+
+void *Scope::operator new(size_t size)
+{
+    if (freelist)
+    {
+	Scope *s = freelist;
+	freelist = s->enclosing;
+	//printf("freelist %p\n", s);
+	assert(s->flags & SCOPEfree);
+	s->flags &= ~SCOPEfree;
+	return s;
+    }
+
+    void *p = ::operator new(size);
+    //printf("new %p\n", p);
+    return p;
+}
+
+Scope::Scope()
+{   // Create root scope
+
+    //printf("Scope::Scope() %p\n", this);
+    this->module = NULL;
+    this->scopesym = NULL;
+    this->sd = NULL;
+    this->enclosing = NULL;
+    this->parent = NULL;
+    this->sw = NULL;
+    this->tf = NULL;
+    this->tfOfTry = NULL;
+    this->sbreak = NULL;
+    this->scontinue = NULL;
+    this->fes = NULL;
+    this->structalign = global.structalign;
+    this->func = NULL;
+    this->slabel = NULL;
+    this->linkage = LINKd;
+    this->protection = PROTpublic;
+    this->explicitProtection = 0;
+    this->stc = 0;
+    this->offset = 0;
+    this->inunion = 0;
+    this->incontract = 0;
+    this->nofree = 0;
+    this->noctor = 0;
+    this->noaccesscheck = 0;
+    this->intypeof = 0;
+    this->parameterSpecialization = 0;
+    this->callSuper = 0;
+    this->flags = 0;
+    this->anonAgg = NULL;
+    this->lastdc = NULL;
+    this->lastoffset = 0;
+    this->docbuf = NULL;
+}
+
+Scope::Scope(Scope *enclosing)
+{
+    //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
+    assert(!(enclosing->flags & SCOPEfree));
+    this->module = enclosing->module;
+    this->func   = enclosing->func;
+    this->parent = enclosing->parent;
+    this->scopesym = NULL;
+    this->sd = NULL;
+    this->sw = enclosing->sw;
+    this->tf = enclosing->tf;
+    this->tfOfTry = enclosing->tfOfTry;
+    this->sbreak = enclosing->sbreak;
+    this->scontinue = enclosing->scontinue;
+    this->fes = enclosing->fes;
+    this->structalign = enclosing->structalign;
+    this->enclosing = enclosing;
+#ifdef DEBUG
+    if (enclosing->enclosing)
+	assert(!(enclosing->enclosing->flags & SCOPEfree));
+    if (this == enclosing->enclosing)
+    {
+	printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
+    }
+    assert(this != enclosing->enclosing);
+#endif
+    this->slabel = NULL;
+    this->linkage = enclosing->linkage;
+    this->protection = enclosing->protection;
+    this->explicitProtection = enclosing->explicitProtection;
+    this->stc = enclosing->stc;
+    this->offset = 0;
+    this->inunion = enclosing->inunion;
+    this->incontract = enclosing->incontract;
+    this->nofree = 0;
+    this->noctor = enclosing->noctor;
+    this->noaccesscheck = enclosing->noaccesscheck;
+    this->intypeof = enclosing->intypeof;
+    this->parameterSpecialization = enclosing->parameterSpecialization;
+    this->callSuper = enclosing->callSuper;
+    this->flags = 0;
+    this->anonAgg = NULL;
+    this->lastdc = NULL;
+    this->lastoffset = 0;
+    this->docbuf = enclosing->docbuf;
+    assert(this != enclosing);
+}
+
+Scope *Scope::createGlobal(Module *module)
+{
+    Scope *sc;
+
+    sc = new Scope();
+    sc->module = module;
+    sc->scopesym = new ScopeDsymbol();
+    sc->scopesym->symtab = new DsymbolTable();
+
+    // Add top level package as member of this global scope
+    Dsymbol *m = module;
+    while (m->parent)
+	m = m->parent;
+    m->addMember(NULL, sc->scopesym, 1);
+    m->parent = NULL;			// got changed by addMember()
+
+    // Create the module scope underneath the global scope
+    sc = sc->push(module);
+    sc->parent = module;
+    return sc;
+}
+
+Scope *Scope::push()
+{
+    //printf("Scope::push()\n");
+    Scope *s = new Scope(this);
+    assert(this != s);
+    return s;
+}
+
+Scope *Scope::push(ScopeDsymbol *ss)
+{
+    //printf("Scope::push(%s)\n", ss->toChars());
+    Scope *s = push();
+    s->scopesym = ss;
+    return s;
+}
+
+Scope *Scope::pop()
+{
+    //printf("Scope::pop() %p nofree = %d\n", this, nofree);
+    Scope *enc = enclosing;
+
+    if (enclosing)
+	enclosing->callSuper |= callSuper;
+
+    if (!nofree)
+    {	enclosing = freelist;
+	freelist = this;
+	flags |= SCOPEfree;
+    }
+
+    return enc;
+}
+
+void Scope::mergeCallSuper(Loc loc, unsigned cs)
+{
+    // This does a primitive flow analysis to support the restrictions
+    // regarding when and how constructors can appear.
+    // It merges the results of two paths.
+    // The two paths are callSuper and cs; the result is merged into callSuper.
+
+    if (cs != callSuper)
+    {	int a;
+	int b;
+
+	callSuper |= cs & (CSXany_ctor | CSXlabel);
+	if (cs & CSXreturn)
+	{
+	}
+	else if (callSuper & CSXreturn)
+	{
+	    callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
+	}
+	else
+	{
+	    a = (cs        & (CSXthis_ctor | CSXsuper_ctor)) != 0;
+	    b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
+	    if (a != b)
+		error(loc, "one path skips constructor");
+	    callSuper |= cs;
+	}
+    }
+}
+
+Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
+{   Dsymbol *s;
+    Scope *sc;
+
+    //printf("Scope::search(%p, '%s')\n", this, ident->toChars());
+    if (ident == Id::empty)
+    {
+	// Look for module scope
+	for (sc = this; sc; sc = sc->enclosing)
+	{
+	    assert(sc != sc->enclosing);
+	    if (sc->scopesym)
+	    {
+		s = sc->scopesym->isModule();
+		if (s)
+		{
+		    //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
+		    if (pscopesym)
+			*pscopesym = sc->scopesym;
+		    return s;
+		}
+	    }
+	}
+	return NULL;
+    }
+
+    for (sc = this; sc; sc = sc->enclosing)
+    {
+	assert(sc != sc->enclosing);
+	if (sc->scopesym)
+	{
+	    //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
+	    s = sc->scopesym->search(loc, ident, 0);
+	    if (s)
+	    {
+		if ((global.params.warnings ||
+		    global.params.Dversion > 1) &&
+		    ident == Id::length &&
+		    sc->scopesym->isArrayScopeSymbol() &&
+		    sc->enclosing &&
+		    sc->enclosing->search(loc, ident, NULL))
+		{
+		    if (global.params.warnings)
+			fprintf(stdmsg, "warning - ");
+		    error(s->loc, "array 'length' hides other 'length' name in outer scope");
+		}
+
+		//printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
+		if (pscopesym)
+		    *pscopesym = sc->scopesym;
+		return s;
+	    }
+	}
+    }
+
+    return NULL;
+}
+
+Dsymbol *Scope::insert(Dsymbol *s)
+{   Scope *sc;
+
+    for (sc = this; sc; sc = sc->enclosing)
+    {
+	//printf("\tsc = %p\n", sc);
+	if (sc->scopesym)
+	{
+	    //printf("\t\tsc->scopesym = %p\n", sc->scopesym);
+	    if (!sc->scopesym->symtab)
+		sc->scopesym->symtab = new DsymbolTable();
+	    return sc->scopesym->symtab->insert(s);
+	}
+    }
+    assert(0);
+    return NULL;
+}
+
+/********************************************
+ * Search enclosing scopes for ClassDeclaration.
+ */
+
+ClassDeclaration *Scope::getClassScope()
+{   Scope *sc;
+
+    for (sc = this; sc; sc = sc->enclosing)
+    {
+	ClassDeclaration *cd;
+	
+	if (sc->scopesym)
+	{
+	    cd = sc->scopesym->isClassDeclaration();
+	    if (cd)
+		return cd;
+	}
+    }
+    return NULL;
+}
+
+/********************************************
+ * Search enclosing scopes for ClassDeclaration.
+ */
+
+AggregateDeclaration *Scope::getStructClassScope()
+{   Scope *sc;
+
+    for (sc = this; sc; sc = sc->enclosing)
+    {
+	AggregateDeclaration *ad;
+	
+	if (sc->scopesym)
+	{
+	    ad = sc->scopesym->isClassDeclaration();
+	    if (ad)
+		return ad;
+	    else
+	    {	ad = sc->scopesym->isStructDeclaration();
+		if (ad)
+		    return ad;
+	    }
+	}
+    }
+    return NULL;
+}
+
+/*******************************************
+ * For TemplateDeclarations, we need to remember the Scope
+ * where it was declared. So mark the Scope as not
+ * to be free'd.
+ */
+
+void Scope::setNoFree()
+{   Scope *sc;
+    //int i = 0;
+
+    //printf("Scope::setNoFree(this = %p)\n", this);
+    for (sc = this; sc; sc = sc->enclosing)
+    {
+	//printf("\tsc = %p\n", sc);
+	sc->nofree = 1;
+
+	assert(!(flags & SCOPEfree));
+	//assert(sc != sc->enclosing);
+	//assert(!sc->enclosing || sc != sc->enclosing->enclosing);
+	//if (++i == 10)
+	    //assert(0);
+    }
+}