2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2006 by Digital Mars
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 #ifndef DMD_TEMPLATE_H
12 #define DMD_TEMPLATE_H
19 #include "arraytypes.h"
25 struct TemplateInstance
;
26 struct TemplateParameter
;
27 struct TemplateTypeParameter
;
28 struct TemplateThisParameter
;
29 struct TemplateValueParameter
;
30 struct TemplateAliasParameter
;
31 struct TemplateTupleParameter
;
36 struct AliasDeclaration
;
37 struct FuncDeclaration
;
45 int dyncast() { return DYNCAST_TUPLE
; } // kludge for template.isType()
49 struct TemplateDeclaration
: ScopeDsymbol
51 TemplateParameters
*parameters
; // array of TemplateParameter's
53 TemplateParameters
*origParameters
; // originals for Ddoc
55 Array instances
; // array of TemplateInstance's
57 TemplateDeclaration
*overnext
; // next overloaded TemplateDeclaration
58 TemplateDeclaration
*overroot
; // first in overnext list
61 Dsymbol
*onemember
; // if !=NULL then one member of this template
63 bool dltSource
; // for Delight code, we can do not-null type checks
65 TemplateDeclaration(Loc loc
, Identifier
*id
, TemplateParameters
*parameters
, Array
*decldefs
, bool dltSource
);
66 Dsymbol
*syntaxCopy(Dsymbol
*);
67 void semantic(Scope
*sc
);
68 int overloadInsert(Dsymbol
*s
);
69 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
73 void emitComment(Scope
*sc
);
74 // void toDocBuffer(OutBuffer *buf);
76 MATCH
matchWithInstance(TemplateInstance
*ti
, Objects
*atypes
, int flag
);
77 MATCH
leastAsSpecialized(TemplateDeclaration
*td2
);
79 MATCH
deduceFunctionTemplateMatch(Loc loc
, Objects
*targsi
, Expression
*ethis
, Expressions
*fargs
, Objects
*dedargs
);
80 FuncDeclaration
*deduceFunctionTemplate(Scope
*sc
, Loc loc
, Objects
*targsi
, Expression
*ethis
, Expressions
*fargs
, int flags
= 0);
81 void declareParameter(Scope
*sc
, TemplateParameter
*tp
, Object
*o
);
83 TemplateDeclaration
*isTemplateDeclaration() { return this; }
85 TemplateTupleParameter
*isVariadic();
89 struct TemplateParameter
91 /* For type-parameter:
92 * template Foo(ident) // specType is set to NULL
93 * template Foo(ident : specType)
94 * For value-parameter:
95 * template Foo(valType ident) // specValue is set to NULL
96 * template Foo(valType ident : specValue)
97 * For alias-parameter:
98 * template Foo(alias ident)
100 * template Foo(this ident)
108 TemplateParameter(Loc loc
, Identifier
*ident
);
110 virtual TemplateTypeParameter
*isTemplateTypeParameter();
111 virtual TemplateValueParameter
*isTemplateValueParameter();
112 virtual TemplateAliasParameter
*isTemplateAliasParameter();
113 virtual TemplateThisParameter
*isTemplateThisParameter();
114 virtual TemplateTupleParameter
*isTemplateTupleParameter();
116 virtual TemplateParameter
*syntaxCopy() = 0;
117 virtual void declareParameter(Scope
*sc
) = 0;
118 virtual void semantic(Scope
*) = 0;
119 virtual void print(Object
*oarg
, Object
*oded
) = 0;
120 virtual void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
) = 0;
121 virtual Object
*specialization() = 0;
122 virtual Object
*defaultArg(Loc loc
, Scope
*sc
) = 0;
124 /* If TemplateParameter's match as far as overloading goes.
126 virtual int overloadMatch(TemplateParameter
*) = 0;
128 /* Match actual argument against parameter.
130 virtual MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
, int flags
= 0) = 0;
132 /* Create dummy argument based on parameter.
134 virtual void *dummyArg() = 0;
137 struct TemplateTypeParameter
: TemplateParameter
140 * ident : specType = defaultType
142 Type
*specType
; // type parameter: if !=NULL, this is the type specialization
145 TemplateTypeParameter(Loc loc
, Identifier
*ident
, Type
*specType
, Type
*defaultType
);
147 TemplateTypeParameter
*isTemplateTypeParameter();
148 TemplateParameter
*syntaxCopy();
149 void declareParameter(Scope
*sc
);
150 void semantic(Scope
*);
151 void print(Object
*oarg
, Object
*oded
);
152 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
153 Object
*specialization();
154 Object
*defaultArg(Loc loc
, Scope
*sc
);
155 int overloadMatch(TemplateParameter
*);
156 MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
, int flags
);
161 struct TemplateThisParameter
: TemplateTypeParameter
164 * this ident : specType = defaultType
166 Type
*specType
; // type parameter: if !=NULL, this is the type specialization
169 TemplateThisParameter(Loc loc
, Identifier
*ident
, Type
*specType
, Type
*defaultType
);
171 TemplateThisParameter
*isTemplateThisParameter();
172 TemplateParameter
*syntaxCopy();
173 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
177 struct TemplateValueParameter
: TemplateParameter
180 * valType ident : specValue = defaultValue
184 Expression
*specValue
;
185 Expression
*defaultValue
;
187 static Expression
*edummy
;
189 TemplateValueParameter(Loc loc
, Identifier
*ident
, Type
*valType
, Expression
*specValue
, Expression
*defaultValue
);
191 TemplateValueParameter
*isTemplateValueParameter();
192 TemplateParameter
*syntaxCopy();
193 void declareParameter(Scope
*sc
);
194 void semantic(Scope
*);
195 void print(Object
*oarg
, Object
*oded
);
196 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
197 Object
*specialization();
198 Object
*defaultArg(Loc loc
, Scope
*sc
);
199 int overloadMatch(TemplateParameter
*);
200 MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
, int flags
);
204 struct TemplateAliasParameter
: TemplateParameter
207 * ident : specAlias = defaultAlias
215 static Dsymbol
*sdummy
;
217 TemplateAliasParameter(Loc loc
, Identifier
*ident
, Type
*specAliasT
, Type
*defaultAlias
);
219 TemplateAliasParameter
*isTemplateAliasParameter();
220 TemplateParameter
*syntaxCopy();
221 void declareParameter(Scope
*sc
);
222 void semantic(Scope
*);
223 void print(Object
*oarg
, Object
*oded
);
224 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
225 Object
*specialization();
226 Object
*defaultArg(Loc loc
, Scope
*sc
);
227 int overloadMatch(TemplateParameter
*);
228 MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
, int flags
);
232 struct TemplateTupleParameter
: TemplateParameter
238 TemplateTupleParameter(Loc loc
, Identifier
*ident
);
240 TemplateTupleParameter
*isTemplateTupleParameter();
241 TemplateParameter
*syntaxCopy();
242 void declareParameter(Scope
*sc
);
243 void semantic(Scope
*);
244 void print(Object
*oarg
, Object
*oded
);
245 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
246 Object
*specialization();
247 Object
*defaultArg(Loc loc
, Scope
*sc
);
248 int overloadMatch(TemplateParameter
*);
249 MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
, int flags
);
253 struct TemplateInstance
: ScopeDsymbol
262 Objects
*tiargs
; // Array of Types/Expressions of template
263 // instance arguments [int*, char, 10*10]
265 Objects tdtypes
; // Array of Types/Expressions corresponding
266 // to TemplateDeclaration.parameters
269 TemplateDeclaration
*tempdecl
; // referenced by foo.bar.abc
270 TemplateInstance
*inst
; // refer to existing instance
271 ScopeDsymbol
*argsym
; // argument symbol table
272 AliasDeclaration
*aliasdecl
; // !=NULL if instance is an alias for its
274 WithScopeSymbol
*withsym
; // if a member of a with statement
275 int semanticdone
; // has semantic() been done?
276 int nest
; // for recursion detection
277 int havetempdecl
; // 1 if used second constructor
278 Dsymbol
*isnested
; // if referencing local symbols, this is the context
279 int errors
; // 1 if compiled with errors
281 /* On some targets, it is necessary to know whether a symbol
282 will be emitted in the output or not before the symbol
283 is used. This can be different from getModule(). */
284 Module
* objFileModule
;
287 TemplateInstance(Loc loc
, Identifier
*temp_id
);
288 TemplateInstance(Loc loc
, TemplateDeclaration
*tempdecl
, Objects
*tiargs
);
289 static Objects
*arraySyntaxCopy(Objects
*objs
);
290 Dsymbol
*syntaxCopy(Dsymbol
*);
291 void semantic(Scope
*sc
);
292 void semantic2(Scope
*sc
);
293 void semantic3(Scope
*sc
);
295 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
296 Dsymbol
*toAlias(); // resolve real symbol
298 int oneMember(Dsymbol
**ps
);
302 void toObjFile(int multiobj
); // compile to .obj file
305 static void semanticTiargs(Loc loc
, Scope
*sc
, Objects
*tiargs
, int flags
);
306 void semanticTiargs(Scope
*sc
);
307 TemplateDeclaration
*findTemplateDeclaration(Scope
*sc
);
308 TemplateDeclaration
*findBestMatch(Scope
*sc
);
309 void declareParameters(Scope
*sc
);
310 int isNested(Objects
*tiargs
);
311 Identifier
*genIdent();
313 TemplateInstance
*isTemplateInstance() { return this; }
314 AliasDeclaration
*isAliasDeclaration();
317 struct TemplateMixin
: TemplateInstance
322 Scope
*scope
; // for forward referencing
324 TemplateMixin(Loc loc
, Identifier
*ident
, Type
*tqual
, Array
*idents
, Objects
*tiargs
);
325 Dsymbol
*syntaxCopy(Dsymbol
*s
);
326 void semantic(Scope
*sc
);
327 void semantic2(Scope
*sc
);
328 void semantic3(Scope
*sc
);
331 int oneMember(Dsymbol
**ps
);
334 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
336 void toObjFile(int multiobj
); // compile to .obj file
338 TemplateMixin
*isTemplateMixin() { return this; }
341 Expression
*isExpression(Object
*o
);
342 Dsymbol
*isDsymbol(Object
*o
);
343 Type
*isType(Object
*o
);
344 Tuple
*isTuple(Object
*o
);
345 Type
*getType(Object
*o
);
346 Dsymbol
*getDsymbol(Object
*o
);
348 void ObjectToCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
, Object
*oarg
);
350 #endif /* DMD_TEMPLATE_H */