annotate dmd/template.c @ 837:331a176c1f4f

Removed error on naked, not fully complete, but I'll be doing more work on it during this Christmas, and some things do work. Fixed taking delegate of final class method. see mini/delegate3.d.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 09 Dec 2008 14:07:30 +0100
parents eef8ac26c66c
children 330f999ade44
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2 // Compiler implementation of the D programming language
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3 // Copyright (c) 1999-2008 by Digital Mars
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4 // All Rights Reserved
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
5 // written by Walter Bright
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
6 // http://www.digitalmars.com
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
7 // License for redistribution is by either the Artistic License
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
9 // See the included readme.txt for details.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
10
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
11 // Handle template implementation
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
12
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
13 #include <stdio.h>
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
14 #include <assert.h>
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
15
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
16 #if !IN_LLVM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
17 #if _WIN32
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
18 #include <windows.h>
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
19 long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
20 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
21 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
22
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
23 #include "root.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
24 #include "mem.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
25 #include "stringtable.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
26 #include "mars.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
27 #include "identifier.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
28 #include "mtype.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
29 #include "template.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
30 #include "init.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
31 #include "expression.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
32 #include "scope.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
33 #include "module.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
34 #include "aggregate.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
35 #include "declaration.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
36 #include "dsymbol.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
37 #include "hdrgen.h"
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
38
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
39 #define LOG 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
40
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
41 /********************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
42 * These functions substitute for dynamic_cast. dynamic_cast does not work
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
43 * on earlier versions of gcc.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
44 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
45
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
46 Expression *isExpression(Object *o)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
47 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
48 //return dynamic_cast<Expression *>(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
49 if (!o || o->dyncast() != DYNCAST_EXPRESSION)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
50 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
51 return (Expression *)o;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
52 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
53
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
54 Dsymbol *isDsymbol(Object *o)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
55 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
56 //return dynamic_cast<Dsymbol *>(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
57 if (!o || o->dyncast() != DYNCAST_DSYMBOL)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
58 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
59 return (Dsymbol *)o;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
60 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
61
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
62 Type *isType(Object *o)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
63 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
64 //return dynamic_cast<Type *>(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
65 if (!o || o->dyncast() != DYNCAST_TYPE)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
66 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
67 return (Type *)o;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
68 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
69
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
70 Tuple *isTuple(Object *o)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
71 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
72 //return dynamic_cast<Tuple *>(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
73 if (!o || o->dyncast() != DYNCAST_TUPLE)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
74 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
75 return (Tuple *)o;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
76 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
77
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
78
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
79 /***********************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
80 * Try to get arg as a type.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
81 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
82
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
83 Type *getType(Object *o)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
84 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
85 Type *t = isType(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
86 if (!t)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
87 { Expression *e = isExpression(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
88 if (e)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
89 t = e->type;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
90 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
91 return t;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
92 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
93
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
94 Dsymbol *getDsymbol(Object *oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
95 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
96 Dsymbol *sa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
97 Expression *ea = isExpression(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
98 if (ea)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
99 { // Try to convert Expression to symbol
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
100 if (ea->op == TOKvar)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
101 sa = ((VarExp *)ea)->var;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
102 else if (ea->op == TOKfunction)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
103 sa = ((FuncExp *)ea)->fd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
104 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
105 sa = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
106 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
107 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
108 { // Try to convert Type to symbol
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
109 Type *ta = isType(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
110 if (ta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
111 sa = ta->toDsymbol(NULL);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
112 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
113 sa = isDsymbol(oarg); // if already a symbol
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
114 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
115 return sa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
116 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
117
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
118 /******************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
119 * If o1 matches o2, return 1.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
120 * Else, return 0.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
121 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
122
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
123 int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
124 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
125 Type *t1 = isType(o1);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
126 Type *t2 = isType(o2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
127 Expression *e1 = isExpression(o1);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
128 Expression *e2 = isExpression(o2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
129 Dsymbol *s1 = isDsymbol(o1);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
130 Dsymbol *s2 = isDsymbol(o2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
131 Tuple *v1 = isTuple(o1);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
132 Tuple *v2 = isTuple(o2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
133
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
134 //printf("\t match t1 %p t2 %p, e1 %p e2 %p, s1 %p s2 %p, v1 %p v2 %p\n", t1,t2,e1,e2,s1,s2,v1,v2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
135
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
136 /* A proper implementation of the various equals() overrides
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
137 * should make it possible to just do o1->equals(o2), but
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
138 * we'll do that another day.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
139 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
140
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
141 if (t1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
142 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
143 /* if t1 is an instance of ti, then give error
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
144 * about recursive expansions.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
145 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
146 Dsymbol *s = t1->toDsymbol(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
147 if (s && s->parent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
148 { TemplateInstance *ti1 = s->parent->isTemplateInstance();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
149 if (ti1 && ti1->tempdecl == tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
150 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
151 for (Scope *sc1 = sc; sc1; sc1 = sc1->enclosing)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
152 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
153 if (sc1->scopesym == ti1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
154 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
155 error("recursive template expansion for template argument %s", t1->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
156 return 1; // fake a match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
157 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
158 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
159 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
160 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
161
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
162 if (!t2 || !t1->equals(t2))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
163 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
164 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
165 else if (e1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
166 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
167 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
168 if (e1 && e2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
169 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
170 printf("match %d\n", e1->equals(e2));
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
171 e1->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
172 e2->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
173 e1->type->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
174 e2->type->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
175 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
176 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
177 if (!e2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
178 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
179 if (!e1->equals(e2))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
180 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
181 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
182 else if (s1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
183 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
184 //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
185 if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
186 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
187 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
188 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
189 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
190 else if (v1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
191 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
192 if (!v2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
193 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
194 if (v1->objects.dim != v2->objects.dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
195 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
196 for (size_t i = 0; i < v1->objects.dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
197 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
198 if (!match((Object *)v1->objects.data[i],
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
199 (Object *)v2->objects.data[i],
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
200 tempdecl, sc))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
201 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
202 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
203 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
204 return 1; // match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
205 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
206 return 0; // nomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
207 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
208
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
209 /****************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
210 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
211
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
212 void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
213 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
214 //printf("ObjectToCBuffer()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
215 Type *t = isType(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
216 Expression *e = isExpression(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
217 Dsymbol *s = isDsymbol(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
218 Tuple *v = isTuple(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
219 if (t)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
220 { //printf("\tt: %s ty = %d\n", t->toChars(), t->ty);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
221 t->toCBuffer(buf, NULL, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
222 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
223 else if (e)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
224 e->toCBuffer(buf, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
225 else if (s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
226 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
227 char *p = s->ident ? s->ident->toChars() : s->toChars();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
228 buf->writestring(p);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
229 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
230 else if (v)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
231 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
232 Objects *args = &v->objects;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
233 for (size_t i = 0; i < args->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
234 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
235 if (i)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
236 buf->writeByte(',');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
237 Object *o = (Object *)args->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
238 ObjectToCBuffer(buf, hgs, o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
239 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
240 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
241 else if (!oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
242 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
243 buf->writestring("NULL");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
244 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
245 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
246 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
247 #ifdef DEBUG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
248 printf("bad Object = %p\n", oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
249 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
250 assert(0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
251 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
252 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
253
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
254
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
255
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
256 /* ======================== TemplateDeclaration ============================= */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
257
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
258 TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
259 : ScopeDsymbol(id)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
260 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
261 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
262 printf("TemplateDeclaration(this = %p, id = '%s')\n", this, id->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
263 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
264 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
265 if (parameters)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
266 for (int i = 0; i < parameters->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
267 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
268 //printf("\tparameter[%d] = %p\n", i, tp);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
269 TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
270
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
271 if (ttp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
272 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
273 printf("\tparameter[%d] = %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : "");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
274 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
275 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
276 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
277 this->loc = loc;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
278 this->parameters = parameters;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
279 this->origParameters = parameters;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
280 this->members = decldefs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
281 this->overnext = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
282 this->overroot = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
283 this->scope = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
284 this->onemember = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
285 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
286
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
287 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
288 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
289 //printf("TemplateDeclaration::syntaxCopy()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
290 TemplateDeclaration *td;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
291 TemplateParameters *p;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
292 Array *d;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
293
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
294 p = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
295 if (parameters)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
296 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
297 p = new TemplateParameters();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
298 p->setDim(parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
299 for (int i = 0; i < p->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
300 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
301 p->data[i] = (void *)tp->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
302 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
303 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
304 d = Dsymbol::arraySyntaxCopy(members);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
305 td = new TemplateDeclaration(loc, ident, p, d);
527
cecfee2d01a8 Added support for overloaded intrinsics.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 336
diff changeset
306
664
eef8ac26c66c Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents: 561
diff changeset
307 // LDC
527
cecfee2d01a8 Added support for overloaded intrinsics.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 336
diff changeset
308 td->intrinsicName = intrinsicName;
cecfee2d01a8 Added support for overloaded intrinsics.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 336
diff changeset
309
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
310 return td;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
311 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
312
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
313 void TemplateDeclaration::semantic(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
314 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
315 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
316 printf("TemplateDeclaration::semantic(this = %p, id = '%s')\n", this, ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
317 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
318 if (scope)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
319 return; // semantic() already run
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
320
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
321 if (sc->func)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
322 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
323 error("cannot declare template at function scope %s", sc->func->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
324 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
325
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
326 if (/*global.params.useArrayBounds &&*/ sc->module)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
327 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
328 // Generate this function as it may be used
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
329 // when template is instantiated in other modules
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
330 sc->module->toModuleArray();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
331 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
332
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
333 if (/*global.params.useAssert &&*/ sc->module)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
334 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
335 // Generate this function as it may be used
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
336 // when template is instantiated in other modules
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
337 sc->module->toModuleAssert();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
338 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
339
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
340 /* Remember Scope for later instantiations, but make
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
341 * a copy since attributes can change.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
342 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
343 this->scope = new Scope(*sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
344 this->scope->setNoFree();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
345
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
346 // Set up scope for parameters
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
347 ScopeDsymbol *paramsym = new ScopeDsymbol();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
348 paramsym->parent = sc->parent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
349 Scope *paramscope = sc->push(paramsym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
350 paramscope->parameterSpecialization = 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
351
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
352 if (global.params.doDocComments)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
353 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
354 origParameters = new TemplateParameters();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
355 origParameters->setDim(parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
356 for (int i = 0; i < parameters->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
357 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
358 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
359 origParameters->data[i] = (void *)tp->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
360 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
361 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
362
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
363 for (int i = 0; i < parameters->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
364 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
365 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
366
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
367 tp->declareParameter(paramscope);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
368 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
369
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
370 for (int i = 0; i < parameters->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
371 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
372 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
373
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
374 tp->semantic(paramscope);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
375 if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
376 error("template tuple parameter must be last one");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
377 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
378
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
379 paramscope->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
380
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
381 if (members)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
382 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
383 Dsymbol *s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
384 if (Dsymbol::oneMembers(members, &s))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
385 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
386 if (s && s->ident && s->ident->equals(ident))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
387 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
388 onemember = s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
389 s->parent = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
390 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
391 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
392 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
393
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
394 /* BUG: should check:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
395 * o no virtual functions or non-static data members of classes
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
396 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
397 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
398
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
399 const char *TemplateDeclaration::kind()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
400 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
401 return (onemember && onemember->isAggregateDeclaration())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
402 ? onemember->kind()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
403 : (char *)"template";
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
404 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
405
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
406 /**********************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
407 * Overload existing TemplateDeclaration 'this' with the new one 's'.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
408 * Return !=0 if successful; i.e. no conflict.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
409 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
410
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
411 int TemplateDeclaration::overloadInsert(Dsymbol *s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
412 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
413 TemplateDeclaration **pf;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
414 TemplateDeclaration *f;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
415
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
416 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
417 printf("TemplateDeclaration::overloadInsert('%s')\n", s->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
418 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
419 f = s->isTemplateDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
420 if (!f)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
421 return FALSE;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
422 TemplateDeclaration *pthis = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
423 for (pf = &pthis; *pf; pf = &(*pf)->overnext)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
424 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
425 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
426 // Conflict if TemplateParameter's match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
427 // Will get caught anyway later with TemplateInstance, but
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
428 // should check it now.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
429 TemplateDeclaration *f2 = *pf;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
430
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
431 if (f->parameters->dim != f2->parameters->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
432 goto Lcontinue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
433
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
434 for (int i = 0; i < f->parameters->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
435 { TemplateParameter *p1 = (TemplateParameter *)f->parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
436 TemplateParameter *p2 = (TemplateParameter *)f2->parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
437
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
438 if (!p1->overloadMatch(p2))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
439 goto Lcontinue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
440 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
441
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
442 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
443 printf("\tfalse: conflict\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
444 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
445 return FALSE;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
446
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
447 Lcontinue:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
448 ;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
449 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
450 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
451
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
452 f->overroot = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
453 *pf = f;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
454 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
455 printf("\ttrue: no conflict\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
456 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
457 return TRUE;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
458 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
459
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
460 /***************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
461 * Given that ti is an instance of this TemplateDeclaration,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
462 * deduce the types of the parameters to this, and store
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
463 * those deduced types in dedtypes[].
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
464 * Input:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
465 * flag 1: don't do semantic() because of dummy types
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
466 * 2: don't change types in matchArg()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
467 * Output:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
468 * dedtypes deduced arguments
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
469 * Return match level.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
470 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
471
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
472 MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
473 Objects *dedtypes, int flag)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
474 { MATCH m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
475 int dedtypes_dim = dedtypes->dim;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
476
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
477 #define LOGM 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
478 #if LOGM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
479 printf("\n+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
480 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
481
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
482 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
483 printf("dedtypes->dim = %d, parameters->dim = %d\n", dedtypes_dim, parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
484 if (ti->tiargs->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
485 printf("ti->tiargs->dim = %d, [0] = %p\n",
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
486 ti->tiargs->dim,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
487 ti->tiargs->data[0]);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
488 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
489 dedtypes->zero();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
490
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
491 int parameters_dim = parameters->dim;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
492 int variadic = isVariadic() != NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
493
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
494 // If more arguments than parameters, no match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
495 if (ti->tiargs->dim > parameters_dim && !variadic)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
496 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
497 #if LOGM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
498 printf(" no match: more arguments than parameters\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
499 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
500 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
501 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
502
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
503 assert(dedtypes_dim == parameters_dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
504 assert(dedtypes_dim >= ti->tiargs->dim || variadic);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
505
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
506 // Set up scope for parameters
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
507 assert((size_t)scope > 0x10000);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
508 ScopeDsymbol *paramsym = new ScopeDsymbol();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
509 paramsym->parent = scope->parent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
510 Scope *paramscope = scope->push(paramsym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
511
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
512 // Attempt type deduction
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
513 m = MATCHexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
514 for (int i = 0; i < dedtypes_dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
515 { MATCH m2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
516 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
517 Declaration *sparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
518
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
519 //printf("\targument [%d]\n", i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
520 #if LOGM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
521 //printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
522 TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
523 if (ttp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
524 printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : "");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
525 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
526
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
527 #if DMDV1
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
528 m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
529 #else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
530 m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam, (flag & 2) ? 1 : 0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
531
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
532 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
533 //printf("\tm2 = %d\n", m2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
534
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
535 if (m2 == MATCHnomatch)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
536 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
537 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
538 printf("\tmatchArg() for parameter %i failed\n", i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
539 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
540 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
541 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
542
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
543 if (m2 < m)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
544 m = m2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
545
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
546 if (!flag)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
547 sparam->semantic(paramscope);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
548 if (!paramscope->insert(sparam))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
549 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
550 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
551
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
552 if (!flag)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
553 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
554 // Any parameter left without a type gets the type of its corresponding arg
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
555 for (int i = 0; i < dedtypes_dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
556 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
557 if (!dedtypes->data[i])
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
558 { assert(i < ti->tiargs->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
559 dedtypes->data[i] = ti->tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
560 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
561 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
562 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
563
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
564 #if LOGM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
565 // Print out the results
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
566 printf("--------------------------\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
567 printf("template %s\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
568 printf("instance %s\n", ti->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
569 if (m)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
570 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
571 for (int i = 0; i < dedtypes_dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
572 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
573 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
574 Object *oarg;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
575
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
576 printf(" [%d]", i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
577
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
578 if (i < ti->tiargs->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
579 oarg = (Object *)ti->tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
580 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
581 oarg = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
582 tp->print(oarg, (Object *)dedtypes->data[i]);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
583 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
584 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
585 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
586 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
587 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
588
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
589 #if LOGM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
590 printf(" match = %d\n", m);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
591 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
592 goto Lret;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
593
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
594 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
595 #if LOGM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
596 printf(" no match\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
597 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
598 m = MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
599
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
600 Lret:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
601 paramscope->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
602 #if LOGM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
603 printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
604 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
605 return m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
606 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
607
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
608 /********************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
609 * Determine partial specialization order of 'this' vs td2.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
610 * Returns:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
611 * 1 this is at least as specialized as td2
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
612 * 0 td2 is more specialized than this
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
613 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
614
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
615 int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
616 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
617 /* This works by taking the template parameters to this template
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
618 * declaration and feeding them to td2 as if it were a template
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
619 * instance.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
620 * If it works, then this template is at least as specialized
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
621 * as td2.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
622 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
623
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
624 TemplateInstance ti(0, ident); // create dummy template instance
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
625 Objects dedtypes;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
626
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
627 #define LOG_LEASTAS 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
628
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
629 #if LOG_LEASTAS
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
630 printf("%s.leastAsSpecialized(%s)\n", toChars(), td2->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
631 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
632
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
633 // Set type arguments to dummy template instance to be types
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
634 // generated from the parameters to this template declaration
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
635 ti.tiargs = new Objects();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
636 ti.tiargs->setDim(parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
637 for (int i = 0; i < ti.tiargs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
638 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
639 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
640
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
641 void *p = tp->dummyArg();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
642 if (p)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
643 ti.tiargs->data[i] = p;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
644 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
645 ti.tiargs->setDim(i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
646 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
647
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
648 // Temporary Array to hold deduced types
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
649 //dedtypes.setDim(parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
650 dedtypes.setDim(td2->parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
651
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
652 // Attempt a type deduction
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
653 if (td2->matchWithInstance(&ti, &dedtypes, 1))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
654 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
655 /* A non-variadic template is more specialized than a
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
656 * variadic one.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
657 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
658 if (isVariadic() && !td2->isVariadic())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
659 goto L1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
660
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
661 #if LOG_LEASTAS
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
662 printf(" matches, so is least as specialized\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
663 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
664 return 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
665 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
666 L1:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
667 #if LOG_LEASTAS
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
668 printf(" doesn't match, so is not as specialized\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
669 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
670 return 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
671 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
672
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
673
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
674 /*************************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
675 * Match function arguments against a specific template function.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
676 * Input:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
677 * targsi Expression/Type initial list of template arguments
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
678 * fargs arguments to function
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
679 * Output:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
680 * dedargs Expression/Type deduced template arguments
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
681 * Returns:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
682 * match level
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
683 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
684
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
685 MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
686 Objects *dedargs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
687 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
688 size_t i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
689 size_t nfparams;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
690 size_t nfargs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
691 size_t nargsi; // array size of targsi
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
692 int fptupindex = -1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
693 int tuple_dim = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
694 MATCH match = MATCHexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
695 FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
696 TypeFunction *fdtype; // type of fd
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
697 TemplateTupleParameter *tp;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
698 Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
699
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
700 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
701 printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
702 for (i = 0; i < fargs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
703 { Expression *e = (Expression *)fargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
704 printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
705 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
706 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
707
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
708 assert((size_t)scope > 0x10000);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
709
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
710 dedargs->setDim(parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
711 dedargs->zero();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
712
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
713 dedtypes.setDim(parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
714 dedtypes.zero();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
715
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
716 // Set up scope for parameters
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
717 ScopeDsymbol *paramsym = new ScopeDsymbol();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
718 paramsym->parent = scope->parent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
719 Scope *paramscope = scope->push(paramsym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
720
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
721 tp = isVariadic();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
722
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
723 nargsi = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
724 if (targsi)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
725 { // Set initial template arguments
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
726
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
727 nargsi = targsi->dim;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
728 if (nargsi > parameters->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
729 { if (!tp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
730 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
731 dedargs->setDim(nargsi);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
732 dedargs->zero();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
733 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
734
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
735 memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
736
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
737 for (i = 0; i < nargsi; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
738 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
739 MATCH m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
740 Declaration *sparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
741
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
742 m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
743 //printf("\tdeduceType m = %d\n", m);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
744 if (m == MATCHnomatch)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
745 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
746 if (m < match)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
747 match = m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
748
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
749 sparam->semantic(paramscope);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
750 if (!paramscope->insert(sparam))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
751 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
752 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
753 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
754
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
755 assert(fd->type->ty == Tfunction);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
756 fdtype = (TypeFunction *)fd->type;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
757
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
758 nfparams = Argument::dim(fdtype->parameters); // number of function parameters
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
759 nfargs = fargs->dim; // number of function arguments
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
760
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
761 /* Check for match of function arguments with variadic template
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
762 * parameter, such as:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
763 *
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
764 * template Foo(T, A...) { void Foo(T t, A a); }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
765 * void main() { Foo(1,2,3); }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
766 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
767 tp = isVariadic();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
768 if (tp) // if variadic
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
769 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
770 if (nfparams == 0) // if no function parameters
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
771 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
772 Tuple *t = new Tuple();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
773 //printf("t = %p\n", t);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
774 dedargs->data[parameters->dim - 1] = (void *)t;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
775 goto L2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
776 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
777 else if (nfargs < nfparams - 1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
778 goto L1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
779 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
780 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
781 /* Figure out which of the function parameters matches
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
782 * the tuple template parameter. Do this by matching
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
783 * type identifiers.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
784 * Set the index of this function parameter to fptupindex.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
785 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
786 for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
787 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
788 Argument *fparam = (Argument *)fdtype->parameters->data[fptupindex];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
789 if (fparam->type->ty != Tident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
790 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
791 TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
792 if (!tp->ident->equals(tid->ident) || tid->idents.dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
793 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
794
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
795 if (fdtype->varargs) // variadic function doesn't
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
796 goto Lnomatch; // go with variadic template
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
797
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
798 /* The types of the function arguments
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
799 * now form the tuple argument.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
800 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
801 Tuple *t = new Tuple();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
802 dedargs->data[parameters->dim - 1] = (void *)t;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
803
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
804 tuple_dim = nfargs - (nfparams - 1);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
805 t->objects.setDim(tuple_dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
806 for (i = 0; i < tuple_dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
807 { Expression *farg = (Expression *)fargs->data[fptupindex + i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
808 t->objects.data[i] = (void *)farg->type;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
809 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
810 goto L2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
811 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
812 fptupindex = -1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
813 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
814 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
815
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
816 L1:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
817 if (nfparams == nfargs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
818 ;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
819 else if (nfargs > nfparams)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
820 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
821 if (fdtype->varargs == 0)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
822 goto Lnomatch; // too many args, no match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
823 match = MATCHconvert; // match ... with a conversion
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
824 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
825
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
826 L2:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
827 // Loop through the function parameters
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
828 for (i = 0; i < nfparams; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
829 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
830 /* Skip over function parameters which wound up
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
831 * as part of a template tuple parameter.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
832 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
833 if (i == fptupindex)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
834 { if (fptupindex == nfparams - 1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
835 break;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
836 i += tuple_dim - 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
837 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
838 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
839
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
840 Argument *fparam = Argument::getNth(fdtype->parameters, i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
841
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
842 if (i >= nfargs) // if not enough arguments
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
843 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
844 if (fparam->defaultArg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
845 { /* Default arguments do not participate in template argument
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
846 * deduction.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
847 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
848 goto Lmatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
849 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
850 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
851 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
852 { Expression *farg = (Expression *)fargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
853 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
854 printf("\tfarg->type = %s\n", farg->type->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
855 printf("\tfparam->type = %s\n", fparam->type->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
856 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
857
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
858 MATCH m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
859 m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
860 //printf("\tdeduceType m = %d\n", m);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
861
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
862 /* If no match, see if there's a conversion to a delegate
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
863 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
864 if (!m && fparam->type->toBasetype()->ty == Tdelegate)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
865 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
866 TypeDelegate *td = (TypeDelegate *)fparam->type->toBasetype();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
867 TypeFunction *tf = (TypeFunction *)td->next;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
868
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
869 if (!tf->varargs && Argument::dim(tf->parameters) == 0)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
870 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
871 m = farg->type->deduceType(scope, tf->next, parameters, &dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
872 if (!m && tf->next->toBasetype()->ty == Tvoid)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
873 m = MATCHconvert;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
874 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
875 //printf("\tm2 = %d\n", m);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
876 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
877
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
878 if (m)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
879 { if (m < match)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
880 match = m; // pick worst match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
881 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
882 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
883 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
884
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
885 /* The following code for variadic arguments closely
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
886 * matches TypeFunction::callMatch()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
887 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
888 if (!(fdtype->varargs == 2 && i + 1 == nfparams))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
889 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
890
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
891 /* Check for match with function parameter T...
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
892 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
893 Type *tb = fparam->type->toBasetype();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
894 switch (tb->ty)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
895 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
896 // Perhaps we can do better with this, see TypeFunction::callMatch()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
897 case Tsarray:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
898 { TypeSArray *tsa = (TypeSArray *)tb;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
899 integer_t sz = tsa->dim->toInteger();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
900 if (sz != nfargs - i)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
901 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
902 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
903 case Tarray:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
904 { TypeArray *ta = (TypeArray *)tb;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
905 for (; i < nfargs; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
906 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
907 Expression *arg = (Expression *)fargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
908 assert(arg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
909 MATCH m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
910 /* If lazy array of delegates,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
911 * convert arg(s) to delegate(s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
912 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
913 Type *tret = fparam->isLazyArray();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
914 if (tret)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
915 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
916 if (ta->next->equals(arg->type))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
917 { m = MATCHexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
918 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
919 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
920 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
921 m = arg->implicitConvTo(tret);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
922 if (m == MATCHnomatch)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
923 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
924 if (tret->toBasetype()->ty == Tvoid)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
925 m = MATCHconvert;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
926 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
927 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
928 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
929 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
930 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
931 m = arg->type->deduceType(scope, ta->next, parameters, &dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
932 //m = arg->implicitConvTo(ta->next);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
933 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
934 if (m == MATCHnomatch)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
935 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
936 if (m < match)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
937 match = m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
938 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
939 goto Lmatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
940 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
941 case Tclass:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
942 case Tident:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
943 goto Lmatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
944
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
945 default:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
946 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
947 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
948 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
949
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
950 Lmatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
951
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
952 /* Fill in any missing arguments with their defaults.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
953 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
954 for (i = nargsi; i < dedargs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
955 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
956 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
957 //printf("tp[%d] = %s\n", i, tp->ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
958 /* For T:T*, the dedargs is the T*, dedtypes is the T
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
959 * But for function templates, we really need them to match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
960 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
961 Object *oarg = (Object *)dedargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
962 Object *oded = (Object *)dedtypes.data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
963 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
964 if (!oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
965 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
966 if (oded)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
967 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
968 if (tp->specialization())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
969 { /* The specialization can work as long as afterwards
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
970 * the oded == oarg
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
971 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
972 Declaration *sparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
973 dedargs->data[i] = (void *)oded;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
974 MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
975 //printf("m2 = %d\n", m2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
976 if (!m2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
977 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
978 if (m2 < match)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
979 match = m2; // pick worst match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
980 if (dedtypes.data[i] != oded)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
981 error("specialization not allowed for deduced parameter %s", tp->ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
982 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
983 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
984 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
985 { oded = tp->defaultArg(paramscope);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
986 if (!oded)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
987 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
988 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
989 declareParameter(paramscope, tp, oded);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
990 dedargs->data[i] = (void *)oded;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
991 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
992 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
993
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
994 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
995 for (i = 0; i < dedargs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
996 { Type *t = (Type *)dedargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
997 printf("\tdedargs[%d] = %d, %s\n", i, t->dyncast(), t->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
998 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
999 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1000
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1001 paramscope->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1002 //printf("\tmatch %d\n", match);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1003 return match;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1004
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1005 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1006 paramscope->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1007 //printf("\tnomatch\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1008 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1009 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1010
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1011 /**************************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1012 * Declare template parameter tp with value o.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1013 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1014
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1015 void TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Object *o)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1016 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1017 //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1018
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1019 Type *targ = isType(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1020 Expression *ea = isExpression(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1021 Dsymbol *sa = isDsymbol(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1022 Tuple *va = isTuple(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1023
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1024 Dsymbol *s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1025
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1026 if (targ)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1027 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1028 //printf("type %s\n", targ->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1029 s = new AliasDeclaration(0, tp->ident, targ);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1030 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1031 else if (sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1032 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1033 //printf("Alias %s %s;\n", sa->ident->toChars(), tp->ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1034 s = new AliasDeclaration(0, tp->ident, sa);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1035 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1036 else if (ea)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1037 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1038 // tdtypes.data[i] always matches ea here
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1039 Initializer *init = new ExpInitializer(loc, ea);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1040 TemplateValueParameter *tvp = tp->isTemplateValueParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1041 assert(tvp);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1042
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1043 VarDeclaration *v = new VarDeclaration(loc, tvp->valType, tp->ident, init);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1044 v->storage_class = STCconst;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1045 s = v;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1046 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1047 else if (va)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1048 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1049 //printf("\ttuple\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1050 s = new TupleDeclaration(loc, tp->ident, &va->objects);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1051 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1052 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1053 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1054 #ifdef DEBUG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1055 o->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1056 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1057 assert(0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1058 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1059 if (!sc->insert(s))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1060 error("declaration %s is already defined", tp->ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1061 s->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1062 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1063
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1064 /**************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1065 * Determine if TemplateDeclaration is variadic.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1066 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1067
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1068 TemplateTupleParameter *isVariadic(TemplateParameters *parameters)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1069 { size_t dim = parameters->dim;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1070 TemplateTupleParameter *tp = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1071
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1072 if (dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1073 tp = ((TemplateParameter *)parameters->data[dim - 1])->isTemplateTupleParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1074 return tp;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1075 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1076
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1077 TemplateTupleParameter *TemplateDeclaration::isVariadic()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1078 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1079 return ::isVariadic(parameters);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1080 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1081
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1082 /***********************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1083 * We can overload templates.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1084 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1085
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1086 int TemplateDeclaration::isOverloadable()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1087 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1088 return 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1089 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1090
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1091 /*************************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1092 * Given function arguments, figure out which template function
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1093 * to expand, and return that function.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1094 * If no match, give error message and return NULL.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1095 * Input:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1096 * sc instantiation scope
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1097 * loc instantiation location
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1098 * targsi initial list of template arguments
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1099 * fargs arguments to function
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1100 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1101
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1102 FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1103 Objects *targsi, Expressions *fargs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1104 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1105 MATCH m_best = MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1106 TemplateDeclaration *td_ambig = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1107 TemplateDeclaration *td_best = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1108 Objects *tdargs = new Objects();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1109 TemplateInstance *ti;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1110 FuncDeclaration *fd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1111
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1112 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1113 printf("TemplateDeclaration::deduceFunctionTemplate() %s\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1114 printf(" targsi:\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1115 if (targsi)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1116 { for (int i = 0; i < targsi->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1117 { Object *arg = (Object *)targsi->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1118 printf("\t%s\n", arg->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1119 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1120 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1121 printf(" fargs:\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1122 for (int i = 0; i < fargs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1123 { Expression *arg = (Expression *)fargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1124 printf("\t%s %s\n", arg->type->toChars(), arg->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1125 //printf("\tty = %d\n", arg->type->ty);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1126 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1127 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1128
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1129 for (TemplateDeclaration *td = this; td; td = td->overnext)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1130 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1131 if (!td->scope)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1132 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1133 error("forward reference to template %s", td->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1134 goto Lerror;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1135 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1136 if (!td->onemember || !td->onemember->toAlias()->isFuncDeclaration())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1137 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1138 error("is not a function template");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1139 goto Lerror;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1140 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1141
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1142 MATCH m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1143 Objects dedargs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1144
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1145 m = td->deduceFunctionTemplateMatch(targsi, fargs, &dedargs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1146 //printf("deduceFunctionTemplateMatch = %d\n", m);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1147 if (!m) // if no match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1148 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1149
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1150 if (m < m_best)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1151 goto Ltd_best;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1152 if (m > m_best)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1153 goto Ltd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1154
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1155 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1156 // Disambiguate by picking the most specialized TemplateDeclaration
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1157 int c1 = td->leastAsSpecialized(td_best);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1158 int c2 = td_best->leastAsSpecialized(td);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1159 //printf("c1 = %d, c2 = %d\n", c1, c2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1160
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1161 if (c1 > c2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1162 goto Ltd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1163 else if (c1 < c2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1164 goto Ltd_best;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1165 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1166 goto Lambig;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1167 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1168
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1169 Lambig: // td_best and td are ambiguous
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1170 td_ambig = td;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1171 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1172
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1173 Ltd_best: // td_best is the best match so far
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1174 td_ambig = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1175 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1176
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1177 Ltd: // td is the new best match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1178 td_ambig = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1179 assert((size_t)td->scope > 0x10000);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1180 td_best = td;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1181 m_best = m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1182 tdargs->setDim(dedargs.dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1183 memcpy(tdargs->data, dedargs.data, tdargs->dim * sizeof(void *));
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1184 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1185 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1186 if (!td_best)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1187 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1188 error(loc, "does not match any template declaration");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1189 goto Lerror;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1190 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1191 if (td_ambig)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1192 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1193 error(loc, "%s matches more than one function template declaration, %s and %s",
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1194 toChars(), td_best->toChars(), td_ambig->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1195 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1196
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1197 /* The best match is td_best with arguments tdargs.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1198 * Now instantiate the template.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1199 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1200 assert((size_t)td_best->scope > 0x10000);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1201 ti = new TemplateInstance(loc, td_best, tdargs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1202 ti->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1203 fd = ti->toAlias()->isFuncDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1204 if (!fd)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1205 goto Lerror;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1206 return fd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1207
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1208 Lerror:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1209 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1210 OutBuffer buf;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1211 HdrGenState hgs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1212
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1213 argExpTypesToCBuffer(&buf, fargs, &hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1214 error(loc, "cannot deduce template function from argument types (%s)",
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1215 buf.toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1216 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1217 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1218 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1219
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1220 void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1221 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1222 #if 0 // Should handle template functions
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1223 if (onemember && onemember->isFuncDeclaration())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1224 buf->writestring("foo ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1225 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1226 buf->writestring(kind());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1227 buf->writeByte(' ');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1228 buf->writestring(ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1229 buf->writeByte('(');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1230 for (int i = 0; i < parameters->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1231 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1232 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1233 if (hgs->ddoc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1234 tp = (TemplateParameter *)origParameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1235 if (i)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1236 buf->writeByte(',');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1237 tp->toCBuffer(buf, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1238 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1239 buf->writeByte(')');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1240
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1241 if (hgs->hdrgen)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1242 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1243 hgs->tpltMember++;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1244 buf->writenl();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1245 buf->writebyte('{');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1246 buf->writenl();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1247 for (int i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1248 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1249 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1250 s->toCBuffer(buf, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1251 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1252 buf->writebyte('}');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1253 buf->writenl();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1254 hgs->tpltMember--;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1255 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1256 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1257
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1258
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1259 char *TemplateDeclaration::toChars()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1260 { OutBuffer buf;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1261 HdrGenState hgs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1262
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1263 memset(&hgs, 0, sizeof(hgs));
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1264 buf.writestring(ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1265 buf.writeByte('(');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1266 for (int i = 0; i < parameters->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1267 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1268 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1269 if (i)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1270 buf.writeByte(',');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1271 tp->toCBuffer(&buf, &hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1272 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1273 buf.writeByte(')');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1274 buf.writeByte(0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1275 return (char *)buf.extractData();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1276 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1277
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1278 /* ======================== Type ============================================ */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1279
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1280 /****
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1281 * Given an identifier, figure out which TemplateParameter it is.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1282 * Return -1 if not found.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1283 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1284
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1285 int templateIdentifierLookup(Identifier *id, TemplateParameters *parameters)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1286 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1287 for (size_t i = 0; i < parameters->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1288 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1289
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1290 if (tp->ident->equals(id))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1291 return i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1292 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1293 return -1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1294 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1295
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1296 int templateParameterLookup(Type *tparam, TemplateParameters *parameters)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1297 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1298 assert(tparam->ty == Tident);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1299 TypeIdentifier *tident = (TypeIdentifier *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1300 //printf("\ttident = '%s'\n", tident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1301 if (tident->idents.dim == 0)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1302 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1303 return templateIdentifierLookup(tident->ident, parameters);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1304 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1305 return -1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1306 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1307
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1308 /* These form the heart of template argument deduction.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1309 * Given 'this' being the type argument to the template instance,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1310 * it is matched against the template declaration parameter specialization
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1311 * 'tparam' to determine the type to be used for the parameter.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1312 * Example:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1313 * template Foo(T:T*) // template declaration
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1314 * Foo!(int*) // template instantiation
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1315 * Input:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1316 * this = int*
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1317 * tparam = T
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1318 * parameters = [ T:T* ] // Array of TemplateParameter's
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1319 * Output:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1320 * dedtypes = [ int ] // Array of Expression/Type's
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1321 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1322
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1323 MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1324 Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1325 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1326 //printf("Type::deduceType()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1327 //printf("\tthis = %d, ", ty); print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1328 //printf("\ttparam = %d, ", tparam->ty); tparam->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1329 if (!tparam)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1330 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1331
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1332 if (this == tparam)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1333 goto Lexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1334
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1335 if (tparam->ty == Tident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1336 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1337 // Determine which parameter tparam is
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1338 int i = templateParameterLookup(tparam, parameters);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1339 if (i == -1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1340 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1341 if (!sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1342 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1343
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1344 /* Need a loc to go with the semantic routine.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1345 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1346 Loc loc;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1347 if (parameters->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1348 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1349 TemplateParameter *tp = (TemplateParameter *)parameters->data[0];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1350 loc = tp->loc;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1351 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1352
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1353 /* BUG: what if tparam is a template instance, that
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1354 * has as an argument another Tident?
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1355 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1356 tparam = tparam->semantic(loc, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1357 assert(tparam->ty != Tident);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1358 return deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1359 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1360
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1361 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1362
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1363 // Found the corresponding parameter tp
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1364 if (!tp->isTemplateTypeParameter())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1365 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1366 Type *at = (Type *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1367 if (!at)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1368 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1369 dedtypes->data[i] = (void *)this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1370 goto Lexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1371 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1372 if (equals(at))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1373 goto Lexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1374 else if (ty == Tclass && at->ty == Tclass)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1375 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1376 return (MATCH) implicitConvTo(at);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1377 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1378 else if (ty == Tsarray && at->ty == Tarray &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1379 nextOf()->equals(at->nextOf()))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1380 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1381 goto Lexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1382 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1383 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1384 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1385 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1386
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1387 if (ty != tparam->ty)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1388 return implicitConvTo(tparam);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1389 // goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1390
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1391 if (nextOf())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1392 return nextOf()->deduceType(sc, tparam->nextOf(), parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1393
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1394 Lexact:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1395 return MATCHexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1396
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1397 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1398 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1399 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1400
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1401 MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1402 Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1403 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1404 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1405 printf("TypeSArray::deduceType()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1406 printf("\tthis = %d, ", ty); print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1407 printf("\ttparam = %d, ", tparam->ty); tparam->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1408 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1409
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1410 // Extra check that array dimensions must match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1411 if (tparam)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1412 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1413 if (tparam->ty == Tsarray)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1414 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1415 TypeSArray *tp = (TypeSArray *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1416
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1417 if (tp->dim->op == TOKvar &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1418 ((VarExp *)tp->dim)->var->storage_class & STCtemplateparameter)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1419 { int i = templateIdentifierLookup(((VarExp *)tp->dim)->var->ident, parameters);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1420 // This code matches code in TypeInstance::deduceType()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1421 if (i == -1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1422 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1423 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1424 TemplateValueParameter *tvp = tp->isTemplateValueParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1425 if (!tvp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1426 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1427 Expression *e = (Expression *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1428 if (e)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1429 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1430 if (!dim->equals(e))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1431 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1432 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1433 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1434 { Type *vt = tvp->valType->semantic(0, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1435 MATCH m = (MATCH)dim->implicitConvTo(vt);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1436 if (!m)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1437 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1438 dedtypes->data[i] = dim;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1439 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1440 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1441 else if (dim->toInteger() != tp->dim->toInteger())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1442 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1443 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1444 else if (tparam->ty == Taarray)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1445 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1446 TypeAArray *tp = (TypeAArray *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1447 if (tp->index->ty == Tident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1448 { TypeIdentifier *tident = (TypeIdentifier *)tp->index;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1449
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1450 if (tident->idents.dim == 0)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1451 { Identifier *id = tident->ident;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1452
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1453 for (size_t i = 0; i < parameters->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1454 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1455 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1456
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1457 if (tp->ident->equals(id))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1458 { // Found the corresponding template parameter
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1459 TemplateValueParameter *tvp = tp->isTemplateValueParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1460 if (!tvp || !tvp->valType->isintegral())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1461 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1462
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1463 if (dedtypes->data[i])
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1464 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1465 if (!dim->equals((Object *)dedtypes->data[i]))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1466 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1467 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1468 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1469 { dedtypes->data[i] = (void *)dim;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1470 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1471 return next->deduceType(sc, tparam->nextOf(), parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1472 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1473 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1474 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1475 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1476 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1477 else if (tparam->ty == Tarray)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1478 { MATCH m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1479
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1480 m = next->deduceType(sc, tparam->nextOf(), parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1481 if (m == MATCHexact)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1482 m = MATCHconvert;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1483 return m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1484 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1485 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1486 return Type::deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1487
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1488 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1489 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1490 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1491
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1492 MATCH TypeAArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1493 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1494 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1495 printf("TypeAArray::deduceType()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1496 printf("\tthis = %d, ", ty); print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1497 printf("\ttparam = %d, ", tparam->ty); tparam->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1498 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1499
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1500 // Extra check that index type must match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1501 if (tparam && tparam->ty == Taarray)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1502 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1503 TypeAArray *tp = (TypeAArray *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1504 if (!index->deduceType(sc, tp->index, parameters, dedtypes))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1505 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1506 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1507 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1508 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1509 return Type::deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1510 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1511
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1512 MATCH TypeFunction::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1513 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1514 //printf("TypeFunction::deduceType()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1515 //printf("\tthis = %d, ", ty); print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1516 //printf("\ttparam = %d, ", tparam->ty); tparam->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1517
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1518 // Extra check that function characteristics must match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1519 if (tparam && tparam->ty == Tfunction)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1520 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1521 TypeFunction *tp = (TypeFunction *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1522 if (varargs != tp->varargs ||
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1523 linkage != tp->linkage)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1524 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1525
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1526 size_t nfargs = Argument::dim(this->parameters);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1527 size_t nfparams = Argument::dim(tp->parameters);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1528
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1529 /* See if tuple match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1530 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1531 if (nfparams > 0 && nfargs >= nfparams - 1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1532 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1533 /* See if 'A' of the template parameter matches 'A'
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1534 * of the type of the last function parameter.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1535 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1536 Argument *fparam = (Argument *)tp->parameters->data[nfparams - 1];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1537 if (fparam->type->ty != Tident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1538 goto L1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1539 TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1540 if (tid->idents.dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1541 goto L1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1542
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1543 /* Look through parameters to find tuple matching tid->ident
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1544 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1545 size_t tupi = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1546 for (; 1; tupi++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1547 { if (tupi == parameters->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1548 goto L1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1549 TemplateParameter *t = (TemplateParameter *)parameters->data[tupi];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1550 TemplateTupleParameter *tup = t->isTemplateTupleParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1551 if (tup && tup->ident->equals(tid->ident))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1552 break;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1553 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1554
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1555 /* The types of the function arguments [nfparams - 1 .. nfargs]
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1556 * now form the tuple argument.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1557 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1558 int tuple_dim = nfargs - (nfparams - 1);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1559
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1560 /* See if existing tuple, and whether it matches or not
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1561 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1562 Object *o = (Object *)dedtypes->data[tupi];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1563 if (o)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1564 { // Existing deduced argument must be a tuple, and must match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1565 Tuple *t = isTuple(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1566 if (!t || t->objects.dim != tuple_dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1567 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1568 for (size_t i = 0; i < tuple_dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1569 { Argument *arg = Argument::getNth(this->parameters, nfparams - 1 + i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1570 if (!arg->type->equals((Object *)t->objects.data[i]))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1571 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1572 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1573 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1574 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1575 { // Create new tuple
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1576 Tuple *t = new Tuple();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1577 t->objects.setDim(tuple_dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1578 for (size_t i = 0; i < tuple_dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1579 { Argument *arg = Argument::getNth(this->parameters, nfparams - 1 + i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1580 t->objects.data[i] = (void *)arg->type;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1581 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1582 dedtypes->data[tupi] = (void *)t;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1583 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1584 nfparams--; // don't consider the last parameter for type deduction
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1585 goto L2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1586 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1587
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1588 L1:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1589 if (nfargs != nfparams)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1590 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1591 L2:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1592 for (size_t i = 0; i < nfparams; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1593 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1594 Argument *a = Argument::getNth(this->parameters, i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1595 Argument *ap = Argument::getNth(tp->parameters, i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1596 if (a->storageClass != ap->storageClass ||
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1597 !a->type->deduceType(sc, ap->type, parameters, dedtypes))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1598 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1599 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1600 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1601 return Type::deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1602 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1603
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1604 MATCH TypeIdentifier::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1605 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1606 // Extra check
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1607 if (tparam && tparam->ty == Tident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1608 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1609 TypeIdentifier *tp = (TypeIdentifier *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1610
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1611 for (int i = 0; i < idents.dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1612 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1613 Identifier *id1 = (Identifier *)idents.data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1614 Identifier *id2 = (Identifier *)tp->idents.data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1615
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1616 if (!id1->equals(id2))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1617 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1618 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1619 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1620 return Type::deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1621 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1622
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1623 MATCH TypeInstance::deduceType(Scope *sc,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1624 Type *tparam, TemplateParameters *parameters,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1625 Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1626 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1627 //printf("TypeInstance::deduceType(tparam = %s) %s\n", tparam->toChars(), toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1628 //printf("\ttparam = %d, ", tparam->ty); tparam->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1629
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1630 // Extra check
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1631 if (tparam && tparam->ty == Tinstance)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1632 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1633 TypeInstance *tp = (TypeInstance *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1634
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1635 //printf("tempinst->tempdecl = %p\n", tempinst->tempdecl);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1636 //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1637 if (!tp->tempinst->tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1638 { //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1639 if (!tp->tempinst->name->equals(tempinst->name))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1640 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1641 /* Handle case of:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1642 * template Foo(T : sa!(T), alias sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1643 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1644 int i = templateIdentifierLookup(tp->tempinst->name, parameters);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1645 if (i == -1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1646 { /* Didn't find it as a parameter identifier. Try looking
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1647 * it up and seeing if is an alias. See Bugzilla 1454
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1648 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1649 Dsymbol *s = tempinst->tempdecl->scope->search(0, tp->tempinst->name, NULL);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1650 if (s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1651 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1652 s = s->toAlias();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1653 TemplateDeclaration *td = s->isTemplateDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1654 if (td && td == tempinst->tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1655 goto L2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1656 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1657 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1658 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1659 TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1660 // This logic duplicates tpx->matchArg()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1661 TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1662 if (!ta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1663 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1664 Dsymbol *sa = tempinst->tempdecl;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1665 if (!sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1666 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1667 if (ta->specAlias && sa != ta->specAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1668 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1669 if (dedtypes->data[i])
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1670 { // Must match already deduced symbol
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1671 Dsymbol *s = (Dsymbol *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1672
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1673 if (s != sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1674 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1675 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1676 dedtypes->data[i] = sa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1677 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1678 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1679 else if (tempinst->tempdecl != tp->tempinst->tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1680 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1681
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1682 L2:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1683 if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1684 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1685
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1686 for (int i = 0; i < tempinst->tiargs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1687 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1688 //printf("\ttest: tempinst->tiargs[%d]\n", i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1689 int j;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1690 Object *o1 = (Object *)tempinst->tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1691 Object *o2 = (Object *)tp->tempinst->tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1692
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1693 Type *t1 = isType(o1);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1694 Type *t2 = isType(o2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1695
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1696 Expression *e1 = isExpression(o1);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1697 Expression *e2 = isExpression(o2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1698
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1699 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1700 if (t1) printf("t1 = %s\n", t1->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1701 if (t2) printf("t2 = %s\n", t2->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1702 if (e1) printf("e1 = %s\n", e1->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1703 if (e2) printf("e2 = %s\n", e2->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1704 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1705
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1706 if (t1 && t2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1707 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1708 if (!t1->deduceType(sc, t2, parameters, dedtypes))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1709 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1710 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1711 else if (e1 && e2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1712 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1713 if (!e1->equals(e2))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1714 { if (e2->op == TOKvar)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1715 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1716 /*
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1717 * (T:Number!(e2), int e2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1718 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1719 j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1720 goto L1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1721 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1722 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1723 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1724 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1725 else if (e1 && t2 && t2->ty == Tident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1726 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1727 j = templateParameterLookup(t2, parameters);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1728 L1:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1729 if (j == -1)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1730 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1731 TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1732 // BUG: use tp->matchArg() instead of the following
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1733 TemplateValueParameter *tv = tp->isTemplateValueParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1734 if (!tv)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1735 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1736 Expression *e = (Expression *)dedtypes->data[j];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1737 if (e)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1738 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1739 if (!e1->equals(e))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1740 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1741 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1742 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1743 { Type *vt = tv->valType->semantic(0, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1744 MATCH m = (MATCH)e1->implicitConvTo(vt);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1745 if (!m)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1746 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1747 dedtypes->data[j] = e1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1748 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1749 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1750 // BUG: Need to handle alias and tuple parameters
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1751 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1752 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1753 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1754 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1755 return Type::deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1756
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1757 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1758 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1759 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1760
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1761 MATCH TypeStruct::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1762 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1763 //printf("TypeStruct::deduceType()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1764 //printf("\tthis->parent = %s, ", sym->parent->toChars()); print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1765 //printf("\ttparam = %d, ", tparam->ty); tparam->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1766
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1767 /* If this struct is a template struct, and we're matching
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1768 * it against a template instance, convert the struct type
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1769 * to a template instance, too, and try again.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1770 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1771 TemplateInstance *ti = sym->parent->isTemplateInstance();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1772
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1773 if (tparam && tparam->ty == Tinstance)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1774 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1775 if (ti && ti->toAlias() == sym)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1776 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1777 TypeInstance *t = new TypeInstance(0, ti);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1778 return t->deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1779 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1780
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1781 /* Match things like:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1782 * S!(T).foo
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1783 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1784 TypeInstance *tpi = (TypeInstance *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1785 if (tpi->idents.dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1786 { Identifier *id = (Identifier *)tpi->idents.data[tpi->idents.dim - 1];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1787 if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals(id))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1788 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1789 Type *tparent = sym->parent->getType();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1790 if (tparent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1791 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1792 /* Slice off the .foo in S!(T).foo
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1793 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1794 tpi->idents.dim--;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1795 MATCH m = tparent->deduceType(sc, tpi, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1796 tpi->idents.dim++;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1797 return m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1798 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1799 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1800 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1801 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1802
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1803 // Extra check
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1804 if (tparam && tparam->ty == Tstruct)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1805 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1806 TypeStruct *tp = (TypeStruct *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1807
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1808 if (sym != tp->sym)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1809 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1810 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1811 return Type::deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1812 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1813
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1814 MATCH TypeEnum::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1815 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1816 // Extra check
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1817 if (tparam && tparam->ty == Tenum)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1818 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1819 TypeEnum *tp = (TypeEnum *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1820
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1821 if (sym != tp->sym)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1822 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1823 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1824 return Type::deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1825 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1826
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1827 MATCH TypeTypedef::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1828 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1829 // Extra check
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1830 if (tparam && tparam->ty == Ttypedef)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1831 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1832 TypeTypedef *tp = (TypeTypedef *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1833
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1834 if (sym != tp->sym)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1835 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1836 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1837 return Type::deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1838 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1839
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1840 MATCH TypeClass::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1841 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1842 //printf("TypeClass::deduceType(this = %s)\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1843
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1844 /* If this class is a template class, and we're matching
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1845 * it against a template instance, convert the class type
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1846 * to a template instance, too, and try again.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1847 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1848 TemplateInstance *ti = sym->parent->isTemplateInstance();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1849
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1850 if (tparam && tparam->ty == Tinstance)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1851 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1852 if (ti && ti->toAlias() == sym)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1853 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1854 TypeInstance *t = new TypeInstance(0, ti);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1855 return t->deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1856 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1857
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1858 /* Match things like:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1859 * S!(T).foo
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1860 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1861 TypeInstance *tpi = (TypeInstance *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1862 if (tpi->idents.dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1863 { Identifier *id = (Identifier *)tpi->idents.data[tpi->idents.dim - 1];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1864 if (id->dyncast() == DYNCAST_IDENTIFIER && sym->ident->equals(id))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1865 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1866 Type *tparent = sym->parent->getType();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1867 if (tparent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1868 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1869 /* Slice off the .foo in S!(T).foo
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1870 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1871 tpi->idents.dim--;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1872 MATCH m = tparent->deduceType(sc, tpi, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1873 tpi->idents.dim++;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1874 return m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1875 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1876 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1877 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1878 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1879
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1880 // Extra check
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1881 if (tparam && tparam->ty == Tclass)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1882 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1883 TypeClass *tp = (TypeClass *)tparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1884
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1885 //printf("\t%d\n", (MATCH) implicitConvTo(tp));
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1886 return (MATCH) implicitConvTo(tp);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1887 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1888 return Type::deduceType(sc, tparam, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1889 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1890
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1891 /* ======================== TemplateParameter =============================== */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1892
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1893 TemplateParameter::TemplateParameter(Loc loc, Identifier *ident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1894 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1895 this->loc = loc;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1896 this->ident = ident;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1897 this->sparam = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1898 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1899
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1900 TemplateTypeParameter *TemplateParameter::isTemplateTypeParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1901 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1902 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1903 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1904
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1905 TemplateValueParameter *TemplateParameter::isTemplateValueParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1906 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1907 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1908 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1909
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1910 TemplateAliasParameter *TemplateParameter::isTemplateAliasParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1911 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1912 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1913 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1914
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1915 TemplateTupleParameter *TemplateParameter::isTemplateTupleParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1916 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1917 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1918 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1919
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1920 #if DMDV2
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1921 TemplateThisParameter *TemplateParameter::isTemplateThisParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1922 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1923 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1924 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1925 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1926
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1927 /* ======================== TemplateTypeParameter =========================== */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1928
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1929 // type-parameter
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1930
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1931 TemplateTypeParameter::TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1932 Type *defaultType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1933 : TemplateParameter(loc, ident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1934 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1935 this->ident = ident;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1936 this->specType = specType;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1937 this->defaultType = defaultType;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1938 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1939
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1940 TemplateTypeParameter *TemplateTypeParameter::isTemplateTypeParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1941 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1942 return this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1943 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1944
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1945 TemplateParameter *TemplateTypeParameter::syntaxCopy()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1946 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1947 TemplateTypeParameter *tp = new TemplateTypeParameter(loc, ident, specType, defaultType);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1948 if (tp->specType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1949 tp->specType = specType->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1950 if (defaultType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1951 tp->defaultType = defaultType->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1952 return tp;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1953 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1954
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1955 void TemplateTypeParameter::declareParameter(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1956 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1957 //printf("TemplateTypeParameter::declareParameter('%s')\n", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1958 TypeIdentifier *ti = new TypeIdentifier(loc, ident);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1959 sparam = new AliasDeclaration(loc, ident, ti);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1960 if (!sc->insert(sparam))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1961 error(loc, "parameter '%s' multiply defined", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1962 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1963
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1964 void TemplateTypeParameter::semantic(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1965 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1966 //printf("TemplateTypeParameter::semantic('%s')\n", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1967 if (specType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1968 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1969 specType = specType->semantic(loc, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1970 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1971 #if 0 // Don't do semantic() until instantiation
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1972 if (defaultType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1973 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1974 defaultType = defaultType->semantic(loc, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1975 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1976 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1977 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1978
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1979 /****************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1980 * Determine if two TemplateParameters are the same
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1981 * as far as TemplateDeclaration overloading goes.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1982 * Returns:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1983 * 1 match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1984 * 0 no match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1985 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1986
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1987 int TemplateTypeParameter::overloadMatch(TemplateParameter *tp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1988 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1989 TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1990
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1991 if (ttp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1992 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1993 if (specType != ttp->specType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1994 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1995
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1996 if (specType && !specType->equals(ttp->specType))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1997 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1998
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
1999 return 1; // match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2000 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2001
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2002 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2003 return 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2004 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2005
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2006 /*******************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2007 * Match to a particular TemplateParameter.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2008 * Input:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2009 * i i'th argument
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2010 * tiargs[] actual arguments to template instance
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2011 * parameters[] template parameters
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2012 * dedtypes[] deduced arguments to template instance
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2013 * *psparam set to symbol declared and initialized to dedtypes[i]
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2014 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2015
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2016 MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2017 int i, TemplateParameters *parameters, Objects *dedtypes,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2018 Declaration **psparam)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2019 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2020 //printf("TemplateTypeParameter::matchArg()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2021 Type *t;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2022 Object *oarg;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2023 MATCH m = MATCHexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2024 Type *ta;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2025
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2026 if (i < tiargs->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2027 oarg = (Object *)tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2028 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2029 { // Get default argument instead
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2030 oarg = defaultArg(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2031 if (!oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2032 { assert(i < dedtypes->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2033 // It might have already been deduced
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2034 oarg = (Object *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2035 if (!oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2036 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2037 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2038 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2039
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2040 ta = isType(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2041 if (!ta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2042 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2043 //printf("ta is %s\n", ta->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2044
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2045 t = (Type *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2046
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2047 if (specType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2048 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2049 //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta->toChars(), specType->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2050 MATCH m2 = ta->deduceType(sc, specType, parameters, dedtypes);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2051 if (m2 == MATCHnomatch)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2052 { //printf("\tfailed deduceType\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2053 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2054 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2055
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2056 if (m2 < m)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2057 m = m2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2058 t = (Type *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2059 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2060 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2061 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2062 // So that matches with specializations are better
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2063 m = MATCHconvert;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2064 if (t)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2065 { // Must match already deduced type
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2066
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2067 m = MATCHexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2068 if (!t->equals(ta))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2069 { //printf("t = %s ta = %s\n", t->toChars(), ta->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2070 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2071 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2072 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2073 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2074
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2075 if (!t)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2076 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2077 dedtypes->data[i] = ta;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2078 t = ta;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2079 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2080 *psparam = new AliasDeclaration(loc, ident, t);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2081 //printf("\tm = %d\n", m);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2082 return m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2083
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2084 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2085 *psparam = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2086 //printf("\tm = %d\n", MATCHnomatch);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2087 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2088 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2089
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2090
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2091 void TemplateTypeParameter::print(Object *oarg, Object *oded)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2092 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2093 printf(" %s\n", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2094
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2095 Type *t = isType(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2096 Type *ta = isType(oded);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2097
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2098 assert(ta);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2099
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2100 if (specType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2101 printf("\tSpecialization: %s\n", specType->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2102 if (defaultType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2103 printf("\tDefault: %s\n", defaultType->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2104 printf("\tArgument: %s\n", t ? t->toChars() : "NULL");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2105 printf("\tDeduced Type: %s\n", ta->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2106 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2107
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2108
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2109 void TemplateTypeParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2110 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2111 buf->writestring(ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2112 if (specType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2113 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2114 buf->writestring(" : ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2115 specType->toCBuffer(buf, NULL, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2116 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2117 if (defaultType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2118 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2119 buf->writestring(" = ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2120 defaultType->toCBuffer(buf, NULL, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2121 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2122 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2123
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2124
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2125 void *TemplateTypeParameter::dummyArg()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2126 { Type *t;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2127
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2128 if (specType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2129 t = specType;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2130 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2131 { // Use this for alias-parameter's too (?)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2132 t = new TypeIdentifier(loc, ident);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2133 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2134 return (void *)t;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2135 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2136
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2137
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2138 Object *TemplateTypeParameter::specialization()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2139 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2140 return specType;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2141 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2142
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2143
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2144 Object *TemplateTypeParameter::defaultArg(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2145 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2146 Type *t;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2147
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2148 t = defaultType;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2149 if (t)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2150 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2151 t = t->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2152 t = t->semantic(loc, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2153 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2154 return t;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2155 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2156
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2157 /* ======================== TemplateThisParameter =========================== */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2158
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2159 #if DMDV2
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2160 // this-parameter
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2161
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2162 TemplateThisParameter::TemplateThisParameter(Loc loc, Identifier *ident,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2163 Type *specType,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2164 Type *defaultType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2165 : TemplateTypeParameter(loc, ident, specType, defaultType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2166 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2167 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2168
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2169 TemplateThisParameter *TemplateThisParameter::isTemplateThisParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2170 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2171 return this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2172 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2173
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2174 TemplateParameter *TemplateThisParameter::syntaxCopy()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2175 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2176 TemplateThisParameter *tp = new TemplateThisParameter(loc, ident, specType, defaultType);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2177 if (tp->specType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2178 tp->specType = specType->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2179 if (defaultType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2180 tp->defaultType = defaultType->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2181 return tp;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2182 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2183
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2184 void TemplateThisParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2185 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2186 buf->writestring("this ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2187 TemplateTypeParameter::toCBuffer(buf, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2188 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2189 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2190
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2191 /* ======================== TemplateAliasParameter ========================== */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2192
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2193 // alias-parameter
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2194
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2195 Dsymbol *TemplateAliasParameter::sdummy = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2196
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2197 TemplateAliasParameter::TemplateAliasParameter(Loc loc, Identifier *ident, Type *specAliasT, Type *defaultAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2198 : TemplateParameter(loc, ident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2199 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2200 this->ident = ident;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2201 this->specAliasT = specAliasT;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2202 this->defaultAlias = defaultAlias;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2203
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2204 this->specAlias = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2205 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2206
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2207 TemplateAliasParameter *TemplateAliasParameter::isTemplateAliasParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2208 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2209 return this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2210 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2211
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2212 TemplateParameter *TemplateAliasParameter::syntaxCopy()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2213 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2214 TemplateAliasParameter *tp = new TemplateAliasParameter(loc, ident, specAliasT, defaultAlias);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2215 if (tp->specAliasT)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2216 tp->specAliasT = specAliasT->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2217 if (defaultAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2218 tp->defaultAlias = defaultAlias->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2219 return tp;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2220 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2221
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2222 void TemplateAliasParameter::declareParameter(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2223 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2224 TypeIdentifier *ti = new TypeIdentifier(loc, ident);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2225 sparam = new AliasDeclaration(loc, ident, ti);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2226 if (!sc->insert(sparam))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2227 error(loc, "parameter '%s' multiply defined", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2228 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2229
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2230 void TemplateAliasParameter::semantic(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2231 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2232 if (specAliasT)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2233 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2234 specAlias = specAliasT->toDsymbol(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2235 if (!specAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2236 error(loc, "%s is not a symbol", specAliasT->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2237 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2238 #if 0 // Don't do semantic() until instantiation
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2239 if (defaultAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2240 defaultAlias = defaultAlias->semantic(loc, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2241 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2242 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2243
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2244 int TemplateAliasParameter::overloadMatch(TemplateParameter *tp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2245 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2246 TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2247
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2248 if (tap)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2249 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2250 if (specAlias != tap->specAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2251 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2252
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2253 return 1; // match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2254 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2255
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2256 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2257 return 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2258 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2259
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2260 MATCH TemplateAliasParameter::matchArg(Scope *sc,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2261 Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2262 Declaration **psparam)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2263 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2264 Dsymbol *sa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2265 Object *oarg;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2266 Expression *ea;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2267
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2268 //printf("TemplateAliasParameter::matchArg()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2269
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2270 if (i < tiargs->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2271 oarg = (Object *)tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2272 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2273 { // Get default argument instead
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2274 oarg = defaultArg(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2275 if (!oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2276 { assert(i < dedtypes->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2277 // It might have already been deduced
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2278 oarg = (Object *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2279 if (!oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2280 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2281 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2282 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2283
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2284 sa = getDsymbol(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2285 if (!sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2286 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2287
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2288 if (specAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2289 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2290 if (!sa || sa == sdummy)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2291 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2292 if (sa != specAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2293 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2294 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2295 else if (dedtypes->data[i])
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2296 { // Must match already deduced symbol
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2297 Dsymbol *s = (Dsymbol *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2298
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2299 if (!sa || s != sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2300 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2301 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2302 dedtypes->data[i] = sa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2303
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2304 *psparam = new AliasDeclaration(loc, ident, sa);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2305 return MATCHexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2306
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2307 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2308 *psparam = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2309 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2310 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2311
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2312
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2313 void TemplateAliasParameter::print(Object *oarg, Object *oded)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2314 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2315 printf(" %s\n", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2316
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2317 Dsymbol *sa = isDsymbol(oded);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2318 assert(sa);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2319
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2320 printf("\tArgument alias: %s\n", sa->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2321 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2322
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2323 void TemplateAliasParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2324 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2325 buf->writestring("alias ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2326 buf->writestring(ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2327 if (specAliasT)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2328 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2329 buf->writestring(" : ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2330 specAliasT->toCBuffer(buf, NULL, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2331 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2332 if (defaultAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2333 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2334 buf->writestring(" = ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2335 defaultAlias->toCBuffer(buf, NULL, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2336 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2337 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2338
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2339
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2340 void *TemplateAliasParameter::dummyArg()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2341 { Dsymbol *s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2342
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2343 s = specAlias;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2344 if (!s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2345 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2346 if (!sdummy)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2347 sdummy = new Dsymbol();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2348 s = sdummy;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2349 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2350 return (void*)s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2351 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2352
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2353
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2354 Object *TemplateAliasParameter::specialization()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2355 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2356 return specAliasT;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2357 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2358
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2359
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2360 Object *TemplateAliasParameter::defaultArg(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2361 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2362 Dsymbol *s = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2363
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2364 if (defaultAlias)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2365 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2366 s = defaultAlias->toDsymbol(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2367 if (!s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2368 error("%s is not a symbol", defaultAlias->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2369 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2370 return s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2371 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2372
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2373 /* ======================== TemplateValueParameter ========================== */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2374
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2375 // value-parameter
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2376
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2377 Expression *TemplateValueParameter::edummy = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2378
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2379 TemplateValueParameter::TemplateValueParameter(Loc loc, Identifier *ident, Type *valType,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2380 Expression *specValue, Expression *defaultValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2381 : TemplateParameter(loc, ident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2382 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2383 this->ident = ident;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2384 this->valType = valType;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2385 this->specValue = specValue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2386 this->defaultValue = defaultValue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2387 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2388
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2389 TemplateValueParameter *TemplateValueParameter::isTemplateValueParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2390 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2391 return this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2392 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2393
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2394 TemplateParameter *TemplateValueParameter::syntaxCopy()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2395 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2396 TemplateValueParameter *tp =
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2397 new TemplateValueParameter(loc, ident, valType, specValue, defaultValue);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2398 tp->valType = valType->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2399 if (specValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2400 tp->specValue = specValue->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2401 if (defaultValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2402 tp->defaultValue = defaultValue->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2403 return tp;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2404 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2405
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2406 void TemplateValueParameter::declareParameter(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2407 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2408 VarDeclaration *v = new VarDeclaration(loc, valType, ident, NULL);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2409 v->storage_class = STCtemplateparameter;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2410 if (!sc->insert(v))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2411 error(loc, "parameter '%s' multiply defined", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2412 sparam = v;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2413 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2414
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2415 void TemplateValueParameter::semantic(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2416 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2417 sparam->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2418 valType = valType->semantic(loc, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2419 if (!(valType->isintegral() || valType->isfloating() || valType->isString()) &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2420 valType->ty != Tident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2421 error(loc, "arithmetic/string type expected for value-parameter, not %s", valType->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2422
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2423 if (specValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2424 { Expression *e = specValue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2425
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2426 e = e->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2427 e = e->implicitCastTo(sc, valType);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2428 e = e->optimize(WANTvalue | WANTinterpret);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2429 if (e->op == TOKint64 || e->op == TOKfloat64 ||
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2430 e->op == TOKcomplex80 || e->op == TOKnull || e->op == TOKstring)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2431 specValue = e;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2432 //e->toInteger();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2433 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2434
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2435 #if 0 // defer semantic analysis to arg match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2436 if (defaultValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2437 { Expression *e = defaultValue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2438
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2439 e = e->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2440 e = e->implicitCastTo(sc, valType);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2441 e = e->optimize(WANTvalue | WANTinterpret);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2442 if (e->op == TOKint64)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2443 defaultValue = e;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2444 //e->toInteger();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2445 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2446 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2447 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2448
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2449 int TemplateValueParameter::overloadMatch(TemplateParameter *tp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2450 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2451 TemplateValueParameter *tvp = tp->isTemplateValueParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2452
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2453 if (tvp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2454 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2455 if (valType != tvp->valType)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2456 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2457
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2458 if (valType && !valType->equals(tvp->valType))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2459 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2460
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2461 if (specValue != tvp->specValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2462 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2463
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2464 return 1; // match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2465 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2466
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2467 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2468 return 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2469 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2470
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2471
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2472 MATCH TemplateValueParameter::matchArg(Scope *sc,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2473 Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2474 Declaration **psparam)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2475 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2476 //printf("TemplateValueParameter::matchArg()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2477
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2478 Initializer *init;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2479 Declaration *sparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2480 MATCH m = MATCHexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2481 Expression *ei;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2482 Object *oarg;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2483
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2484 if (i < tiargs->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2485 oarg = (Object *)tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2486 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2487 { // Get default argument instead
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2488 oarg = defaultArg(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2489 if (!oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2490 { assert(i < dedtypes->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2491 // It might have already been deduced
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2492 oarg = (Object *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2493 if (!oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2494 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2495 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2496 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2497
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2498 ei = isExpression(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2499 Type *vt;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2500
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2501 if (!ei && oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2502 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2503
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2504 if (specValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2505 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2506 if (!ei || ei == edummy)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2507 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2508
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2509 Expression *e = specValue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2510
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2511 e = e->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2512 e = e->implicitCastTo(sc, valType);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2513 e = e->optimize(WANTvalue | WANTinterpret);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2514
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2515 ei = ei->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2516 ei = ei->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2517 ei = ei->optimize(WANTvalue | WANTinterpret);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2518 //printf("ei: %s, %s\n", ei->toChars(), ei->type->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2519 //printf("e : %s, %s\n", e->toChars(), e->type->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2520 if (!ei->equals(e))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2521 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2522 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2523 else if (dedtypes->data[i])
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2524 { // Must match already deduced value
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2525 Expression *e = (Expression *)dedtypes->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2526
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2527 if (!ei || !ei->equals(e))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2528 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2529 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2530 Lmatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2531 //printf("valType: %s, ty = %d\n", valType->toChars(), valType->ty);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2532 vt = valType->semantic(0, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2533 //printf("ei: %s, %s\n", ei->toChars(), ei->type->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2534 if (ei->type)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2535 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2536 m = (MATCH)ei->implicitConvTo(vt);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2537 //printf("m: %d\n", m);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2538 if (!m)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2539 goto Lnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2540 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2541 dedtypes->data[i] = ei;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2542
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2543 init = new ExpInitializer(loc, ei);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2544 sparam = new VarDeclaration(loc, vt, ident, init);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2545 sparam->storage_class = STCconst;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2546 *psparam = sparam;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2547 return m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2548
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2549 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2550 //printf("\tno match\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2551 *psparam = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2552 return MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2553 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2554
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2555
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2556 void TemplateValueParameter::print(Object *oarg, Object *oded)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2557 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2558 printf(" %s\n", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2559
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2560 Expression *ea = isExpression(oded);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2561
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2562 if (specValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2563 printf("\tSpecialization: %s\n", specValue->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2564 printf("\tArgument Value: %s\n", ea ? ea->toChars() : "NULL");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2565 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2566
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2567
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2568 void TemplateValueParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2569 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2570 valType->toCBuffer(buf, ident, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2571 if (specValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2572 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2573 buf->writestring(" : ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2574 specValue->toCBuffer(buf, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2575 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2576 if (defaultValue)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2577 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2578 buf->writestring(" = ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2579 defaultValue->toCBuffer(buf, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2580 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2581 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2582
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2583
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2584 void *TemplateValueParameter::dummyArg()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2585 { Expression *e;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2586
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2587 e = specValue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2588 if (!e)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2589 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2590 // Create a dummy value
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2591 if (!edummy)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2592 edummy = valType->defaultInit();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2593 e = edummy;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2594 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2595 return (void *)e;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2596 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2597
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2598
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2599 Object *TemplateValueParameter::specialization()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2600 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2601 return specValue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2602 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2603
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2604
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2605 Object *TemplateValueParameter::defaultArg(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2606 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2607 Expression *e = defaultValue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2608 if (e)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2609 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2610 e = e->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2611 e = e->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2612 #if DMDV2
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2613 if (e->op == TOKdefault)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2614 { DefaultInitExp *de = (DefaultInitExp *)e;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2615 e = de->resolve(loc, sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2616 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2617 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2618 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2619 return e;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2620 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2621
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2622 /* ======================== TemplateTupleParameter ========================== */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2623
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2624 // variadic-parameter
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2625
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2626 TemplateTupleParameter::TemplateTupleParameter(Loc loc, Identifier *ident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2627 : TemplateParameter(loc, ident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2628 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2629 this->ident = ident;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2630 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2631
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2632 TemplateTupleParameter *TemplateTupleParameter::isTemplateTupleParameter()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2633 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2634 return this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2635 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2636
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2637 TemplateParameter *TemplateTupleParameter::syntaxCopy()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2638 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2639 TemplateTupleParameter *tp = new TemplateTupleParameter(loc, ident);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2640 return tp;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2641 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2642
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2643 void TemplateTupleParameter::declareParameter(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2644 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2645 TypeIdentifier *ti = new TypeIdentifier(loc, ident);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2646 sparam = new AliasDeclaration(loc, ident, ti);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2647 if (!sc->insert(sparam))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2648 error(loc, "parameter '%s' multiply defined", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2649 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2650
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2651 void TemplateTupleParameter::semantic(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2652 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2653 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2654
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2655 int TemplateTupleParameter::overloadMatch(TemplateParameter *tp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2656 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2657 TemplateTupleParameter *tvp = tp->isTemplateTupleParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2658
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2659 if (tvp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2660 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2661 return 1; // match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2662 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2663
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2664 Lnomatch:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2665 return 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2666 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2667
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2668 MATCH TemplateTupleParameter::matchArg(Scope *sc,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2669 Objects *tiargs, int i, TemplateParameters *parameters,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2670 Objects *dedtypes,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2671 Declaration **psparam)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2672 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2673 //printf("TemplateTupleParameter::matchArg()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2674
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2675 /* The rest of the actual arguments (tiargs[]) form the match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2676 * for the variadic parameter.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2677 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2678 assert(i + 1 == dedtypes->dim); // must be the last one
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2679 Tuple *ovar;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2680 if (i + 1 == tiargs->dim && isTuple((Object *)tiargs->data[i]))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2681 ovar = isTuple((Object *)tiargs->data[i]);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2682 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2683 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2684 ovar = new Tuple();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2685 //printf("ovar = %p\n", ovar);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2686 if (i < tiargs->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2687 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2688 //printf("i = %d, tiargs->dim = %d\n", i, tiargs->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2689 ovar->objects.setDim(tiargs->dim - i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2690 for (size_t j = 0; j < ovar->objects.dim; j++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2691 ovar->objects.data[j] = tiargs->data[i + j];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2692 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2693 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2694 *psparam = new TupleDeclaration(loc, ident, &ovar->objects);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2695 dedtypes->data[i] = (void *)ovar;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2696 return MATCHexact;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2697 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2698
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2699
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2700 void TemplateTupleParameter::print(Object *oarg, Object *oded)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2701 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2702 printf(" %s... [", ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2703 Tuple *v = isTuple(oded);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2704 assert(v);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2705
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2706 //printf("|%d| ", v->objects.dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2707 for (int i = 0; i < v->objects.dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2708 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2709 if (i)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2710 printf(", ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2711
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2712 Object *o = (Object *)v->objects.data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2713
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2714 Dsymbol *sa = isDsymbol(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2715 if (sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2716 printf("alias: %s", sa->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2717
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2718 Type *ta = isType(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2719 if (ta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2720 printf("type: %s", ta->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2721
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2722 Expression *ea = isExpression(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2723 if (ea)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2724 printf("exp: %s", ea->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2725
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2726 assert(!isTuple(o)); // no nested Tuple arguments
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2727 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2728
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2729 printf("]\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2730 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2731
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2732 void TemplateTupleParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2733 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2734 buf->writestring(ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2735 buf->writestring("...");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2736 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2737
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2738
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2739 void *TemplateTupleParameter::dummyArg()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2740 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2741 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2742 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2743
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2744
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2745 Object *TemplateTupleParameter::specialization()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2746 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2747 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2748 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2749
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2750
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2751 Object *TemplateTupleParameter::defaultArg(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2752 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2753 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2754 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2755
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2756 /* ======================== TemplateInstance ================================ */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2757
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2758 TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2759 : ScopeDsymbol(NULL)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2760 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2761 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2762 printf("TemplateInstance(this = %p, ident = '%s')\n", this, ident ? ident->toChars() : "null");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2763 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2764 this->loc = loc;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2765 this->name = ident;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2766 this->tiargs = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2767 this->tempdecl = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2768 this->inst = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2769 this->argsym = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2770 this->aliasdecl = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2771 this->semanticdone = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2772 this->semantictiargsdone = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2773 this->withsym = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2774 this->nest = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2775 this->havetempdecl = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2776 this->isnested = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2777 this->errors = 0;
561
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
2778 this->tinst = NULL;
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2779 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2780
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2781
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2782 TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2783 : ScopeDsymbol(NULL)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2784 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2785 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2786 printf("TemplateInstance(this = %p, tempdecl = '%s')\n", this, td->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2787 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2788 this->loc = loc;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2789 this->name = td->ident;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2790 this->tiargs = tiargs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2791 this->tempdecl = td;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2792 this->inst = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2793 this->argsym = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2794 this->aliasdecl = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2795 this->semanticdone = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2796 this->semantictiargsdone = 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2797 this->withsym = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2798 this->nest = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2799 this->havetempdecl = 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2800 this->isnested = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2801 this->errors = 0;
561
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
2802 this->tinst = NULL;
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2803
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2804 assert((size_t)tempdecl->scope > 0x10000);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2805 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2806
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2807
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2808 Objects *TemplateInstance::arraySyntaxCopy(Objects *objs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2809 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2810 Objects *a = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2811 if (objs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2812 { a = new Objects();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2813 a->setDim(objs->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2814 for (size_t i = 0; i < objs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2815 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2816 Type *ta = isType((Object *)objs->data[i]);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2817 if (ta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2818 a->data[i] = ta->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2819 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2820 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2821 Expression *ea = isExpression((Object *)objs->data[i]);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2822 assert(ea);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2823 a->data[i] = ea->syntaxCopy();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2824 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2825 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2826 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2827 return a;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2828 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2829
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2830 Dsymbol *TemplateInstance::syntaxCopy(Dsymbol *s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2831 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2832 TemplateInstance *ti;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2833 int i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2834
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2835 if (s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2836 ti = (TemplateInstance *)s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2837 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2838 ti = new TemplateInstance(loc, name);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2839
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2840 ti->tiargs = arraySyntaxCopy(tiargs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2841
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2842 ScopeDsymbol::syntaxCopy(ti);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2843 return ti;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2844 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2845
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2846
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2847 void TemplateInstance::semantic(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2848 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2849 if (global.errors)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2850 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2851 if (!global.gag)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2852 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2853 /* Trying to soldier on rarely generates useful messages
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2854 * at this point.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2855 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2856 fatal();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2857 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2858 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2859 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2860 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2861 printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2862 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2863 if (inst) // if semantic() was already run
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2864 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2865 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2866 printf("-TemplateInstance::semantic('%s', this=%p) already run\n", inst->toChars(), inst);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2867 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2868 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2869 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2870
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2871 if (semanticdone != 0)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2872 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2873 error(loc, "recursive template expansion");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2874 // inst = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2875 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2876 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2877 semanticdone = 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2878
561
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
2879 // get the enclosing template instance from the scope tinst
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
2880 tinst = sc->tinst;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
2881
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2882 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2883 printf("\tdo semantic\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2884 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2885 if (havetempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2886 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2887 assert((size_t)tempdecl->scope > 0x10000);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2888 // Deduce tdtypes
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2889 tdtypes.setDim(tempdecl->parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2890 if (!tempdecl->matchWithInstance(this, &tdtypes, 0))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2891 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2892 error("incompatible arguments for template instantiation");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2893 inst = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2894 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2895 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2896 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2897 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2898 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2899 // Run semantic on each argument, place results in tiargs[]
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2900 semanticTiargs(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2901
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2902 tempdecl = findTemplateDeclaration(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2903 if (tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2904 tempdecl = findBestMatch(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2905 if (!tempdecl || global.errors)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2906 { inst = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2907 //printf("error return %p, %d\n", tempdecl, global.errors);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2908 return; // error recovery
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2909 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2910 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2911
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2912 isNested(tiargs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2913
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2914 /* See if there is an existing TemplateInstantiation that already
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2915 * implements the typeargs. If so, just refer to that one instead.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2916 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2917
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2918 for (size_t i = 0; i < tempdecl->instances.dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2919 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2920 TemplateInstance *ti = (TemplateInstance *)tempdecl->instances.data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2921 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2922 printf("\t%s: checking for match with instance %d (%p): '%s'\n", toChars(), i, ti, ti->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2923 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2924 assert(tdtypes.dim == ti->tdtypes.dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2925
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2926 // Nesting must match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2927 if (isnested != ti->isnested)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2928 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2929 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2930 if (isnested && sc->parent != ti->parent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2931 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2932 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2933 for (size_t j = 0; j < tdtypes.dim; j++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2934 { Object *o1 = (Object *)tdtypes.data[j];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2935 Object *o2 = (Object *)ti->tdtypes.data[j];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2936 if (!match(o1, o2, tempdecl, sc))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2937 goto L1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2938 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2939
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2940 // It's a match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2941 inst = ti;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2942 parent = ti->parent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2943 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2944 printf("\tit's a match with instance %p\n", inst);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2945 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2946 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2947
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2948 L1:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2949 ;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2950 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2951
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2952 /* So, we need to implement 'this' instance.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2953 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2954 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2955 printf("\timplement template instance '%s'\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2956 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2957 unsigned errorsave = global.errors;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2958 inst = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2959 int tempdecl_instance_idx = tempdecl->instances.dim;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2960 tempdecl->instances.push(this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2961 parent = tempdecl->parent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2962 //printf("parent = '%s'\n", parent->kind());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2963
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2964 ident = genIdent(); // need an identifier for name mangling purposes.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2965
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2966 #if 1
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2967 if (isnested)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2968 parent = isnested;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2969 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2970 //printf("parent = '%s'\n", parent->kind());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2971
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2972 // Add 'this' to the enclosing scope's members[] so the semantic routines
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2973 // will get called on the instance members
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2974 #if 1
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2975 int dosemantic3 = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2976 { Array *a;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2977 int i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2978
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2979 if (sc->scopesym && sc->scopesym->members && !sc->scopesym->isTemplateMixin())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2980 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2981 //printf("\t1: adding to %s %s\n", sc->scopesym->kind(), sc->scopesym->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2982 a = sc->scopesym->members;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2983 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2984 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2985 { Module *m = sc->module->importedFrom;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2986 //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2987 a = m->members;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2988 if (m->semanticdone >= 3)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2989 dosemantic3 = 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2990 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2991 for (int i = 0; 1; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2992 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2993 if (i == a->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2994 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2995 a->push(this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2996 break;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2997 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2998 if (this == (Dsymbol *)a->data[i]) // if already in Array
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
2999 break;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3000 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3001 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3002 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3003
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3004 // Copy the syntax trees from the TemplateDeclaration
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3005 members = Dsymbol::arraySyntaxCopy(tempdecl->members);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3006
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3007 // Create our own scope for the template parameters
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3008 Scope *scope = tempdecl->scope;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3009 if (!scope)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3010 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3011 error("forward reference to template declaration %s\n", tempdecl->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3012 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3013 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3014
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3015 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3016 printf("\tcreate scope for template parameters '%s'\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3017 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3018 argsym = new ScopeDsymbol();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3019 argsym->parent = scope->parent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3020 scope = scope->push(argsym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3021
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3022 // Declare each template parameter as an alias for the argument type
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3023 declareParameters(scope);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3024
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3025 // Add members of template instance to template instance symbol table
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3026 // parent = scope->scopesym;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3027 symtab = new DsymbolTable();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3028 int memnum = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3029 for (int i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3030 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3031 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3032 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3033 printf("\t[%d] adding member '%s' %p kind %s to '%s', memnum = %d\n", i, s->toChars(), s, s->kind(), this->toChars(), memnum);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3034 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3035 memnum |= s->addMember(scope, this, memnum);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3036 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3037 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3038 printf("adding members done\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3039 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3040
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3041 /* See if there is only one member of template instance, and that
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3042 * member has the same name as the template instance.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3043 * If so, this template instance becomes an alias for that member.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3044 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3045 //printf("members->dim = %d\n", members->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3046 if (members->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3047 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3048 Dsymbol *s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3049 if (Dsymbol::oneMembers(members, &s) && s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3050 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3051 //printf("s->kind = '%s'\n", s->kind());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3052 //s->print();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3053 //printf("'%s', '%s'\n", s->ident->toChars(), tempdecl->ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3054 if (s->ident && s->ident->equals(tempdecl->ident))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3055 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3056 //printf("setting aliasdecl\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3057 aliasdecl = new AliasDeclaration(loc, s->ident, s);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3058 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3059 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3060 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3061
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3062 // Do semantic() analysis on template instance members
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3063 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3064 printf("\tdo semantic() on template instance members '%s'\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3065 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3066 Scope *sc2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3067 sc2 = scope->push(this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3068 //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3069 sc2->parent = /*isnested ? sc->parent :*/ this;
561
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3070 sc2->tinst = this;
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3071
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3072 #if !IN_LLVM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3073 #if _WIN32
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3074 __try
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3075 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3076 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3077 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3078 for (int i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3079 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3080 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3081 //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3082 //printf("test: isnested = %d, sc2->parent = %s\n", isnested, sc2->parent->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3083 // if (isnested)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3084 // s->parent = sc->parent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3085 //printf("test3: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3086 s->semantic(sc2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3087 //printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3088 sc2->module->runDeferredSemantic();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3089 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3090 #if !IN_LLVM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3091 #if _WIN32
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3092 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3093 __except (__ehfilter(GetExceptionInformation()))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3094 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3095 global.gag = 0; // ensure error message gets printed
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3096 error("recursive expansion");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3097 fatal();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3098 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3099 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3100 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3101
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3102 /* If any of the instantiation members didn't get semantic() run
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3103 * on them due to forward references, we cannot run semantic2()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3104 * or semantic3() yet.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3105 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3106 for (size_t i = 0; i < Module::deferred.dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3107 { Dsymbol *sd = (Dsymbol *)Module::deferred.data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3108
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3109 if (sd->parent == this)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3110 goto Laftersemantic;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3111 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3112
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3113 /* The problem is when to parse the initializer for a variable.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3114 * Perhaps VarDeclaration::semantic() should do it like it does
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3115 * for initializers inside a function.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3116 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3117 // if (sc->parent->isFuncDeclaration())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3118
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3119 /* BUG 782: this has problems if the classes this depends on
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3120 * are forward referenced. Find a way to defer semantic()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3121 * on this template.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3122 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3123 semantic2(sc2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3124
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3125 if (sc->func || dosemantic3)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3126 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3127 semantic3(sc2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3128 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3129
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3130 Laftersemantic:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3131 sc2->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3132
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3133 scope->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3134
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3135 // Give additional context info if error occurred during instantiation
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3136 if (global.errors != errorsave)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3137 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3138 error("error instantiating");
561
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3139 if(tinst)
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3140 tinst->printInstantiationTrace();
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3141 errors = 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3142 if (global.gag)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3143 tempdecl->instances.remove(tempdecl_instance_idx);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3144 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3145
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3146 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3147 printf("-TemplateInstance::semantic('%s', this=%p)\n", toChars(), this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3148 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3149 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3150
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3151
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3152 void TemplateInstance::semanticTiargs(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3153 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3154 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3155 if (semantictiargsdone)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3156 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3157 semantictiargsdone = 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3158 semanticTiargs(loc, sc, tiargs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3159 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3160
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3161 void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3162 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3163 // Run semantic on each argument, place results in tiargs[]
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3164 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3165 if (!tiargs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3166 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3167 for (size_t j = 0; j < tiargs->dim; j++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3168 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3169 Object *o = (Object *)tiargs->data[j];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3170 Type *ta = isType(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3171 Expression *ea = isExpression(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3172 Dsymbol *sa = isDsymbol(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3173
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3174 //printf("1: tiargs->data[%d] = %p, %p, %p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3175 if (ta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3176 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3177 //printf("type %s\n", ta->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3178 // It might really be an Expression or an Alias
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3179 ta->resolve(loc, sc, &ea, &ta, &sa);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3180 if (ea)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3181 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3182 ea = ea->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3183 ea = ea->optimize(WANTvalue | WANTinterpret);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3184 tiargs->data[j] = ea;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3185 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3186 else if (sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3187 { tiargs->data[j] = sa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3188 TupleDeclaration *d = sa->toAlias()->isTupleDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3189 if (d)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3190 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3191 size_t dim = d->objects->dim;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3192 tiargs->remove(j);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3193 tiargs->insert(j, d->objects);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3194 j--;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3195 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3196 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3197 else if (ta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3198 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3199 if (ta->ty == Ttuple)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3200 { // Expand tuple
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3201 TypeTuple *tt = (TypeTuple *)ta;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3202 size_t dim = tt->arguments->dim;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3203 tiargs->remove(j);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3204 if (dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3205 { tiargs->reserve(dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3206 for (size_t i = 0; i < dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3207 { Argument *arg = (Argument *)tt->arguments->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3208 tiargs->insert(j + i, arg->type);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3209 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3210 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3211 j--;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3212 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3213 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3214 tiargs->data[j] = ta;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3215 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3216 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3217 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3218 assert(global.errors);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3219 tiargs->data[j] = Type::terror;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3220 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3221 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3222 else if (ea)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3223 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3224 if (!ea)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3225 { assert(global.errors);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3226 ea = new IntegerExp(0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3227 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3228 assert(ea);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3229 ea = ea->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3230 ea = ea->optimize(WANTvalue | WANTinterpret);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3231 tiargs->data[j] = ea;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3232 if (ea->op == TOKtype)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3233 tiargs->data[j] = ea->type;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3234 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3235 else if (sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3236 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3237 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3238 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3239 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3240 assert(0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3241 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3242 //printf("1: tiargs->data[%d] = %p\n", j, tiargs->data[j]);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3243 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3244 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3245 printf("-TemplateInstance::semanticTiargs('%s', this=%p)\n", toChars(), this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3246 for (size_t j = 0; j < tiargs->dim; j++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3247 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3248 Object *o = (Object *)tiargs->data[j];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3249 Type *ta = isType(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3250 Expression *ea = isExpression(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3251 Dsymbol *sa = isDsymbol(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3252 Tuple *va = isTuple(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3253
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3254 printf("\ttiargs[%d] = ta %p, ea %p, sa %p, va %p\n", j, ta, ea, sa, va);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3255 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3256 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3257 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3258
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3259 /**********************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3260 * Find template declaration corresponding to template instance.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3261 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3262
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3263 TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3264 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3265 //printf("TemplateInstance::findTemplateDeclaration() %s\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3266 if (!tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3267 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3268 /* Given:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3269 * foo!( ... )
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3270 * figure out which TemplateDeclaration foo refers to.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3271 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3272 Dsymbol *s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3273 Dsymbol *scopesym;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3274 Identifier *id;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3275 int i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3276
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3277 id = name;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3278 s = sc->search(loc, id, &scopesym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3279 if (!s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3280 { error("identifier '%s' is not defined", id->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3281 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3282 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3283 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3284 printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3285 if (s->parent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3286 printf("s->parent = '%s'\n", s->parent->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3287 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3288 withsym = scopesym->isWithScopeSymbol();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3289
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3290 /* We might have found an alias within a template when
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3291 * we really want the template.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3292 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3293 TemplateInstance *ti;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3294 if (s->parent &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3295 (ti = s->parent->isTemplateInstance()) != NULL)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3296 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3297 if (
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3298 (ti->name == id ||
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3299 ti->toAlias()->ident == id)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3300 &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3301 ti->tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3302 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3303 /* This is so that one can refer to the enclosing
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3304 * template, even if it has the same name as a member
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3305 * of the template, if it has a !(arguments)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3306 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3307 tempdecl = ti->tempdecl;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3308 if (tempdecl->overroot) // if not start of overloaded list of TemplateDeclaration's
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3309 tempdecl = tempdecl->overroot; // then get the start
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3310 s = tempdecl;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3311 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3312 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3313
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3314 s = s->toAlias();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3315
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3316 /* It should be a TemplateDeclaration, not some other symbol
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3317 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3318 tempdecl = s->isTemplateDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3319 if (!tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3320 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3321 if (!s->parent && global.errors)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3322 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3323 if (!s->parent && s->getType())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3324 { Dsymbol *s2 = s->getType()->toDsymbol(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3325 if (!s2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3326 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3327 error("%s is not a template declaration, it is a %s", id->toChars(), s->kind());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3328 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3329 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3330 s = s2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3331 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3332 #ifdef DEBUG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3333 //if (!s->parent) printf("s = %s %s\n", s->kind(), s->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3334 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3335 //assert(s->parent);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3336 TemplateInstance *ti = s->parent ? s->parent->isTemplateInstance() : NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3337 if (ti &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3338 (ti->name == id ||
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3339 ti->toAlias()->ident == id)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3340 &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3341 ti->tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3342 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3343 /* This is so that one can refer to the enclosing
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3344 * template, even if it has the same name as a member
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3345 * of the template, if it has a !(arguments)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3346 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3347 tempdecl = ti->tempdecl;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3348 if (tempdecl->overroot) // if not start of overloaded list of TemplateDeclaration's
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3349 tempdecl = tempdecl->overroot; // then get the start
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3350 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3351 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3352 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3353 error("%s is not a template declaration, it is a %s", id->toChars(), s->kind());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3354 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3355 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3356 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3357 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3358 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3359 assert(tempdecl->isTemplateDeclaration());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3360 return tempdecl;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3361 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3362
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3363 TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3364 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3365 /* Since there can be multiple TemplateDeclaration's with the same
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3366 * name, look for the best match.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3367 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3368 TemplateDeclaration *td_ambig = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3369 TemplateDeclaration *td_best = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3370 MATCH m_best = MATCHnomatch;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3371 Objects dedtypes;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3372
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3373 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3374 printf("TemplateInstance::findBestMatch()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3375 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3376 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3377 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3378 MATCH m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3379
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3380 //if (tiargs->dim) printf("2: tiargs->dim = %d, data[0] = %p\n", tiargs->dim, tiargs->data[0]);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3381
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3382 // If more arguments than parameters,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3383 // then this is no match.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3384 if (td->parameters->dim < tiargs->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3385 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3386 if (!td->isVariadic())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3387 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3388 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3389
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3390 dedtypes.setDim(td->parameters->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3391 dedtypes.zero();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3392 if (!td->scope)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3393 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3394 error("forward reference to template declaration %s", td->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3395 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3396 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3397 m = td->matchWithInstance(this, &dedtypes, 0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3398 //printf("m = %d\n", m);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3399 if (!m) // no match at all
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3400 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3401
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3402 #if 1
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3403 if (m < m_best)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3404 goto Ltd_best;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3405 if (m > m_best)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3406 goto Ltd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3407 #else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3408 if (!m_best)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3409 goto Ltd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3410 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3411 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3412 // Disambiguate by picking the most specialized TemplateDeclaration
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3413 int c1 = td->leastAsSpecialized(td_best);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3414 int c2 = td_best->leastAsSpecialized(td);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3415 //printf("c1 = %d, c2 = %d\n", c1, c2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3416
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3417 if (c1 > c2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3418 goto Ltd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3419 else if (c1 < c2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3420 goto Ltd_best;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3421 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3422 goto Lambig;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3423 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3424
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3425 Lambig: // td_best and td are ambiguous
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3426 td_ambig = td;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3427 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3428
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3429 Ltd_best: // td_best is the best match so far
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3430 td_ambig = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3431 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3432
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3433 Ltd: // td is the new best match
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3434 td_ambig = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3435 td_best = td;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3436 m_best = m;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3437 tdtypes.setDim(dedtypes.dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3438 memcpy(tdtypes.data, dedtypes.data, tdtypes.dim * sizeof(void *));
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3439 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3440 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3441
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3442 if (!td_best)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3443 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3444 error("%s does not match any template declaration", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3445 return NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3446 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3447 if (td_ambig)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3448 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3449 error("%s matches more than one template declaration, %s and %s",
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3450 toChars(), td_best->toChars(), td_ambig->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3451 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3452
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3453 /* The best match is td_best
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3454 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3455 tempdecl = td_best;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3456
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3457 #if 0
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3458 /* Cast any value arguments to be same type as value parameter
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3459 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3460 for (size_t i = 0; i < tiargs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3461 { Object *o = (Object *)tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3462 Expression *ea = isExpression(o); // value argument
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3463 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3464 assert(tp);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3465 TemplateValueParameter *tvp = tp->isTemplateValueParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3466 if (tvp)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3467 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3468 assert(ea);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3469 ea = ea->castTo(tvp->valType);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3470 ea = ea->optimize(WANTvalue | WANTinterpret);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3471 tiargs->data[i] = (Object *)ea;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3472 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3473 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3474 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3475
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3476 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3477 printf("\tIt's a match with template declaration '%s'\n", tempdecl->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3478 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3479 return tempdecl;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3480 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3481
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3482
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3483 /*****************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3484 * Determines if a TemplateInstance will need a nested
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3485 * generation of the TemplateDeclaration.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3486 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3487
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3488 int TemplateInstance::isNested(Objects *args)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3489 { int nested = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3490 //printf("TemplateInstance::isNested('%s')\n", tempdecl->ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3491
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3492 /* A nested instance happens when an argument references a local
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3493 * symbol that is on the stack.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3494 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3495 for (size_t i = 0; i < args->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3496 { Object *o = (Object *)args->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3497 Expression *ea = isExpression(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3498 Dsymbol *sa = isDsymbol(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3499 Tuple *va = isTuple(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3500 if (ea)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3501 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3502 if (ea->op == TOKvar)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3503 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3504 sa = ((VarExp *)ea)->var;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3505 goto Lsa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3506 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3507 if (ea->op == TOKfunction)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3508 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3509 sa = ((FuncExp *)ea)->fd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3510 goto Lsa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3511 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3512 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3513 else if (sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3514 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3515 Lsa:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3516 Declaration *d = sa->isDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3517 if (d && !d->isDataseg() &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3518 #if DMDV2
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3519 !(d->storage_class & STCmanifest) &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3520 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3521 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3522 !isTemplateMixin())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3523 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3524 // if module level template
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3525 if (tempdecl->toParent()->isModule())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3526 { Dsymbol *dparent = d->toParent();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3527 if (!isnested)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3528 isnested = dparent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3529 else if (isnested != dparent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3530 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3531 /* Select the more deeply nested of the two.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3532 * Error if one is not nested inside the other.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3533 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3534 for (Dsymbol *p = isnested; p; p = p->parent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3535 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3536 if (p == dparent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3537 goto L1; // isnested is most nested
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3538 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3539 for (Dsymbol *p = dparent; 1; p = p->parent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3540 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3541 if (p == isnested)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3542 { isnested = dparent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3543 goto L1; // dparent is most nested
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3544 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3545 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3546 error("is nested in both %s and %s", isnested->toChars(), dparent->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3547 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3548 L1:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3549 //printf("\tnested inside %s\n", isnested->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3550 nested |= 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3551 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3552 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3553 error("cannot use local '%s' as template parameter", d->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3554 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3555 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3556 else if (va)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3557 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3558 nested |= isNested(&va->objects);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3559 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3560 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3561 return nested;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3562 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3563
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3564 /****************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3565 * This instance needs an identifier for name mangling purposes.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3566 * Create one by taking the template declaration name and adding
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3567 * the type signature for it.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3568 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3569
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3570 Identifier *TemplateInstance::genIdent()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3571 { OutBuffer buf;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3572 char *id;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3573 Objects *args;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3574
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3575 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3576 id = tempdecl->ident->toChars();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3577 buf.printf("__T%"PRIuSIZE"%s", strlen(id), id);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3578 args = tiargs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3579 for (int i = 0; i < args->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3580 { Object *o = (Object *)args->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3581 Type *ta = isType(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3582 Expression *ea = isExpression(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3583 Dsymbol *sa = isDsymbol(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3584 Tuple *va = isTuple(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3585 //printf("\to %p ta %p ea %p sa %p va %p\n", o, ta, ea, sa, va);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3586 if (ta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3587 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3588 buf.writeByte('T');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3589 if (ta->deco)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3590 buf.writestring(ta->deco);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3591 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3592 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3593 #ifdef DEBUG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3594 printf("ta = %d, %s\n", ta->ty, ta->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3595 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3596 assert(global.errors);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3597 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3598 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3599 else if (ea)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3600 { sinteger_t v;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3601 real_t r;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3602
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3603 if (ea->op == TOKvar)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3604 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3605 sa = ((VarExp *)ea)->var;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3606 ea = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3607 goto Lsa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3608 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3609 if (ea->op == TOKfunction)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3610 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3611 sa = ((FuncExp *)ea)->fd;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3612 ea = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3613 goto Lsa;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3614 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3615 buf.writeByte('V');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3616 if (ea->op == TOKtuple)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3617 { ea->error("tuple is not a valid template value argument");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3618 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3619 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3620 #if 1
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3621 /* Use deco that matches what it would be for a function parameter
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3622 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3623 buf.writestring(ea->type->deco);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3624 #else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3625 // Use type of parameter, not type of argument
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3626 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3627 assert(tp);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3628 TemplateValueParameter *tvp = tp->isTemplateValueParameter();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3629 assert(tvp);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3630 buf.writestring(tvp->valType->deco);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3631 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3632 ea->toMangleBuffer(&buf);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3633 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3634 else if (sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3635 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3636 Lsa:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3637 buf.writeByte('S');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3638 Declaration *d = sa->isDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3639 if (d && !d->type->deco)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3640 error("forward reference of %s", d->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3641 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3642 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3643 char *p = sa->mangle();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3644 buf.printf("%"PRIuSIZE"%s", strlen(p), p);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3645 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3646 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3647 else if (va)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3648 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3649 assert(i + 1 == args->dim); // must be last one
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3650 args = &va->objects;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3651 i = -1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3652 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3653 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3654 assert(0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3655 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3656 buf.writeByte('Z');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3657 id = buf.toChars();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3658 buf.data = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3659 return new Identifier(id, TOKidentifier);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3660 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3661
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3662
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3663 /****************************************************
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3664 * Declare parameters of template instance, initialize them with the
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3665 * template instance arguments.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3666 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3667
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3668 void TemplateInstance::declareParameters(Scope *scope)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3669 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3670 //printf("TemplateInstance::declareParameters()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3671 for (int i = 0; i < tdtypes.dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3672 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3673 TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3674 //Object *o = (Object *)tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3675 Object *o = (Object *)tdtypes.data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3676
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3677 //printf("\ttdtypes[%d] = %p\n", i, o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3678 tempdecl->declareParameter(scope, tp, o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3679 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3680 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3681
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3682
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3683 void TemplateInstance::semantic2(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3684 { int i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3685
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3686 if (semanticdone >= 2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3687 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3688 semanticdone = 2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3689 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3690 printf("+TemplateInstance::semantic2('%s')\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3691 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3692 if (!errors && members)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3693 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3694 sc = tempdecl->scope;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3695 assert(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3696 sc = sc->push(argsym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3697 sc = sc->push(this);
561
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3698 sc->tinst = this;
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3699 for (i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3700 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3701 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3702 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3703 printf("\tmember '%s', kind = '%s'\n", s->toChars(), s->kind());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3704 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3705 s->semantic2(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3706 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3707 sc = sc->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3708 sc->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3709 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3710 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3711 printf("-TemplateInstance::semantic2('%s')\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3712 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3713 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3714
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3715 void TemplateInstance::semantic3(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3716 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3717 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3718 printf("TemplateInstance::semantic3('%s'), semanticdone = %d\n", toChars(), semanticdone);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3719 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3720 //if (toChars()[0] == 'D') *(char*)0=0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3721 if (semanticdone >= 3)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3722 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3723 semanticdone = 3;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3724 if (!errors && members)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3725 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3726 sc = tempdecl->scope;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3727 sc = sc->push(argsym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3728 sc = sc->push(this);
561
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3729 sc->tinst = this;
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3730 for (int i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3731 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3732 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3733 s->semantic3(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3734 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3735 sc = sc->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3736 sc->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3737 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3738 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3739
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3740 void TemplateInstance::toObjFile(int multiobj)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3741 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3742 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3743 printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3744 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3745 if (!errors && members)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3746 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3747 if (multiobj)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3748 // Append to list of object files to be written later
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3749 //obj_append(this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3750 assert(0 && "multiobj");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3751 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3752 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3753 for (int i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3754 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3755 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3756 s->toObjFile(multiobj);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3757 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3758 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3759 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3760 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3761
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3762 void TemplateInstance::inlineScan()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3763 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3764 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3765 printf("TemplateInstance::inlineScan('%s')\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3766 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3767 if (!errors && members)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3768 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3769 for (int i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3770 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3771 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3772 s->inlineScan();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3773 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3774 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3775 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3776
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3777 void TemplateInstance::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3778 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3779 int i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3780
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3781 Identifier *id = name;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3782 buf->writestring(id->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3783 buf->writestring("!(");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3784 if (nest)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3785 buf->writestring("...");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3786 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3787 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3788 nest++;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3789 Objects *args = tiargs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3790 for (i = 0; i < args->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3791 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3792 if (i)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3793 buf->writeByte(',');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3794 Object *oarg = (Object *)args->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3795 ObjectToCBuffer(buf, hgs, oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3796 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3797 nest--;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3798 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3799 buf->writeByte(')');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3800 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3801
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3802
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3803 Dsymbol *TemplateInstance::toAlias()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3804 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3805 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3806 printf("TemplateInstance::toAlias()\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3807 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3808 if (!inst)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3809 { error("cannot resolve forward reference");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3810 return this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3811 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3812
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3813 if (inst != this)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3814 return inst->toAlias();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3815
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3816 if (aliasdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3817 return aliasdecl->toAlias();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3818
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3819 return inst;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3820 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3821
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3822 AliasDeclaration *TemplateInstance::isAliasDeclaration()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3823 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3824 return aliasdecl;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3825 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3826
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3827 const char *TemplateInstance::kind()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3828 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3829 return "template instance";
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3830 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3831
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3832 int TemplateInstance::oneMember(Dsymbol **ps)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3833 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3834 *ps = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3835 return TRUE;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3836 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3837
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3838 char *TemplateInstance::toChars()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3839 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3840 OutBuffer buf;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3841 HdrGenState hgs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3842 char *s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3843
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3844 toCBuffer(&buf, &hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3845 s = buf.toChars();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3846 buf.data = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3847 return s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3848 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3849
561
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3850 void TemplateInstance::printInstantiationTrace()
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3851 {
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3852 if(global.gag)
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3853 return;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3854
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3855 const int max_shown = 6;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3856
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3857 // determine instantiation depth
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3858 int n_instantiations = 1;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3859 TemplateInstance* cur = this;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3860 while(cur = cur->tinst)
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3861 ++n_instantiations;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3862
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3863 // show full trace only if it's short or verbose is on
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3864 if(n_instantiations <= max_shown || global.params.verbose)
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3865 {
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3866 cur = this;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3867 while(cur)
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3868 {
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3869 fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars());
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3870 cur = cur->tinst;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3871 }
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3872 }
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3873 else
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3874 {
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3875 cur = this;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3876 size_t i = 0;
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3877 for(; i < max_shown/2; ++i, cur = cur->tinst)
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3878 fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars());
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3879 fprintf(stdmsg," ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown);
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3880 for(; i < n_instantiations - max_shown + max_shown/2; ++i, cur = cur->tinst)
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3881 {}
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3882 for(; i < n_instantiations; ++i, cur = cur->tinst)
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3883 fprintf(stdmsg," instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars());
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3884 }
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3885 }
d4e95db0e62b Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents: 527
diff changeset
3886
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3887 /* ======================== TemplateMixin ================================ */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3888
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3889 TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3890 Array *idents, Objects *tiargs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3891 : TemplateInstance(loc, (Identifier *)idents->data[idents->dim - 1])
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3892 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3893 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : "");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3894 this->ident = ident;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3895 this->tqual = tqual;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3896 this->idents = idents;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3897 this->tiargs = tiargs ? tiargs : new Objects();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3898 this->scope = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3899 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3900
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3901 Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3902 { TemplateMixin *tm;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3903
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3904 Array *ids = new Array();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3905 ids->setDim(idents->dim);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3906 for (int i = 0; i < idents->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3907 { // Matches TypeQualified::syntaxCopyHelper()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3908 Identifier *id = (Identifier *)idents->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3909 if (id->dyncast() == DYNCAST_DSYMBOL)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3910 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3911 TemplateInstance *ti = (TemplateInstance *)id;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3912
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3913 ti = (TemplateInstance *)ti->syntaxCopy(NULL);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3914 id = (Identifier *)ti;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3915 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3916 ids->data[i] = id;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3917 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3918
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3919 tm = new TemplateMixin(loc, ident,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3920 (Type *)(tqual ? tqual->syntaxCopy() : NULL),
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3921 ids, tiargs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3922 TemplateInstance::syntaxCopy(tm);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3923 return tm;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3924 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3925
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3926 void TemplateMixin::semantic(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3927 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3928 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3929 printf("+TemplateMixin::semantic('%s', this=%p)\n", toChars(), this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3930 fflush(stdout);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3931 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3932 if (semanticdone &&
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3933 // This for when a class/struct contains mixin members, and
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3934 // is done over because of forward references
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3935 (!parent || !toParent()->isAggregateDeclaration()))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3936 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3937 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3938 printf("\tsemantic done\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3939 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3940 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3941 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3942 if (!semanticdone)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3943 semanticdone = 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3944 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3945 printf("\tdo semantic\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3946 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3947
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3948 #if !IN_LLVM
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3949 // dont know what this is
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3950 util_progress();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3951 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3952
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3953 Scope *scx = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3954 if (scope)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3955 { sc = scope;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3956 scx = scope; // save so we don't make redundant copies
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3957 scope = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3958 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3959
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3960 // Follow qualifications to find the TemplateDeclaration
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3961 if (!tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3962 { Dsymbol *s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3963 int i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3964 Identifier *id;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3965
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3966 if (tqual)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3967 { s = tqual->toDsymbol(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3968 i = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3969 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3970 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3971 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3972 i = 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3973 id = (Identifier *)idents->data[0];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3974 switch (id->dyncast())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3975 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3976 case DYNCAST_IDENTIFIER:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3977 s = sc->search(loc, id, NULL);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3978 break;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3979
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3980 case DYNCAST_DSYMBOL:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3981 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3982 TemplateInstance *ti = (TemplateInstance *)id;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3983 ti->semantic(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3984 s = ti;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3985 break;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3986 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3987 default:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3988 assert(0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3989 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3990 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3991
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3992 for (; i < idents->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3993 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3994 if (!s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3995 break;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3996 id = (Identifier *)idents->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3997 s = s->searchX(loc, sc, id);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3998 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
3999 if (!s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4000 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4001 error("is not defined");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4002 inst = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4003 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4004 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4005 tempdecl = s->toAlias()->isTemplateDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4006 if (!tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4007 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4008 error("%s isn't a template", s->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4009 inst = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4010 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4011 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4012 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4013
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4014 // Look for forward reference
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4015 assert(tempdecl);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4016 for (TemplateDeclaration *td = tempdecl; td; td = td->overnext)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4017 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4018 if (!td->scope)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4019 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4020 /* Cannot handle forward references if mixin is a struct member,
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4021 * because addField must happen during struct's semantic, not
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4022 * during the mixin semantic.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4023 * runDeferred will re-run mixin's semantic outside of the struct's
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4024 * semantic.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4025 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4026 semanticdone = 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4027 AggregateDeclaration *ad = toParent()->isAggregateDeclaration();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4028 if (ad)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4029 ad->sizeok = 2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4030 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4031 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4032 // Forward reference
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4033 //printf("forward reference - deferring\n");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4034 scope = scx ? scx : new Scope(*sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4035 scope->setNoFree();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4036 scope->module->addDeferredSemantic(this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4037 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4038 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4039 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4040 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4041
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4042 // Run semantic on each argument, place results in tiargs[]
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4043 semanticTiargs(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4044
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4045 tempdecl = findBestMatch(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4046 if (!tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4047 { inst = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4048 return; // error recovery
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4049 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4050
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4051 if (!ident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4052 ident = genIdent();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4053
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4054 inst = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4055 parent = sc->parent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4056
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4057 /* Detect recursive mixin instantiations.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4058 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4059 for (Dsymbol *s = parent; s; s = s->parent)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4060 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4061 //printf("\ts = '%s'\n", s->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4062 TemplateMixin *tm = s->isTemplateMixin();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4063 if (!tm || tempdecl != tm->tempdecl)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4064 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4065
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4066 /* Different argument list lengths happen with variadic args
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4067 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4068 if (tiargs->dim != tm->tiargs->dim)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4069 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4070
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4071 for (int i = 0; i < tiargs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4072 { Object *o = (Object *)tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4073 Type *ta = isType(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4074 Expression *ea = isExpression(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4075 Dsymbol *sa = isDsymbol(o);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4076 Object *tmo = (Object *)tm->tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4077 if (ta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4078 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4079 Type *tmta = isType(tmo);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4080 if (!tmta)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4081 goto Lcontinue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4082 if (!ta->equals(tmta))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4083 goto Lcontinue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4084 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4085 else if (ea)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4086 { Expression *tme = isExpression(tmo);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4087 if (!tme || !ea->equals(tme))
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4088 goto Lcontinue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4089 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4090 else if (sa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4091 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4092 Dsymbol *tmsa = isDsymbol(tmo);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4093 if (sa != tmsa)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4094 goto Lcontinue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4095 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4096 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4097 assert(0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4098 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4099 error("recursive mixin instantiation");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4100 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4101
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4102 Lcontinue:
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4103 continue;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4104 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4105
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4106 // Copy the syntax trees from the TemplateDeclaration
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4107 members = Dsymbol::arraySyntaxCopy(tempdecl->members);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4108 if (!members)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4109 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4110
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4111 symtab = new DsymbolTable();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4112
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4113 for (Scope *sce = sc; 1; sce = sce->enclosing)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4114 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4115 ScopeDsymbol *sds = (ScopeDsymbol *)sce->scopesym;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4116 if (sds)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4117 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4118 sds->importScope(this, PROTpublic);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4119 break;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4120 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4121 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4122
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4123 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4124 printf("\tcreate scope for template parameters '%s'\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4125 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4126 Scope *scy = sc;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4127 scy = sc->push(this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4128 scy->parent = this;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4129
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4130 argsym = new ScopeDsymbol();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4131 argsym->parent = scy->parent;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4132 Scope *scope = scy->push(argsym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4133
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4134 unsigned errorsave = global.errors;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4135
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4136 // Declare each template parameter as an alias for the argument type
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4137 declareParameters(scope);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4138
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4139 // Add members to enclosing scope, as well as this scope
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4140 for (unsigned i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4141 { Dsymbol *s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4142
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4143 s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4144 s->addMember(scope, this, i);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4145 //sc->insert(s);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4146 //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4147 //printf("s->parent = %s\n", s->parent->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4148 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4149
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4150 // Do semantic() analysis on template instance members
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4151 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4152 printf("\tdo semantic() on template instance members '%s'\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4153 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4154 Scope *sc2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4155 sc2 = scope->push(this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4156 sc2->offset = sc->offset;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4157 for (int i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4158 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4159 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4160 s->semantic(sc2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4161 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4162 sc->offset = sc2->offset;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4163
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4164 /* The problem is when to parse the initializer for a variable.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4165 * Perhaps VarDeclaration::semantic() should do it like it does
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4166 * for initializers inside a function.
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4167 */
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4168 // if (sc->parent->isFuncDeclaration())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4169
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4170 semantic2(sc2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4171
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4172 if (sc->func)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4173 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4174 semantic3(sc2);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4175 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4176
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4177 // Give additional context info if error occurred during instantiation
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4178 if (global.errors != errorsave)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4179 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4180 error("error instantiating");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4181 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4182
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4183 sc2->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4184
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4185 scope->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4186
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4187 // if (!isAnonymous())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4188 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4189 scy->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4190 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4191 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4192 printf("-TemplateMixin::semantic('%s', this=%p)\n", toChars(), this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4193 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4194 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4195
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4196 void TemplateMixin::semantic2(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4197 { int i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4198
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4199 if (semanticdone >= 2)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4200 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4201 semanticdone = 2;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4202 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4203 printf("+TemplateMixin::semantic2('%s')\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4204 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4205 if (members)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4206 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4207 assert(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4208 sc = sc->push(argsym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4209 sc = sc->push(this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4210 for (i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4211 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4212 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4213 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4214 printf("\tmember '%s', kind = '%s'\n", s->toChars(), s->kind());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4215 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4216 s->semantic2(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4217 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4218 sc = sc->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4219 sc->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4220 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4221 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4222 printf("-TemplateMixin::semantic2('%s')\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4223 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4224 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4225
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4226 void TemplateMixin::semantic3(Scope *sc)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4227 { int i;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4228
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4229 if (semanticdone >= 3)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4230 return;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4231 semanticdone = 3;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4232 #if LOG
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4233 printf("TemplateMixin::semantic3('%s')\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4234 #endif
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4235 if (members)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4236 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4237 sc = sc->push(argsym);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4238 sc = sc->push(this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4239 for (i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4240 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4241 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4242 s->semantic3(sc);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4243 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4244 sc = sc->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4245 sc->pop();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4246 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4247 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4248
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4249 void TemplateMixin::inlineScan()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4250 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4251 TemplateInstance::inlineScan();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4252 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4253
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4254 const char *TemplateMixin::kind()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4255 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4256 return "mixin";
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4257 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4258
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4259 int TemplateMixin::oneMember(Dsymbol **ps)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4260 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4261 return Dsymbol::oneMember(ps);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4262 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4263
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4264 int TemplateMixin::hasPointers()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4265 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4266 //printf("TemplateMixin::hasPointers() %s\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4267 for (size_t i = 0; i < members->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4268 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4269 Dsymbol *s = (Dsymbol *)members->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4270 //printf(" s = %s %s\n", s->kind(), s->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4271 if (s->hasPointers())
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4272 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4273 return 1;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4274 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4275 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4276 return 0;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4277 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4278
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4279 char *TemplateMixin::toChars()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4280 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4281 OutBuffer buf;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4282 HdrGenState hgs;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4283 char *s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4284
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4285 TemplateInstance::toCBuffer(&buf, &hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4286 s = buf.toChars();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4287 buf.data = NULL;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4288 return s;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4289 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4290
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4291 void TemplateMixin::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4292 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4293 buf->writestring("mixin ");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4294
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4295 for (int i = 0; i < idents->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4296 { Identifier *id = (Identifier *)idents->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4297
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4298 if (i)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4299 buf->writeByte('.');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4300 buf->writestring(id->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4301 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4302 buf->writestring("!(");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4303 if (tiargs)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4304 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4305 for (int i = 0; i < tiargs->dim; i++)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4306 { if (i)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4307 buf->writebyte(',');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4308 Object *oarg = (Object *)tiargs->data[i];
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4309 Type *t = isType(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4310 Expression *e = isExpression(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4311 Dsymbol *s = isDsymbol(oarg);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4312 if (t)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4313 t->toCBuffer(buf, NULL, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4314 else if (e)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4315 e->toCBuffer(buf, hgs);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4316 else if (s)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4317 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4318 char *p = s->ident ? s->ident->toChars() : s->toChars();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4319 buf->writestring(p);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4320 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4321 else if (!oarg)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4322 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4323 buf->writestring("NULL");
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4324 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4325 else
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4326 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4327 assert(0);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4328 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4329 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4330 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4331 buf->writebyte(')');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4332 if (ident)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4333 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4334 buf->writebyte(' ');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4335 buf->writestring(ident->toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4336 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4337 buf->writebyte(';');
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4338 buf->writenl();
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4339 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4340
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4341
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4342 void TemplateMixin::toObjFile(int multiobj)
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4343 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4344 //printf("TemplateMixin::toObjFile('%s')\n", toChars());
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4345 TemplateInstance::toObjFile(multiobj);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4346 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 305
diff changeset
4347