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 int leastAsSpecialized(TemplateDeclaration
*td2
);
79 MATCH
deduceFunctionTemplateMatch(Objects
*targsi
, Expressions
*fargs
, Objects
*dedargs
);
80 FuncDeclaration
*deduceFunctionTemplate(Scope
*sc
, Loc loc
, Objects
*targsi
, Expressions
*fargs
);
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)
106 TemplateParameter(Loc loc
, Identifier
*ident
);
108 virtual TemplateTypeParameter
*isTemplateTypeParameter();
109 virtual TemplateValueParameter
*isTemplateValueParameter();
110 virtual TemplateAliasParameter
*isTemplateAliasParameter();
111 virtual TemplateTupleParameter
*isTemplateTupleParameter();
113 virtual TemplateParameter
*syntaxCopy() = 0;
114 virtual void declareParameter(Scope
*sc
) = 0;
115 virtual void semantic(Scope
*) = 0;
116 virtual void print(Object
*oarg
, Object
*oded
) = 0;
117 virtual void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
) = 0;
118 virtual Object
*specialization() = 0;
119 virtual Object
*defaultArg(Scope
*sc
) = 0;
121 /* If TemplateParameter's match as far as overloading goes.
123 virtual int overloadMatch(TemplateParameter
*) = 0;
125 /* Match actual argument against parameter.
127 virtual MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
) = 0;
129 /* Create dummy argument based on parameter.
131 virtual void *dummyArg() = 0;
134 struct TemplateTypeParameter
: TemplateParameter
137 * ident : specType = defaultType
139 Type
*specType
; // type parameter: if !=NULL, this is the type specialization
142 TemplateTypeParameter(Loc loc
, Identifier
*ident
, Type
*specType
, Type
*defaultType
);
144 TemplateTypeParameter
*isTemplateTypeParameter();
145 TemplateParameter
*syntaxCopy();
146 void declareParameter(Scope
*sc
);
147 void semantic(Scope
*);
148 void print(Object
*oarg
, Object
*oded
);
149 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
150 Object
*specialization();
151 Object
*defaultArg(Scope
*sc
);
152 int overloadMatch(TemplateParameter
*);
153 MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
);
158 struct TemplateThisParameter
: TemplateTypeParameter
161 * this ident : specType = defaultType
163 Type
*specType
; // type parameter: if !=NULL, this is the type specialization
166 TemplateThisParameter(Loc loc
, Identifier
*ident
, Type
*specType
, Type
*defaultType
);
168 TemplateThisParameter
*isTemplateThisParameter();
169 TemplateParameter
*syntaxCopy();
170 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
174 struct TemplateValueParameter
: TemplateParameter
177 * valType ident : specValue = defaultValue
181 Expression
*specValue
;
182 Expression
*defaultValue
;
184 static Expression
*edummy
;
186 TemplateValueParameter(Loc loc
, Identifier
*ident
, Type
*valType
, Expression
*specValue
, Expression
*defaultValue
);
188 TemplateValueParameter
*isTemplateValueParameter();
189 TemplateParameter
*syntaxCopy();
190 void declareParameter(Scope
*sc
);
191 void semantic(Scope
*);
192 void print(Object
*oarg
, Object
*oded
);
193 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
194 Object
*specialization();
195 Object
*defaultArg(Scope
*sc
);
196 int overloadMatch(TemplateParameter
*);
197 MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
);
201 struct TemplateAliasParameter
: TemplateParameter
204 * ident : specAlias = defaultAlias
212 static Dsymbol
*sdummy
;
214 TemplateAliasParameter(Loc loc
, Identifier
*ident
, Type
*specAliasT
, Type
*defaultAlias
);
216 TemplateAliasParameter
*isTemplateAliasParameter();
217 TemplateParameter
*syntaxCopy();
218 void declareParameter(Scope
*sc
);
219 void semantic(Scope
*);
220 void print(Object
*oarg
, Object
*oded
);
221 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
222 Object
*specialization();
223 Object
*defaultArg(Scope
*sc
);
224 int overloadMatch(TemplateParameter
*);
225 MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
);
229 struct TemplateTupleParameter
: TemplateParameter
235 TemplateTupleParameter(Loc loc
, Identifier
*ident
);
237 TemplateTupleParameter
*isTemplateTupleParameter();
238 TemplateParameter
*syntaxCopy();
239 void declareParameter(Scope
*sc
);
240 void semantic(Scope
*);
241 void print(Object
*oarg
, Object
*oded
);
242 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
243 Object
*specialization();
244 Object
*defaultArg(Scope
*sc
);
245 int overloadMatch(TemplateParameter
*);
246 MATCH
matchArg(Scope
*sc
, Objects
*tiargs
, int i
, TemplateParameters
*parameters
, Objects
*dedtypes
, Declaration
**psparam
);
250 struct TemplateInstance
: ScopeDsymbol
259 Objects
*tiargs
; // Array of Types/Expressions of template
260 // instance arguments [int*, char, 10*10]
262 Objects tdtypes
; // Array of Types/Expressions corresponding
263 // to TemplateDeclaration.parameters
266 TemplateDeclaration
*tempdecl
; // referenced by foo.bar.abc
267 TemplateInstance
*inst
; // refer to existing instance
268 ScopeDsymbol
*argsym
; // argument symbol table
269 AliasDeclaration
*aliasdecl
; // !=NULL if instance is an alias for its
271 WithScopeSymbol
*withsym
; // if a member of a with statement
272 int semanticdone
; // has semantic() been done?
273 int nest
; // for recursion detection
274 int havetempdecl
; // 1 if used second constructor
275 Dsymbol
*isnested
; // if referencing local symbols, this is the context
276 int errors
; // 1 if compiled with errors
278 /* On some targets, it is necessary to know whether a symbol
279 will be emitted in the output or not before the symbol
280 is used. This can be different from getModule(). */
281 Module
* objFileModule
;
284 TemplateInstance(Loc loc
, Identifier
*temp_id
);
285 TemplateInstance(Loc loc
, TemplateDeclaration
*tempdecl
, Objects
*tiargs
);
286 static Objects
*arraySyntaxCopy(Objects
*objs
);
287 Dsymbol
*syntaxCopy(Dsymbol
*);
288 void semantic(Scope
*sc
);
289 void semantic2(Scope
*sc
);
290 void semantic3(Scope
*sc
);
292 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
293 Dsymbol
*toAlias(); // resolve real symbol
295 int oneMember(Dsymbol
**ps
);
299 void toObjFile(int multiobj
); // compile to .obj file
302 static void semanticTiargs(Loc loc
, Scope
*sc
, Objects
*tiargs
);
303 void semanticTiargs(Scope
*sc
);
304 TemplateDeclaration
*findTemplateDeclaration(Scope
*sc
);
305 TemplateDeclaration
*findBestMatch(Scope
*sc
);
306 void declareParameters(Scope
*sc
);
307 int isNested(Objects
*tiargs
);
308 Identifier
*genIdent();
310 TemplateInstance
*isTemplateInstance() { return this; }
311 AliasDeclaration
*isAliasDeclaration();
314 struct TemplateMixin
: TemplateInstance
319 Scope
*scope
; // for forward referencing
321 TemplateMixin(Loc loc
, Identifier
*ident
, Type
*tqual
, Array
*idents
, Objects
*tiargs
);
322 Dsymbol
*syntaxCopy(Dsymbol
*s
);
323 void semantic(Scope
*sc
);
324 void semantic2(Scope
*sc
);
325 void semantic3(Scope
*sc
);
328 int oneMember(Dsymbol
**ps
);
331 void toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
);
333 void toObjFile(int multiobj
); // compile to .obj file
335 TemplateMixin
*isTemplateMixin() { return this; }
338 Expression
*isExpression(Object
*o
);
339 Dsymbol
*isDsymbol(Object
*o
);
340 Type
*isType(Object
*o
);
341 Tuple
*isTuple(Object
*o
);
342 Type
*getType(Object
*o
);
343 Dsymbol
*getDsymbol(Object
*o
);
345 void ObjectToCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
, Object
*oarg
);
347 #endif /* DMD_TEMPLATE_H */