diff dmd2/template.c @ 1526:54b3c1394d62

Merged dmdfe 2.031.
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 07 Jul 2009 02:26:11 +0100
parents 638d16625da2
children e4f7b5d9c68a
line wrap: on
line diff
--- a/dmd2/template.c	Mon Jul 06 23:57:27 2009 +0100
+++ b/dmd2/template.c	Tue Jul 07 02:26:11 2009 +0100
@@ -308,7 +308,7 @@
     this->members = decldefs;
     this->overnext = NULL;
     this->overroot = NULL;
-    this->scope = NULL;
+    this->semanticRun = 0;
     this->onemember = NULL;
     this->literal = 0;
 }
@@ -337,7 +337,6 @@
     td = new TemplateDeclaration(loc, ident, p, e, d);
 
 #if IN_LLVM
-    // LDC
     td->intrinsicName = intrinsicName;
 #endif
 
@@ -349,8 +348,9 @@
 #if LOG
     printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars());
 #endif
-    if (scope)
+    if (semanticRun)
 	return;		// semantic() already run
+    semanticRun = 1;
 
     if (sc->func)
     {
@@ -878,8 +878,8 @@
 	fvarargs = fctor->varargs;
     }
 
-    nfparams = Argument::dim(fparameters); // number of function parameters
-    nfargs = fargs->dim;		// number of function arguments
+    nfparams = Argument::dim(fparameters);	// number of function parameters
+    nfargs = fargs ? fargs->dim : 0;		// number of function arguments
 
     /* Check for match of function arguments with variadic template
      * parameter, such as:
@@ -1329,7 +1329,7 @@
 
     for (TemplateDeclaration *td = this; td; td = td->overnext)
     {
-	if (!td->scope)
+	if (!td->semanticRun)
 	{
 	    error("forward reference to template %s", td->toChars());
 	    goto Lerror;
@@ -3215,7 +3215,7 @@
     this->tinst = NULL;
     this->argsym = NULL;
     this->aliasdecl = NULL;
-    this->semanticdone = 0;
+    this->semanticRun = 0;
     this->semantictiargsdone = 0;
     this->withsym = NULL;
     this->nest = 0;
@@ -3249,7 +3249,7 @@
     this->tinst = NULL;
     this->argsym = NULL;
     this->aliasdecl = NULL;
-    this->semanticdone = 0;
+    this->semanticRun = 0;
     this->semantictiargsdone = 1;
     this->withsym = NULL;
     this->nest = 0;
@@ -3324,13 +3324,13 @@
     // get the enclosing template instance from the scope tinst
     tinst = sc->tinst;
 
-    if (semanticdone != 0)
+    if (semanticRun != 0)
     {
 	error(loc, "recursive template expansion");
 //	inst = this;
 	return;
     }
-    semanticdone = 1;
+    semanticRun = 1;
 #if IN_LLVM
     // get the enclosing template instance from the scope tinst
     tinst = sc->tinst;
@@ -3474,7 +3474,7 @@
 	{   Module *m = sc->module->importedFrom;
 	    //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars());
 	    a = m->members;
-	    if (m->semanticdone >= 3)
+	    if (m->semanticRun >= 3)
 		dosemantic3 = 1;
 	}
 	for (int i = 0; 1; i++)
@@ -3495,9 +3495,9 @@
 
     // Create our own scope for the template parameters
     Scope *scope = tempdecl->scope;
-    if (!scope)
+    if (!tempdecl->semanticRun)
     {
-	error("forward reference to template declaration %s\n", tempdecl->toChars());
+	error("template instantiation %s forward references template declaration %s\n", toChars(), tempdecl->toChars());
 	return;
     }
 
@@ -3717,6 +3717,7 @@
 	    }
 	    else if (ta)
 	    {
+	      Ltype:
 		if (ta->ty == Ttuple)
 		{   // Expand tuple
 		    TypeTuple *tt = (TypeTuple *)ta;
@@ -3752,12 +3753,26 @@
 		ea = ea->optimize(WANTvalue | WANTinterpret);
 	    tiargs->data[j] = ea;
 	    if (ea->op == TOKtype)
-		tiargs->data[j] = ea->type;
+	    {	ta = ea->type;
+		goto Ltype;
+	    }
+	    if (ea->op == TOKtuple)
+	    {   // Expand tuple
+		TupleExp *te = (TupleExp *)ea;
+		size_t dim = te->exps->dim;
+		tiargs->remove(j);
+		if (dim)
+		{   tiargs->reserve(dim);
+		    for (size_t i = 0; i < dim; i++)
+			tiargs->insert(j + i, te->exps->data[i]);
+		}
+		j--;
+	    }
 	}
 	else if (sa)
 	{
 	    TemplateDeclaration *td = sa->isTemplateDeclaration();
-	    if (td && !td->scope && td->literal)
+	    if (td && !td->semanticRun && td->literal)
 		td->semantic(sc);
 	}
 	else
@@ -3898,6 +3913,23 @@
 #if LOG
     printf("TemplateInstance::findBestMatch()\n");
 #endif
+    // First look for forward references
+    for (TemplateDeclaration *td = tempdecl; td; td = td->overnext)
+    {
+	if (!td->semanticRun)
+	{
+	    if (td->scope)
+	    {	// Try to fix forward reference
+		td->semantic(td->scope);
+	    }
+	    if (!td->semanticRun)
+	    {
+		error("%s forward references template declaration %s\n", toChars(), td->toChars());
+		return NULL;
+	    }
+	}
+    }
+
     for (TemplateDeclaration *td = tempdecl; td; td = td->overnext)
     {
 	MATCH m;
@@ -3914,11 +3946,7 @@
 
 	dedtypes.setDim(td->parameters->dim);
 	dedtypes.zero();
-	if (!td->scope)
-	{
-	    error("forward reference to template declaration %s", td->toChars());
-	    return NULL;
-	}
+	assert(td->semanticRun);
 	m = td->matchWithInstance(this, &dedtypes, 0);
 	//printf("matchWithInstance = %d\n", m);
 	if (!m)			// no match at all
@@ -4212,7 +4240,7 @@
  * template instance arguments.
  */
 
-void TemplateInstance::declareParameters(Scope *scope)
+void TemplateInstance::declareParameters(Scope *sc)
 {
     //printf("TemplateInstance::declareParameters()\n");
     for (int i = 0; i < tdtypes.dim; i++)
@@ -4222,7 +4250,7 @@
 	Object *o = (Object *)tdtypes.data[i];		// initializer for tp
 
 	//printf("\ttdtypes[%d] = %p\n", i, o);
-	tempdecl->declareParameter(scope, tp, o);
+	tempdecl->declareParameter(sc, tp, o);
     }
 }
 
@@ -4230,9 +4258,9 @@
 void TemplateInstance::semantic2(Scope *sc)
 {   int i;
 
-    if (semanticdone >= 2)
+    if (semanticRun >= 2)
 	return;
-    semanticdone = 2;
+    semanticRun = 2;
 #if LOG
     printf("+TemplateInstance::semantic2('%s')\n", toChars());
 #endif
@@ -4262,12 +4290,12 @@
 void TemplateInstance::semantic3(Scope *sc)
 {
 #if LOG
-    printf("TemplateInstance::semantic3('%s'), semanticdone = %d\n", toChars(), semanticdone);
+    printf("TemplateInstance::semantic3('%s'), semanticRun = %d\n", toChars(), semanticRun);
 #endif
 //if (toChars()[0] == 'D') *(char*)0=0;
-    if (semanticdone >= 3)
+    if (semanticRun >= 3)
 	return;
-    semanticdone = 3;
+    semanticRun = 3;
     if (!errors && members)
     {
 	sc = tempdecl->scope;
@@ -4457,7 +4485,6 @@
     this->tqual = tqual;
     this->idents = idents;
     this->tiargs = tiargs ? tiargs : new Objects();
-    this->scope = NULL;
 }
 
 Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s)
@@ -4491,7 +4518,7 @@
     printf("+TemplateMixin::semantic('%s', this=%p)\n", toChars(), this);
     fflush(stdout);
 #endif
-    if (semanticdone &&
+    if (semanticRun &&
 	// This for when a class/struct contains mixin members, and
 	// is done over because of forward references
 	(!parent || !toParent()->isAggregateDeclaration()))
@@ -4501,8 +4528,8 @@
 #endif
 	return;
     }
-    if (!semanticdone)
-	semanticdone = 1;
+    if (!semanticRun)
+	semanticRun = 1;
 #if LOG
     printf("\tdo semantic\n");
 #endif
@@ -4577,7 +4604,7 @@
     assert(tempdecl);
     for (TemplateDeclaration *td = tempdecl; td; td = td->overnext)
     {
-	if (!td->scope)
+	if (!td->semanticRun)
 	{
 	    /* Cannot handle forward references if mixin is a struct member,
 	     * because addField must happen during struct's semantic, not
@@ -4585,7 +4612,7 @@
 	     * runDeferred will re-run mixin's semantic outside of the struct's
 	     * semantic.
 	     */
-	    semanticdone = 0;
+	    semanticRun = 0;
 	    AggregateDeclaration *ad = toParent()->isAggregateDeclaration();
 	    if (ad)
 		ad->sizeok = 2;
@@ -4691,19 +4718,19 @@
 
     argsym = new ScopeDsymbol();
     argsym->parent = scy->parent;
-    Scope *scope = scy->push(argsym);
+    Scope *argscope = scy->push(argsym);
 
     unsigned errorsave = global.errors;
 
     // Declare each template parameter as an alias for the argument type
-    declareParameters(scope);
+    declareParameters(argscope);
 
     // Add members to enclosing scope, as well as this scope
     for (unsigned i = 0; i < members->dim; i++)
     {   Dsymbol *s;
 
 	s = (Dsymbol *)members->data[i];
-	s->addMember(scope, this, i);
+	s->addMember(argscope, this, i);
 	//sc->insert(s);
 	//printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym);
 	//printf("s->parent = %s\n", s->parent->toChars());
@@ -4714,7 +4741,7 @@
     printf("\tdo semantic() on template instance members '%s'\n", toChars());
 #endif
     Scope *sc2;
-    sc2 = scope->push(this);
+    sc2 = argscope->push(this);
     sc2->offset = sc->offset;
 
     static int nest;
@@ -4757,7 +4784,7 @@
 
     sc2->pop();
 
-    scope->pop();
+    argscope->pop();
 
 //    if (!isAnonymous())
     {
@@ -4771,9 +4798,9 @@
 void TemplateMixin::semantic2(Scope *sc)
 {   int i;
 
-    if (semanticdone >= 2)
+    if (semanticRun >= 2)
 	return;
-    semanticdone = 2;
+    semanticRun = 2;
 #if LOG
     printf("+TemplateMixin::semantic2('%s')\n", toChars());
 #endif
@@ -4801,9 +4828,9 @@
 void TemplateMixin::semantic3(Scope *sc)
 {   int i;
 
-    if (semanticdone >= 3)
+    if (semanticRun >= 3)
 	return;
-    semanticdone = 3;
+    semanticRun = 3;
 #if LOG
     printf("TemplateMixin::semantic3('%s')\n", toChars());
 #endif