diff dmd/template.c @ 1103:b30fe7e1dbb9

- Updated to DMD frontend 1.041. - Removed dmd/inifile.c , it's not under a free license, replaced with libconfig based config file.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Thu, 12 Mar 2009 20:37:27 +0100
parents d33b0d4b816a
children 1860414bf3b7
line wrap: on
line diff
--- a/dmd/template.c	Thu Mar 12 14:08:57 2009 +0100
+++ b/dmd/template.c	Thu Mar 12 20:37:27 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -21,7 +21,7 @@
 #endif
 
 #include "root.h"
-#include "mem.h"
+#include "rmem.h"
 #include "stringtable.h"
 #include "mars.h"
 #include "identifier.h"
@@ -186,6 +186,16 @@
 	{
 	    goto Lnomatch;
 	}
+#if V2
+	VarDeclaration *v1 = s1->isVarDeclaration();
+	VarDeclaration *v2 = s2->isVarDeclaration();
+	if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest)
+	{   ExpInitializer *ei1 = v1->init->isExpInitializer();
+	    ExpInitializer *ei2 = v2->init->isExpInitializer();
+	    if (ei1 && ei2 && !ei1->exp->equals(ei2->exp))
+		goto Lnomatch;
+	}
+#endif
     }
     else if (v1)
     {
@@ -253,6 +263,20 @@
     }
 }
 
+#if V2
+Object *objectSyntaxCopy(Object *o)
+{
+    if (!o)
+	return NULL;
+    Type *t = isType(o);
+    if (t)
+	return t->syntaxCopy();
+    Expression *e = isExpression(o);
+    if (e)
+	return e->syntaxCopy();
+    return o;
+}
+#endif
 
 
 /* ======================== TemplateDeclaration ============================= */
@@ -279,6 +303,9 @@
     this->loc = loc;
     this->parameters = parameters;
     this->origParameters = parameters;
+#if V2
+    this->constraint = constraint;
+#endif
     this->members = decldefs;
     this->overnext = NULL;
     this->overroot = NULL;
@@ -303,6 +330,11 @@
 	    p->data[i] = (void *)tp->syntaxCopy();
 	}
     }
+#if V2
+    Expression *e = NULL;
+    if (constraint)
+	e = constraint->syntaxCopy();
+#endif
     d = Dsymbol::arraySyntaxCopy(members);
     td = new TemplateDeclaration(loc, ident, p, d);
     
@@ -352,6 +384,7 @@
     paramsym->parent = sc->parent;
     Scope *paramscope = sc->push(paramsym);
     paramscope->parameterSpecialization = 1;
+    paramscope->stc = 0;
 
     if (global.params.doDocComments)
     {
@@ -512,6 +545,7 @@
     ScopeDsymbol *paramsym = new ScopeDsymbol();
     paramsym->parent = scope->parent;
     Scope *paramscope = scope->push(paramsym);
+    paramscope->stc = 0;
 
     // Attempt type deduction
     m = MATCHexact;
@@ -763,7 +797,8 @@
 	memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
 
 	for (i = 0; i < nargsi; i++)
-	{   TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
+	{   assert(i < parameters->dim);
+	    TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
 	    MATCH m;
 	    Declaration *sparam;
 
@@ -800,6 +835,7 @@
 	    Tuple *t = new Tuple();
 	    //printf("t = %p\n", t);
 	    dedargs->data[parameters->dim - 1] = (void *)t;
+	    declareParameter(paramscope, tp, t);
 	    goto L2;
 	}
 	else if (nfargs < nfparams - 1)
@@ -835,6 +871,7 @@
 		{   Expression *farg = (Expression *)fargs->data[fptupindex + i];
 		    t->objects.data[i] = (void *)farg->type;
 		}
+		declareParameter(paramscope, tp, t);
 		goto L2;
 	    }
 	    fptupindex = -1;
@@ -1020,7 +1057,7 @@
 		     */
 		    Declaration *sparam;
 		    dedargs->data[i] = (void *)oded;
-		    MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
+		    MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam, 0);
 		    //printf("m2 = %d\n", m2);
 		    if (!m2)
 			goto Lnomatch;
@@ -1077,7 +1114,7 @@
 }
 
 /**************************************************
- * Declare template parameter tp with value o.
+ * Declare template parameter tp with value o, and install it in the scope sc.
  */
 
 void TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Object *o)
@@ -1260,8 +1297,8 @@
     }
     if (td_ambig)
     {
-	error(loc, "%s matches more than one function template declaration, %s and %s",
-		toChars(), td_best->toChars(), td_ambig->toChars());
+	error(loc, "matches more than one function template declaration:\n  %s\nand:\n  %s",
+		td_best->toChars(), td_ambig->toChars());
     }
 
     /* The best match is td_best with arguments tdargs.
@@ -1794,11 +1831,20 @@
 	    Expression *e1 = isExpression(o1);
 	    Expression *e2 = isExpression(o2);
 
+	    Dsymbol *s1 = isDsymbol(o1);
+	    Dsymbol *s2 = isDsymbol(o2);
+
+	    Tuple *v1 = isTuple(o1);
+	    Tuple *v2 = isTuple(o2);
 #if 0
 	    if (t1)	printf("t1 = %s\n", t1->toChars());
 	    if (t2)	printf("t2 = %s\n", t2->toChars());
 	    if (e1)	printf("e1 = %s\n", e1->toChars());
 	    if (e2)	printf("e2 = %s\n", e2->toChars());
+	    if (s1)	printf("s1 = %s\n", s1->toChars());
+	    if (s2)	printf("s2 = %s\n", s2->toChars());
+	    if (v1)	printf("v1 = %s\n", v1->toChars());
+	    if (v2)	printf("v2 = %s\n", v2->toChars());
 #endif
 
 	    if (t1 && t2)
@@ -1845,7 +1891,33 @@
 		    dedtypes->data[j] = e1;
 		}
 	    }
-	    // BUG: Need to handle alias and tuple parameters
+	    else if (s1 && t2 && t2->ty == Tident)
+	    {
+		j = templateParameterLookup(t2, parameters);
+		if (j == -1)
+		    goto Lnomatch;
+		TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
+		// BUG: use tp->matchArg() instead of the following
+		TemplateAliasParameter *ta = tp->isTemplateAliasParameter();
+		if (!ta)
+		    goto Lnomatch;
+		Dsymbol *s = (Dsymbol *)dedtypes->data[j];
+		if (s)
+		{
+		    if (!s1->equals(s))
+			goto Lnomatch;
+		}
+		else
+		{
+		    dedtypes->data[j] = s1;
+		}
+	    }
+	    else if (s1 && s2)
+	    {
+		if (!s1->equals(s2))
+		    goto Lnomatch;
+	    }
+	    // BUG: Need to handle tuple parameters
 	    else
 		goto Lnomatch;
 	}
@@ -2113,7 +2185,7 @@
 
 MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs,
 	int i, TemplateParameters *parameters, Objects *dedtypes,
-	Declaration **psparam)
+	Declaration **psparam, int flags)
 {
     //printf("TemplateTypeParameter::matchArg()\n");
     Type *t;
@@ -2357,7 +2429,7 @@
 
 MATCH TemplateAliasParameter::matchArg(Scope *sc,
 	Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
-	Declaration **psparam)
+	Declaration **psparam, int flags)
 {
     Dsymbol *sa;
     Object *oarg;
@@ -2569,7 +2641,7 @@
 
 MATCH TemplateValueParameter::matchArg(Scope *sc,
 	Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
-	Declaration **psparam)
+	Declaration **psparam, int flags)
 {
     //printf("TemplateValueParameter::matchArg()\n");
 
@@ -2766,7 +2838,7 @@
 MATCH TemplateTupleParameter::matchArg(Scope *sc,
 	Objects *tiargs, int i, TemplateParameters *parameters,
 	Objects *dedtypes,
-	Declaration **psparam)
+	Declaration **psparam, int flags)
 {
     //printf("TemplateTupleParameter::matchArg()\n");
 
@@ -3026,7 +3098,7 @@
 	}
     }
 
-    isNested(tiargs);
+    hasNestedArgs(tiargs);
 
     /* See if there is an existing TemplateInstantiation that already
      * implements the typeargs. If so, just refer to that one instead.
@@ -3101,12 +3173,16 @@
 
 	//if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
 	if (scx && scx->scopesym &&
-	    scx->scopesym->members && !scx->scopesym->isTemplateMixin() &&
-	    /* The following test should really be if scx->module recursively
-	     * imports itself. Because if it does, see bugzilla 2500.
+	    scx->scopesym->members && !scx->scopesym->isTemplateMixin()
+#if 1 // removed because it bloated compile times
+	    /* The problem is if A imports B, and B imports A, and both A
+	     * and B instantiate the same template, does the compilation of A
+	     * or the compilation of B do the actual instantiation?
+	     *
+	     * see bugzilla 2500.
 	     */
-	    //scx->module == tempdecl->getModule()
-	    !scx->module->imports(scx->module)
+	    && !scx->module->selfImports()
+#endif
 	   )
 	{
 	    //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
@@ -3151,7 +3227,10 @@
     scope = scope->push(argsym);
 
     // Declare each template parameter as an alias for the argument type
-    declareParameters(scope);
+    Scope *paramscope = scope->push();
+    paramscope->stc = 0;
+    declareParameters(paramscope);
+    paramscope->pop();
 
     // Add members of template instance to template instance symbol table
 //    parent = scope->scopesym;
@@ -3620,9 +3699,9 @@
  * generation of the TemplateDeclaration.
  */
 
-int TemplateInstance::isNested(Objects *args)
+int TemplateInstance::hasNestedArgs(Objects *args)
 {   int nested = 0;
-    //printf("TemplateInstance::isNested('%s')\n", tempdecl->ident->toChars());
+    //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
 
     /* A nested instance happens when an argument references a local
      * symbol that is on the stack.
@@ -3691,7 +3770,7 @@
 	}
 	else if (va)
 	{
-	    nested |= isNested(&va->objects);
+	    nested |= hasNestedArgs(&va->objects);
 	}
     }
     return nested;
@@ -3710,7 +3789,7 @@
 
     //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
     id = tempdecl->ident->toChars();
-    buf.printf("__T%"PRIuSIZE"%s", strlen(id), id);
+    buf.printf("__T%zu%s", strlen(id), id);
     args = tiargs;
     for (int i = 0; i < args->dim; i++)
     {   Object *o = (Object *)args->data[i];
@@ -3777,7 +3856,7 @@
 	    else
 	    {
 		char *p = sa->mangle();
-        buf.printf("%"PRIuSIZE"%s", strlen(p), p);
+		buf.printf("%zu%s", strlen(p), p);
 	    }
 	}
 	else if (va)