d: Merge upstream dmd 568496d5b, druntime 178c44ff, phobos 574bf883b.
[official-gcc.git] / gcc / d / dmd / template.h
blob69cc84f6573cf8d7de9118bf2eeb280dacddedd2
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/dlang/dmd/blob/master/src/dmd/template.h
9 */
11 #pragma once
13 #include "arraytypes.h"
14 #include "dsymbol.h"
16 class Identifier;
17 class TemplateInstance;
18 class TemplateParameter;
19 class TemplateTypeParameter;
20 class TemplateThisParameter;
21 class TemplateValueParameter;
22 class TemplateAliasParameter;
23 class TemplateTupleParameter;
24 class Type;
25 class TypeQualified;
26 struct Scope;
27 class Expression;
28 class FuncDeclaration;
29 class Parameter;
31 class Tuple : public RootObject
33 public:
34 Objects objects;
36 // kludge for template.isType()
37 DYNCAST dyncast() const { return DYNCAST_TUPLE; }
39 const char *toChars() const { return objects.toChars(); }
42 struct TemplatePrevious
44 TemplatePrevious *prev;
45 Scope *sc;
46 Objects *dedargs;
49 class TemplateDeclaration : public ScopeDsymbol
51 public:
52 TemplateParameters *parameters; // array of TemplateParameter's
54 TemplateParameters *origParameters; // originals for Ddoc
55 Expression *constraint;
57 // Hash table to look up TemplateInstance's of this TemplateDeclaration
58 void *instances;
60 TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
61 TemplateDeclaration *overroot; // first in overnext list
62 FuncDeclaration *funcroot; // first function in unified overload list
64 Dsymbol *onemember; // if !=NULL then one member of this template
66 bool literal; // this template declaration is a literal
67 bool ismixin; // template declaration is only to be used as a mixin
68 bool isstatic; // this is static template declaration
69 bool isTrivialAliasSeq; // matches `template AliasSeq(T...) { alias AliasSeq = T; }
70 bool isTrivialAlias; // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
71 bool deprecated_; // this template declaration is deprecated
72 Visibility visibility;
73 int inuse; // for recursive expansion detection
75 TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack
77 TemplateDeclaration *syntaxCopy(Dsymbol *);
78 bool overloadInsert(Dsymbol *s);
79 bool hasStaticCtorOrDtor();
80 const char *kind() const;
81 const char *toChars() const;
83 Visibility visible();
85 MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs);
86 RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);
88 TemplateDeclaration *isTemplateDeclaration() { return this; }
90 TemplateTupleParameter *isVariadic();
91 bool isDeprecated() const;
92 bool isOverloadable() const;
94 void accept(Visitor *v) { v->visit(this); }
97 /* For type-parameter:
98 * template Foo(ident) // specType is set to NULL
99 * template Foo(ident : specType)
100 * For value-parameter:
101 * template Foo(valType ident) // specValue is set to NULL
102 * template Foo(valType ident : specValue)
103 * For alias-parameter:
104 * template Foo(alias ident)
105 * For this-parameter:
106 * template Foo(this ident)
108 class TemplateParameter : public ASTNode
110 public:
111 Loc loc;
112 Identifier *ident;
114 /* True if this is a part of precedent parameter specialization pattern.
116 * template A(T : X!TL, alias X, TL...) {}
117 * // X and TL are dependent template parameter
119 * A dependent template parameter should return MATCHexact in matchArg()
120 * to respect the match level of the corresponding precedent parameter.
122 bool dependent;
124 virtual TemplateTypeParameter *isTemplateTypeParameter();
125 virtual TemplateValueParameter *isTemplateValueParameter();
126 virtual TemplateAliasParameter *isTemplateAliasParameter();
127 virtual TemplateThisParameter *isTemplateThisParameter();
128 virtual TemplateTupleParameter *isTemplateTupleParameter();
130 virtual TemplateParameter *syntaxCopy() = 0;
131 virtual bool declareParameter(Scope *sc) = 0;
132 virtual void print(RootObject *oarg, RootObject *oded) = 0;
133 virtual RootObject *specialization() = 0;
134 virtual RootObject *defaultArg(const Loc &instLoc, Scope *sc) = 0;
135 virtual bool hasDefaultArg() = 0;
137 /* Create dummy argument based on parameter.
139 virtual RootObject *dummyArg() = 0;
140 void accept(Visitor *v) { v->visit(this); }
143 /* Syntax:
144 * ident : specType = defaultType
146 class TemplateTypeParameter : public TemplateParameter
148 public:
149 Type *specType; // type parameter: if !=NULL, this is the type specialization
150 Type *defaultType;
152 TemplateTypeParameter *isTemplateTypeParameter();
153 TemplateTypeParameter *syntaxCopy();
154 bool declareParameter(Scope *sc);
155 void print(RootObject *oarg, RootObject *oded);
156 RootObject *specialization();
157 RootObject *defaultArg(const Loc &instLoc, Scope *sc);
158 bool hasDefaultArg();
159 RootObject *dummyArg();
160 void accept(Visitor *v) { v->visit(this); }
163 /* Syntax:
164 * this ident : specType = defaultType
166 class TemplateThisParameter : public TemplateTypeParameter
168 public:
169 TemplateThisParameter *isTemplateThisParameter();
170 TemplateThisParameter *syntaxCopy();
171 void accept(Visitor *v) { v->visit(this); }
174 /* Syntax:
175 * valType ident : specValue = defaultValue
177 class TemplateValueParameter : public TemplateParameter
179 public:
180 Type *valType;
181 Expression *specValue;
182 Expression *defaultValue;
184 TemplateValueParameter *isTemplateValueParameter();
185 TemplateValueParameter *syntaxCopy();
186 bool declareParameter(Scope *sc);
187 void print(RootObject *oarg, RootObject *oded);
188 RootObject *specialization();
189 RootObject *defaultArg(const Loc &instLoc, Scope *sc);
190 bool hasDefaultArg();
191 RootObject *dummyArg();
192 void accept(Visitor *v) { v->visit(this); }
195 /* Syntax:
196 * specType ident : specAlias = defaultAlias
198 class TemplateAliasParameter : public TemplateParameter
200 public:
201 Type *specType;
202 RootObject *specAlias;
203 RootObject *defaultAlias;
205 TemplateAliasParameter *isTemplateAliasParameter();
206 TemplateAliasParameter *syntaxCopy();
207 bool declareParameter(Scope *sc);
208 void print(RootObject *oarg, RootObject *oded);
209 RootObject *specialization();
210 RootObject *defaultArg(const Loc &instLoc, Scope *sc);
211 bool hasDefaultArg();
212 RootObject *dummyArg();
213 void accept(Visitor *v) { v->visit(this); }
216 /* Syntax:
217 * ident ...
219 class TemplateTupleParameter : public TemplateParameter
221 public:
222 TemplateTupleParameter *isTemplateTupleParameter();
223 TemplateTupleParameter *syntaxCopy();
224 bool declareParameter(Scope *sc);
225 void print(RootObject *oarg, RootObject *oded);
226 RootObject *specialization();
227 RootObject *defaultArg(const Loc &instLoc, Scope *sc);
228 bool hasDefaultArg();
229 RootObject *dummyArg();
230 void accept(Visitor *v) { v->visit(this); }
233 /* Given:
234 * foo!(args) =>
235 * name = foo
236 * tiargs = args
238 class TemplateInstance : public ScopeDsymbol
240 public:
241 Identifier *name;
243 // Array of Types/Expressions of template
244 // instance arguments [int*, char, 10*10]
245 Objects *tiargs;
247 // Array of Types/Expressions corresponding
248 // to TemplateDeclaration.parameters
249 // [int, char, 100]
250 Objects tdtypes;
252 // Modules imported by this template instance
253 Modules importedModules;
255 Dsymbol *tempdecl; // referenced by foo.bar.abc
256 Dsymbol *enclosing; // if referencing local symbols, this is the context
257 Dsymbol *aliasdecl; // !=NULL if instance is an alias for its sole member
258 TemplateInstance *inst; // refer to existing instance
259 ScopeDsymbol *argsym; // argument symbol table
260 hash_t hash; // cached result of toHash()
261 Expressions *fargs; // for function template, these are the function arguments
263 TemplateInstances* deferred;
265 Module *memberOf; // if !null, then this TemplateInstance appears in memberOf.members[]
267 // Used to determine the instance needs code generation.
268 // Note that these are inaccurate until semantic analysis phase completed.
269 TemplateInstance *tinst; // enclosing template instance
270 TemplateInstance *tnext; // non-first instantiated instances
271 Module *minst; // the top module that instantiated this instance
273 private:
274 unsigned short _nest; // for recursive pretty printing detection, 3 MSBs reserved for flags
275 public:
276 unsigned char inuse; // for recursive expansion detection
278 TemplateInstance *syntaxCopy(Dsymbol *);
279 Dsymbol *toAlias(); // resolve real symbol
280 const char *kind() const;
281 bool oneMember(Dsymbol **ps, Identifier *ident);
282 const char *toChars() const;
283 const char* toPrettyCharsHelper();
284 Identifier *getIdent();
285 hash_t toHash();
287 bool needsCodegen();
289 TemplateInstance *isTemplateInstance() { return this; }
290 void accept(Visitor *v) { v->visit(this); }
293 class TemplateMixin : public TemplateInstance
295 public:
296 TypeQualified *tqual;
298 TemplateMixin *syntaxCopy(Dsymbol *s);
299 const char *kind() const;
300 bool oneMember(Dsymbol **ps, Identifier *ident);
301 bool hasPointers();
302 void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
303 const char *toChars() const;
305 TemplateMixin *isTemplateMixin() { return this; }
306 void accept(Visitor *v) { v->visit(this); }
309 Expression *isExpression(RootObject *o);
310 Dsymbol *isDsymbol(RootObject *o);
311 Type *isType(RootObject *o);
312 Tuple *isTuple(RootObject *o);
313 Parameter *isParameter(RootObject *o);
314 TemplateParameter *isTemplateParameter(RootObject *o);
315 bool isError(const RootObject *const o);