d: Merge dmd, druntime d8e3976a58, phobos 7a6e95688
[official-gcc.git] / gcc / d / dmd / template.h
blob09c4912a52113ce9f55bc33d0765762f0809d560
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * https://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * https://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 final : public RootObject
33 public:
34 Objects objects;
36 // kludge for template.isType()
37 DYNCAST dyncast() const override { return DYNCAST_TUPLE; }
39 const char *toChars() const override { return objects.toChars(); }
42 struct TemplatePrevious
44 TemplatePrevious *prev;
45 Scope *sc;
46 Objects *dedargs;
49 struct ArgumentList final
51 Expressions* arguments;
52 Identifiers* names;
53 ArgumentList() :
54 arguments(),
55 names()
58 ArgumentList(Expressions* arguments, Identifiers* names = nullptr) :
59 arguments(arguments),
60 names(names)
64 class TemplateDeclaration final : public ScopeDsymbol
66 public:
67 TemplateParameters *parameters; // array of TemplateParameter's
69 TemplateParameters *origParameters; // originals for Ddoc
70 Expression *constraint;
72 // Hash table to look up TemplateInstance's of this TemplateDeclaration
73 void *instances;
75 TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
76 TemplateDeclaration *overroot; // first in overnext list
77 FuncDeclaration *funcroot; // first function in unified overload list
79 Dsymbol *onemember; // if !=NULL then one member of this template
81 d_bool literal; // this template declaration is a literal
82 d_bool ismixin; // template declaration is only to be used as a mixin
83 d_bool isstatic; // this is static template declaration
84 d_bool isTrivialAliasSeq; // matches `template AliasSeq(T...) { alias AliasSeq = T; }
85 d_bool isTrivialAlias; // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
86 d_bool deprecated_; // this template declaration is deprecated
87 Visibility visibility;
89 TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack
91 TemplateDeclaration *syntaxCopy(Dsymbol *) override;
92 bool overloadInsert(Dsymbol *s) override;
93 bool hasStaticCtorOrDtor() override;
94 const char *kind() const override;
95 const char *toChars() const override;
97 Visibility visible() override;
99 TemplateDeclaration *isTemplateDeclaration() override { return this; }
101 bool isDeprecated() const override;
102 bool isOverloadable() const override;
104 void accept(Visitor *v) override { v->visit(this); }
107 /* For type-parameter:
108 * template Foo(ident) // specType is set to NULL
109 * template Foo(ident : specType)
110 * For value-parameter:
111 * template Foo(valType ident) // specValue is set to NULL
112 * template Foo(valType ident : specValue)
113 * For alias-parameter:
114 * template Foo(alias ident)
115 * For this-parameter:
116 * template Foo(this ident)
118 class TemplateParameter : public ASTNode
120 public:
121 Loc loc;
122 Identifier *ident;
124 /* True if this is a part of precedent parameter specialization pattern.
126 * template A(T : X!TL, alias X, TL...) {}
127 * // X and TL are dependent template parameter
129 * A dependent template parameter should return MATCHexact in matchArg()
130 * to respect the match level of the corresponding precedent parameter.
132 d_bool dependent;
134 virtual TemplateTypeParameter *isTemplateTypeParameter();
135 virtual TemplateValueParameter *isTemplateValueParameter();
136 virtual TemplateAliasParameter *isTemplateAliasParameter();
137 virtual TemplateThisParameter *isTemplateThisParameter();
138 virtual TemplateTupleParameter *isTemplateTupleParameter();
140 virtual TemplateParameter *syntaxCopy() = 0;
141 virtual bool declareParameter(Scope *sc) = 0;
142 virtual void print(RootObject *oarg, RootObject *oded) = 0;
143 virtual RootObject *specialization() = 0;
144 virtual RootObject *defaultArg(const Loc &instLoc, Scope *sc) = 0;
145 virtual bool hasDefaultArg() = 0;
147 DYNCAST dyncast() const override { return DYNCAST_TEMPLATEPARAMETER; }
149 /* Create dummy argument based on parameter.
151 virtual RootObject *dummyArg() = 0;
152 void accept(Visitor *v) override { v->visit(this); }
155 /* Syntax:
156 * ident : specType = defaultType
158 class TemplateTypeParameter : public TemplateParameter
160 public:
161 Type *specType; // type parameter: if !=NULL, this is the type specialization
162 Type *defaultType;
164 TemplateTypeParameter *isTemplateTypeParameter() override final;
165 TemplateTypeParameter *syntaxCopy() override;
166 bool declareParameter(Scope *sc) override final;
167 void print(RootObject *oarg, RootObject *oded) override final;
168 RootObject *specialization() override final;
169 RootObject *defaultArg(const Loc &instLoc, Scope *sc) override final;
170 bool hasDefaultArg() override final;
171 RootObject *dummyArg() override final;
172 void accept(Visitor *v) override { v->visit(this); }
175 /* Syntax:
176 * this ident : specType = defaultType
178 class TemplateThisParameter final : public TemplateTypeParameter
180 public:
181 TemplateThisParameter *isTemplateThisParameter() override;
182 TemplateThisParameter *syntaxCopy() override;
183 void accept(Visitor *v) override { v->visit(this); }
186 /* Syntax:
187 * valType ident : specValue = defaultValue
189 class TemplateValueParameter final : public TemplateParameter
191 public:
192 Type *valType;
193 Expression *specValue;
194 Expression *defaultValue;
196 TemplateValueParameter *isTemplateValueParameter() override;
197 TemplateValueParameter *syntaxCopy() override;
198 bool declareParameter(Scope *sc) override;
199 void print(RootObject *oarg, RootObject *oded) override;
200 RootObject *specialization() override;
201 RootObject *defaultArg(const Loc &instLoc, Scope *sc) override;
202 bool hasDefaultArg() override;
203 RootObject *dummyArg() override;
204 void accept(Visitor *v) override { v->visit(this); }
207 /* Syntax:
208 * specType ident : specAlias = defaultAlias
210 class TemplateAliasParameter final : public TemplateParameter
212 public:
213 Type *specType;
214 RootObject *specAlias;
215 RootObject *defaultAlias;
217 TemplateAliasParameter *isTemplateAliasParameter() override;
218 TemplateAliasParameter *syntaxCopy() override;
219 bool declareParameter(Scope *sc) override;
220 void print(RootObject *oarg, RootObject *oded) override;
221 RootObject *specialization() override;
222 RootObject *defaultArg(const Loc &instLoc, Scope *sc) override;
223 bool hasDefaultArg() override;
224 RootObject *dummyArg() override;
225 void accept(Visitor *v) override { v->visit(this); }
228 /* Syntax:
229 * ident ...
231 class TemplateTupleParameter final : public TemplateParameter
233 public:
234 TemplateTupleParameter *isTemplateTupleParameter() override;
235 TemplateTupleParameter *syntaxCopy() override;
236 bool declareParameter(Scope *sc) override;
237 void print(RootObject *oarg, RootObject *oded) override;
238 RootObject *specialization() override;
239 RootObject *defaultArg(const Loc &instLoc, Scope *sc) override;
240 bool hasDefaultArg() override;
241 RootObject *dummyArg() override;
242 void accept(Visitor *v) override { v->visit(this); }
245 /* Given:
246 * foo!(args) =>
247 * name = foo
248 * tiargs = args
250 class TemplateInstance : public ScopeDsymbol
252 public:
253 Identifier *name;
255 // Array of Types/Expressions of template
256 // instance arguments [int*, char, 10*10]
257 Objects *tiargs;
259 // Array of Types/Expressions corresponding
260 // to TemplateDeclaration.parameters
261 // [int, char, 100]
262 Objects tdtypes;
264 // Modules imported by this template instance
265 Modules importedModules;
267 Dsymbol *tempdecl; // referenced by foo.bar.abc
268 Dsymbol *enclosing; // if referencing local symbols, this is the context
269 Dsymbol *aliasdecl; // !=NULL if instance is an alias for its sole member
270 TemplateInstance *inst; // refer to existing instance
271 ScopeDsymbol *argsym; // argument symbol table
272 hash_t hash; // cached result of toHash()
273 Expressions *fargs; // for function template, these are the function arguments
275 TemplateInstances* deferred;
277 Module *memberOf; // if !null, then this TemplateInstance appears in memberOf.members[]
279 // Used to determine the instance needs code generation.
280 // Note that these are inaccurate until semantic analysis phase completed.
281 TemplateInstance *tinst; // enclosing template instance
282 TemplateInstance *tnext; // non-first instantiated instances
283 Module *minst; // the top module that instantiated this instance
285 private:
286 unsigned short _nest; // for recursive pretty printing detection, 3 MSBs reserved for flags
287 public:
288 unsigned char inuse; // for recursive expansion detection
290 TemplateInstance *syntaxCopy(Dsymbol *) override;
291 Dsymbol *toAlias() override final; // resolve real symbol
292 const char *kind() const override;
293 bool oneMember(Dsymbol *&ps, Identifier *ident) override;
294 const char *toChars() const override;
295 const char* toPrettyCharsHelper() override final;
296 Identifier *getIdent() override final;
298 bool isDiscardable();
299 bool needsCodegen();
301 TemplateInstance *isTemplateInstance() override final { return this; }
302 void accept(Visitor *v) override { v->visit(this); }
305 class TemplateMixin final : public TemplateInstance
307 public:
308 TypeQualified *tqual;
310 TemplateMixin *syntaxCopy(Dsymbol *s) override;
311 const char *kind() const override;
312 bool oneMember(Dsymbol *&ps, Identifier *ident) override;
313 bool hasPointers() override;
314 const char *toChars() const override;
316 TemplateMixin *isTemplateMixin() override { return this; }
317 void accept(Visitor *v) override { v->visit(this); }
320 Expression *isExpression(RootObject *o);
321 Dsymbol *isDsymbol(RootObject *o);
322 Type *isType(RootObject *o);
323 Tuple *isTuple(RootObject *o);
324 Parameter *isParameter(RootObject *o);
325 TemplateParameter *isTemplateParameter(RootObject *o);
326 bool isError(const RootObject *const o);
327 void printTemplateStats();