changeset 1615:3da302cc4966

Merge DMD r294: bugzilla 2816 Sudden-death static assert is not... bugzilla 2816 Sudden-death static assert is not very useful. --- dmd/expression.h | 12 ++++++ dmd/staticassert.c | 10 +--- dmd/template.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++---- dmd/template.h | 2 + 4 files changed, 117 insertions(+), 15 deletions(-)
author Leandro Lucarella <llucax@gmail.com>
date Wed, 06 Jan 2010 15:18:21 -0300
parents dbf7b54f542f
children c94049033c20
files dmd/expression.h dmd/staticassert.c dmd/template.c dmd/template.h
diffstat 4 files changed, 117 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/expression.h	Wed Jan 06 15:18:21 2010 -0300
+++ b/dmd/expression.h	Wed Jan 06 15:18:21 2010 -0300
@@ -1546,6 +1546,18 @@
 #endif
 };
 
+#if DMDV2
+struct PowExp : BinExp
+{
+    PowExp(Loc loc, Expression *e1, Expression *e2);
+    Expression *semantic(Scope *sc);
+
+    // For operator overloading
+    Identifier *opId();
+    Identifier *opId_r();
+};
+#endif
+
 struct ShlExp : BinExp
 {
     ShlExp(Loc loc, Expression *e1, Expression *e2);
--- a/dmd/staticassert.c	Wed Jan 06 15:18:21 2010 -0300
+++ b/dmd/staticassert.c	Wed Jan 06 15:18:21 2010 -0300
@@ -18,6 +18,7 @@
 #include "hdrgen.h"
 #include "scope.h"
 #include "template.h"
+#include "declaration.h"
 
 
 /********************************* AttribDeclaration ****************************/
@@ -48,10 +49,6 @@
 {
 }
 
-#include "scope.h"
-#include "template.h"
-#include "declaration.h"
-
 void StaticAssert::semantic2(Scope *sc)
 {
     Expression *e;
@@ -73,11 +70,10 @@
 	}
 	else
 	    error("(%s) is false", exp->toChars());
-		if(sc->tinst)
+	if (sc->tinst)
 	    sc->tinst->printInstantiationTrace();
-	  if (!global.gag) {
+	if (!global.gag)
 	      fatal();
-	  }
     }
     else if (!e->isBool(TRUE))
     {
--- a/dmd/template.c	Wed Jan 06 15:18:21 2010 -0300
+++ b/dmd/template.c	Wed Jan 06 15:18:21 2010 -0300
@@ -3497,7 +3497,28 @@
 
     if (sc->func || dosemantic3)
     {
-	semantic3(sc2);
+#if WINDOWS_SEH
+	__try
+	{
+#endif
+	    static int nest;
+	    if (++nest > 300)
+	    {
+		global.gag = 0;            // ensure error message gets printed
+		error("recursive expansion");
+		fatal();
+	    }
+	    semantic3(sc2);
+	    --nest;
+#if WINDOWS_SEH
+	}
+	__except (__ehfilter(GetExceptionInformation()))
+	{
+	    global.gag = 0;            // ensure error message gets printed
+	    error("recursive expansion");
+	    fatal();
+	}
+#endif
     }
 
   Laftersemantic:
@@ -3509,7 +3530,7 @@
     if (global.errors != errorsave)
     {
 	error("error instantiating");
-	if (tinst && !global.gag)
+	if (tinst)
 	{   tinst->printInstantiationTrace();
 	    fatal();
 	}
@@ -3672,7 +3693,7 @@
 	id = name;
 	s = sc->search(loc, id, &scopesym);
 	if (!s)
-	{   error("identifier '%s' is not defined", id->toChars());
+	{   error("template '%s' is not defined", id->toChars());
 	    return NULL;
 	}
 #if LOG
@@ -3978,20 +3999,18 @@
 
 Identifier *TemplateInstance::genIdent()
 {   OutBuffer buf;
-    char *id;
-    Objects *args;
 
     //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
-    id = tempdecl->ident->toChars();
+    char *id = tempdecl->ident->toChars();
     buf.printf("__T%zu%s", strlen(id), id);
-    args = tiargs;
+    Objects *args = tiargs;
     for (int i = 0; i < args->dim; i++)
     {   Object *o = (Object *)args->data[i];
 	Type *ta = isType(o);
 	Expression *ea = isExpression(o);
 	Dsymbol *sa = isDsymbol(o);
 	Tuple *va = isTuple(o);
-	//printf("\to %p ta %p ea %p sa %p va %p\n", o, ta, ea, sa, va);
+	//printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va);
 	if (ta)
 	{
 	    buf.writeByte('T');
@@ -4191,10 +4210,81 @@
 
 #if IN_DMD
 
+/**************************************
+ * Given an error instantiating the TemplateInstance,
+ * give the nested TemplateInstance instantiations that got
+ * us here. Those are a list threaded into the nested scopes.
+ */
 void TemplateInstance::printInstantiationTrace()
 {
     if (global.gag)
 	return;
+
+    const int max_shown = 6;
+    const char format[] = "%s:        instantiated from here: %s\n";
+
+    // determine instantiation depth and number of recursive instantiations
+    int n_instantiations = 1;
+    int n_totalrecursions = 0;
+    for (TemplateInstance *cur = this; cur; cur = cur->tinst)
+    {
+	++n_instantiations;
+	// If two instantiations use the same declaration, they are recursive.
+	// (this works even if they are instantiated from different places in the
+	// same template).
+	// In principle, we could also check for multiple-template recursion, but it's
+	// probably not worthwhile.
+	if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl
+	    && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc))
+	    ++n_totalrecursions;
+    }
+
+    // show full trace only if it's short or verbose is on
+    if (n_instantiations <= max_shown || global.params.verbose)
+    {
+	for (TemplateInstance *cur = this; cur; cur = cur->tinst)
+	{
+	    fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars());
+	}
+    }
+    else if (n_instantiations - n_totalrecursions <= max_shown)
+    {
+	// By collapsing recursive instantiations into a single line,
+	// we can stay under the limit.
+	int recursionDepth=0;
+	for (TemplateInstance *cur = this; cur; cur = cur->tinst)
+	{
+	    if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl
+		    && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc))
+	    {
+		++recursionDepth;
+	    }
+	    else
+	    {
+		if (recursionDepth)
+		    fprintf(stdmsg, "%s:        %d recursive instantiations from here: %s\n", cur->loc.toChars(), recursionDepth+2, cur->toChars());
+		else 
+		    fprintf(stdmsg,format, cur->loc.toChars(), cur->toChars());
+		recursionDepth = 0;
+	    }
+	}
+    }
+    else
+    {
+	// Even after collapsing the recursions, the depth is too deep.
+	// Just display the first few and last few instantiations.
+	size_t i = 0;
+	for (TemplateInstance *cur = this; cur; cur = cur->tinst)
+	{
+	    if (i == max_shown / 2)
+		fprintf(stdmsg,"    ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown);
+
+	    if (i < max_shown / 2 ||
+		i >= n_instantiations - max_shown + max_shown / 2)
+		fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars());
+	    ++i;
+	}
+    }
 }
 
 void TemplateInstance::toObjFile(int multiobj)
@@ -4277,7 +4367,9 @@
 	return inst->toAlias();
 
     if (aliasdecl)
+    {
 	return aliasdecl->toAlias();
+    }
 
     return inst;
 }
--- a/dmd/template.h	Wed Jan 06 15:18:21 2010 -0300
+++ b/dmd/template.h	Wed Jan 06 15:18:21 2010 -0300
@@ -89,6 +89,8 @@
     TemplateTupleParameter *isVariadic();
     int isOverloadable();
 
+    void makeParamNamesVisibleInConstraint(Scope *paramscope);
+
 #if IN_LLVM
     // LDC
     std::string intrinsicName;