root/trunk/src/template.h

Revision 811, 12.1 kB (checked in by walter, 1 year ago)

better fix for the recursive template constraint issue

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2010 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #ifndef DMD_TEMPLATE_H
11 #define DMD_TEMPLATE_H
12
13 #ifdef __DMC__
14 #pragma once
15 #endif /* __DMC__ */
16
17 #include "root.h"
18 #include "arraytypes.h"
19 #include "dsymbol.h"
20
21
22 struct OutBuffer;
23 struct Identifier;
24 struct TemplateInstance;
25 struct TemplateParameter;
26 struct TemplateTypeParameter;
27 struct TemplateThisParameter;
28 struct TemplateValueParameter;
29 struct TemplateAliasParameter;
30 struct TemplateTupleParameter;
31 struct Type;
32 struct TypeTypeof;
33 struct Scope;
34 struct Expression;
35 struct AliasDeclaration;
36 struct FuncDeclaration;
37 struct HdrGenState;
38 enum MATCH;
39
40 struct Tuple : Object
41 {
42     Objects objects;
43
44     int dyncast() { return DYNCAST_TUPLE; } // kludge for template.isType()
45 };
46
47
48 struct TemplateDeclaration : ScopeDsymbol
49 {
50     TemplateParameters *parameters;     // array of TemplateParameter's
51
52     TemplateParameters *origParameters; // originals for Ddoc
53     Expression *constraint;
54     Array instances;                    // array of TemplateInstance's
55
56     TemplateDeclaration *overnext;      // next overloaded TemplateDeclaration
57     TemplateDeclaration *overroot;      // first in overnext list
58
59     int semanticRun;                    // 1 semantic() run
60
61     Dsymbol *onemember;         // if !=NULL then one member of this template
62
63     int literal;                // this template declaration is a literal
64     int ismixin;                // template declaration is only to be used as a mixin
65
66     struct Previous
67     {   Previous *prev;
68         Scope *sc;
69         Objects *dedargs;
70     };
71     Previous *previous;         // threaded list of previous instantiation attempts on stack
72
73     TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters,
74         Expression *constraint, Dsymbols *decldefs, int ismixin);
75     Dsymbol *syntaxCopy(Dsymbol *);
76     void semantic(Scope *sc);
77     int overloadInsert(Dsymbol *s);
78     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
79     const char *kind();
80     char *toChars();
81
82     void emitComment(Scope *sc);
83     void toJsonBuffer(OutBuffer *buf);
84 //    void toDocBuffer(OutBuffer *buf);
85
86     MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag);
87     MATCH leastAsSpecialized(TemplateDeclaration *td2);
88
89     MATCH deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, Objects *dedargs);
90     FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, int flags = 0);
91     void declareParameter(Scope *sc, TemplateParameter *tp, Object *o);
92
93     TemplateDeclaration *isTemplateDeclaration() { return this; }
94
95     TemplateTupleParameter *isVariadic();
96     int isOverloadable();
97
98     void makeParamNamesVisibleInConstraint(Scope *paramscope);
99 };
100
101 struct TemplateParameter
102 {
103     /* For type-parameter:
104      *  template Foo(ident)             // specType is set to NULL
105      *  template Foo(ident : specType)
106      * For value-parameter:
107      *  template Foo(valType ident)     // specValue is set to NULL
108      *  template Foo(valType ident : specValue)
109      * For alias-parameter:
110      *  template Foo(alias ident)
111      * For this-parameter:
112      *  template Foo(this ident)
113      */
114
115     Loc loc;
116     Identifier *ident;
117
118     Declaration *sparam;
119
120     TemplateParameter(Loc loc, Identifier *ident);
121
122     virtual TemplateTypeParameter  *isTemplateTypeParameter();
123     virtual TemplateValueParameter *isTemplateValueParameter();
124     virtual TemplateAliasParameter *isTemplateAliasParameter();
125 #if DMDV2
126     virtual TemplateThisParameter *isTemplateThisParameter();
127 #endif
128     virtual TemplateTupleParameter *isTemplateTupleParameter();
129
130     virtual TemplateParameter *syntaxCopy() = 0;
131     virtual void declareParameter(Scope *sc) = 0;
132     virtual void semantic(Scope *) = 0;
133     virtual void print(Object *oarg, Object *oded) = 0;
134     virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
135     virtual Object *specialization() = 0;
136     virtual Object *defaultArg(Loc loc, Scope *sc) = 0;
137
138     /* If TemplateParameter's match as far as overloading goes.
139      */
140     virtual int overloadMatch(TemplateParameter *) = 0;
141
142     /* Match actual argument against parameter.
143      */
144     virtual MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags = 0) = 0;
145
146     /* Create dummy argument based on parameter.
147      */
148     virtual void *dummyArg() = 0;
149 };
150
151 struct TemplateTypeParameter : TemplateParameter
152 {
153     /* Syntax:
154      *  ident : specType = defaultType
155      */
156     Type *specType;     // type parameter: if !=NULL, this is the type specialization
157     Type *defaultType;
158
159     TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
160
161     TemplateTypeParameter *isTemplateTypeParameter();
162     TemplateParameter *syntaxCopy();
163     void declareParameter(Scope *sc);
164     void semantic(Scope *);
165     void print(Object *oarg, Object *oded);
166     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
167     Object *specialization();
168     Object *defaultArg(Loc loc, Scope *sc);
169     int overloadMatch(TemplateParameter *);
170     MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
171     void *dummyArg();
172 };
173
174 #if DMDV2
175 struct TemplateThisParameter : TemplateTypeParameter
176 {
177     /* Syntax:
178      *  this ident : specType = defaultType
179      */
180     Type *specType;     // type parameter: if !=NULL, this is the type specialization
181     Type *defaultType;
182
183     TemplateThisParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
184
185     TemplateThisParameter *isTemplateThisParameter();
186     TemplateParameter *syntaxCopy();
187     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
188 };
189 #endif
190
191 struct TemplateValueParameter : TemplateParameter
192 {
193     /* Syntax:
194      *  valType ident : specValue = defaultValue
195      */
196
197     Type *valType;
198     Expression *specValue;
199     Expression *defaultValue;
200
201     static Expression *edummy;
202
203     TemplateValueParameter(Loc loc, Identifier *ident, Type *valType, Expression *specValue, Expression *defaultValue);
204
205     TemplateValueParameter *isTemplateValueParameter();
206     TemplateParameter *syntaxCopy();
207     void declareParameter(Scope *sc);
208     void semantic(Scope *);
209     void print(Object *oarg, Object *oded);
210     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
211     Object *specialization();
212     Object *defaultArg(Loc loc, Scope *sc);
213     int overloadMatch(TemplateParameter *);
214     MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
215     void *dummyArg();
216 };
217
218 struct TemplateAliasParameter : TemplateParameter
219 {
220     /* Syntax:
221      *  specType ident : specAlias = defaultAlias
222      */
223
224     Type *specType;
225     Object *specAlias;
226     Object *defaultAlias;
227
228     static Dsymbol *sdummy;
229
230     TemplateAliasParameter(Loc loc, Identifier *ident, Type *specType, Object *specAlias, Object *defaultAlias);
231
232     TemplateAliasParameter *isTemplateAliasParameter();
233     TemplateParameter *syntaxCopy();
234     void declareParameter(Scope *sc);
235     void semantic(Scope *);
236     void print(Object *oarg, Object *oded);
237     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
238     Object *specialization();
239     Object *defaultArg(Loc loc, Scope *sc);
240     int overloadMatch(TemplateParameter *);
241     MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
242     void *dummyArg();
243 };
244
245 struct TemplateTupleParameter : TemplateParameter
246 {
247     /* Syntax:
248      *  ident ...
249      */
250
251     TemplateTupleParameter(Loc loc, Identifier *ident);
252
253     TemplateTupleParameter *isTemplateTupleParameter();
254     TemplateParameter *syntaxCopy();
255     void declareParameter(Scope *sc);
256     void semantic(Scope *);
257     void print(Object *oarg, Object *oded);
258     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
259     Object *specialization();
260     Object *defaultArg(Loc loc, Scope *sc);
261     int overloadMatch(TemplateParameter *);
262     MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam, int flags);
263     void *dummyArg();
264 };
265
266 struct TemplateInstance : ScopeDsymbol
267 {
268     /* Given:
269      *  foo!(args) =>
270      *      name = foo
271      *      tiargs = args
272      */
273     Identifier *name;
274     //Array idents;
275     Objects *tiargs;            // Array of Types/Expressions of template
276                                 // instance arguments [int*, char, 10*10]
277
278     Objects tdtypes;            // Array of Types/Expressions corresponding
279                                 // to TemplateDeclaration.parameters
280                                 // [int, char, 100]
281
282     TemplateDeclaration *tempdecl;      // referenced by foo.bar.abc
283     TemplateInstance *inst;             // refer to existing instance
284     TemplateInstance *tinst;            // enclosing template instance
285     ScopeDsymbol *argsym;               // argument symbol table
286     AliasDeclaration *aliasdecl;        // !=NULL if instance is an alias for its
287                                         // sole member
288     WithScopeSymbol *withsym;           // if a member of a with statement
289     int semanticRun;    // has semantic() been done?
290     int semantictiargsdone;     // has semanticTiargs() been done?
291     int nest;           // for recursion detection
292     int havetempdecl;   // 1 if used second constructor
293     Dsymbol *isnested;  // if referencing local symbols, this is the context
294     int errors;         // 1 if compiled with errors
295 #ifdef IN_GCC
296     /* On some targets, it is necessary to know whether a symbol
297        will be emitted in the output or not before the symbol
298        is used.  This can be different from getModule(). */
299     Module * objFileModule;
300 #endif
301
302     TemplateInstance(Loc loc, Identifier *temp_id);
303     TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs);
304     static Objects *arraySyntaxCopy(Objects *objs);
305     Dsymbol *syntaxCopy(Dsymbol *);
306     void semantic(Scope *sc, Expressions *fargs);
307     void semantic(Scope *sc);
308     void semantic2(Scope *sc);
309     void semantic3(Scope *sc);
310     void inlineScan();
311     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
312     Dsymbol *toAlias();                 // resolve real symbol
313     const char *kind();
314     int oneMember(Dsymbol **ps);
315     int needsTypeInference(Scope *sc);
316     char *toChars();
317     char *mangle();
318     void printInstantiationTrace();
319
320     void toObjFile(int multiobj);                       // compile to .obj file
321
322     // Internal
323     static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags);
324     void semanticTiargs(Scope *sc);
325     TemplateDeclaration *findTemplateDeclaration(Scope *sc);
326     TemplateDeclaration *findBestMatch(Scope *sc);
327     void declareParameters(Scope *sc);
328     int hasNestedArgs(Objects *tiargs);
329     Identifier *genIdent(Objects *args);
330
331     TemplateInstance *isTemplateInstance() { return this; }
332     AliasDeclaration *isAliasDeclaration();
333 };
334
335 struct TemplateMixin : TemplateInstance
336 {
337     Array *idents;
338     Type *tqual;
339
340     TemplateMixin(Loc loc, Identifier *ident, Type *tqual, Array *idents, Objects *tiargs);
341     Dsymbol *syntaxCopy(Dsymbol *s);
342     void semantic(Scope *sc);
343     void semantic2(Scope *sc);
344     void semantic3(Scope *sc);
345     void inlineScan();
346     const char *kind();
347     int oneMember(Dsymbol **ps);
348     int hasPointers();
349     char *toChars();
350     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
351
352     void toObjFile(int multiobj);                       // compile to .obj file
353
354     TemplateMixin *isTemplateMixin() { return this; }
355 };
356
357 Expression *isExpression(Object *o);
358 Dsymbol *isDsymbol(Object *o);
359 Type *isType(Object *o);
360 Tuple *isTuple(Object *o);
361 int arrayObjectIsError(Objects *args);
362 int isError(Object *o);
363 Type *getType(Object *o);
364 Dsymbol *getDsymbol(Object *o);
365
366 void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg);
367 Object *objectSyntaxCopy(Object *o);
368
369 #endif /* DMD_TEMPLATE_H */
Note: See TracBrowser for help on using the browser.