1 
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/mtype.h
9  */
10 
11 #pragma once
12 
13 #include "root/dcompat.h" // for d_size_t
14 
15 #include "arraytypes.h"
16 #include "ast_node.h"
17 #include "globals.h"
18 #include "visitor.h"
19 
20 struct Scope;
21 class AggregateDeclaration;
22 class Identifier;
23 class Expression;
24 class StructDeclaration;
25 class ClassDeclaration;
26 class EnumDeclaration;
27 class TypeInfoDeclaration;
28 class Dsymbol;
29 class TemplateInstance;
30 class TemplateDeclaration;
31 
32 class TypeBasic;
33 class Parameter;
34 
35 // Back end
36 #ifdef IN_GCC
37 typedef union tree_node type;
38 #else
39 typedef struct TYPE type;
40 #endif
41 
42 void semanticTypeInfo(Scope *sc, Type *t);
43 
44 Type *typeSemantic(Type *t, const Loc &loc, Scope *sc);
45 Type *merge(Type *type);
46 
47 enum class TY : uint8_t
48 {
49     Tarray,             // slice array, aka T[]
50     Tsarray,            // static array, aka T[dimension]
51     Taarray,            // associative array, aka T[type]
52     Tpointer,
53     Treference,
54     Tfunction,
55     Tident,
56     Tclass,
57     Tstruct,
58     Tenum,
59 
60     Tdelegate,
61     Tnone,
62     Tvoid,
63     Tint8,
64     Tuns8,
65     Tint16,
66     Tuns16,
67     Tint32,
68     Tuns32,
69     Tint64,
70 
71     Tuns64,
72     Tfloat32,
73     Tfloat64,
74     Tfloat80,
75     Timaginary32,
76     Timaginary64,
77     Timaginary80,
78     Tcomplex32,
79     Tcomplex64,
80     Tcomplex80,
81 
82     Tbool,
83     Tchar,
84     Twchar,
85     Tdchar,
86     Terror,
87     Tinstance,
88     Ttypeof,
89     Ttuple,
90     Tslice,
91     Treturn,
92 
93     Tnull,
94     Tvector,
95     Tint128,
96     Tuns128,
97     Ttraits,
98     Tmixin,
99     Tnoreturn,
100     TMAX
101 };
102 
103 #define SIZE_INVALID (~(d_uns64)0)   // error return from size() functions
104 
105 
106 /**
107  * type modifiers
108  * pick this order of numbers so switch statements work better
109  */
110 enum MODFlags
111 {
112     MODconst     = 1, // type is const
113     MODimmutable = 4, // type is immutable
114     MODshared    = 2, // type is shared
115     MODwild      = 8, // type is wild
116     MODwildconst = (MODwild | MODconst), // type is wild const
117     MODmutable   = 0x10       // type is mutable (only used in wildcard matching)
118 };
119 typedef unsigned char MOD;
120 
121 enum class Covariant
122 {
123     distinct = 0,
124     yes = 1,
125     no = 2,
126     fwdref = 3,
127 };
128 
129 enum VarArgValues
130 {
131     VARARGnone     = 0,  /// fixed number of arguments
132     VARARGvariadic = 1,  /// T t, ...)  can be C-style (core.stdc.stdarg) or D-style (core.vararg)
133     VARARGtypesafe = 2   /// T t ...) typesafe https://dlang.org/spec/function.html#typesafe_variadic_functions
134                          ///   or https://dlang.org/spec/function.html#typesafe_variadic_functions
135 };
136 typedef unsigned char VarArg;
137 
138 class Type : public ASTNode
139 {
140 public:
141     TY ty;
142     MOD mod;  // modifiers MODxxxx
143     char *deco;
144 
145 private:
146     void* mcache;
147 
148 public:
149     Type *pto;          // merged pointer to this type
150     Type *rto;          // reference to this type
151     Type *arrayof;      // array of this type
152     TypeInfoDeclaration *vtinfo;        // TypeInfo object for this Type
153 
154     type *ctype;        // for back end
155 
156     static Type *tvoid;
157     static Type *tint8;
158     static Type *tuns8;
159     static Type *tint16;
160     static Type *tuns16;
161     static Type *tint32;
162     static Type *tuns32;
163     static Type *tint64;
164     static Type *tuns64;
165     static Type *tint128;
166     static Type *tuns128;
167     static Type *tfloat32;
168     static Type *tfloat64;
169     static Type *tfloat80;
170 
171     static Type *timaginary32;
172     static Type *timaginary64;
173     static Type *timaginary80;
174 
175     static Type *tcomplex32;
176     static Type *tcomplex64;
177     static Type *tcomplex80;
178 
179     static Type *tbool;
180     static Type *tchar;
181     static Type *twchar;
182     static Type *tdchar;
183 
184     // Some special types
185     static Type *tshiftcnt;
186     static Type *tvoidptr;              // void*
187     static Type *tstring;               // immutable(char)[]
188     static Type *twstring;              // immutable(wchar)[]
189     static Type *tdstring;              // immutable(dchar)[]
190     static Type *terror;                // for error recovery
191     static Type *tnull;                 // for null type
192     static Type *tnoreturn;             // for bottom type typeof(*null)
193 
194     static Type *tsize_t;               // matches size_t alias
195     static Type *tptrdiff_t;            // matches ptrdiff_t alias
196     static Type *thash_t;               // matches hash_t alias
197 
198     static ClassDeclaration *dtypeinfo;
199     static ClassDeclaration *typeinfoclass;
200     static ClassDeclaration *typeinfointerface;
201     static ClassDeclaration *typeinfostruct;
202     static ClassDeclaration *typeinfopointer;
203     static ClassDeclaration *typeinfoarray;
204     static ClassDeclaration *typeinfostaticarray;
205     static ClassDeclaration *typeinfoassociativearray;
206     static ClassDeclaration *typeinfovector;
207     static ClassDeclaration *typeinfoenum;
208     static ClassDeclaration *typeinfofunction;
209     static ClassDeclaration *typeinfodelegate;
210     static ClassDeclaration *typeinfotypelist;
211     static ClassDeclaration *typeinfoconst;
212     static ClassDeclaration *typeinfoinvariant;
213     static ClassDeclaration *typeinfoshared;
214     static ClassDeclaration *typeinfowild;
215 
216     static TemplateDeclaration *rtinfo;
217 
218     static Type *basic[(int)TY::TMAX];
219 
220     virtual const char *kind();
221     Type *copy() const;
222     virtual Type *syntaxCopy();
223     bool equals(const RootObject *o) const;
224     bool equivalent(Type *t);
225     // kludge for template.isType()
dyncast()226     DYNCAST dyncast() const { return DYNCAST_TYPE; }
227     Covariant covariant(Type *t, StorageClass *pstc = NULL);
228     const char *toChars() const;
229     char *toPrettyChars(bool QualifyTypes = false);
230     static void _init();
231 
232     d_uns64 size();
233     virtual d_uns64 size(const Loc &loc);
234     virtual unsigned alignsize();
235     Type *trySemantic(const Loc &loc, Scope *sc);
236     Type *merge2();
237     void modToBuffer(OutBuffer *buf) const;
238     char *modToChars() const;
239 
240     virtual bool isintegral();
241     virtual bool isfloating();   // real, imaginary, or complex
242     virtual bool isreal();
243     virtual bool isimaginary();
244     virtual bool iscomplex();
245     virtual bool isscalar();
246     virtual bool isunsigned();
247     virtual bool isscope();
248     virtual bool isString();
249     virtual bool isAssignable();
250     virtual bool isBoolean();
251     virtual void checkDeprecated(const Loc &loc, Scope *sc);
isConst()252     bool isConst() const       { return (mod & MODconst) != 0; }
isImmutable()253     bool isImmutable() const   { return (mod & MODimmutable) != 0; }
isMutable()254     bool isMutable() const     { return (mod & (MODconst | MODimmutable | MODwild)) == 0; }
isShared()255     bool isShared() const      { return (mod & MODshared) != 0; }
isSharedConst()256     bool isSharedConst() const { return (mod & (MODshared | MODconst)) == (MODshared | MODconst); }
isWild()257     bool isWild() const        { return (mod & MODwild) != 0; }
isWildConst()258     bool isWildConst() const   { return (mod & MODwildconst) == MODwildconst; }
isSharedWild()259     bool isSharedWild() const  { return (mod & (MODshared | MODwild)) == (MODshared | MODwild); }
isNaked()260     bool isNaked() const       { return mod == 0; }
261     Type *nullAttributes() const;
262     Type *constOf();
263     Type *immutableOf();
264     Type *mutableOf();
265     Type *sharedOf();
266     Type *sharedConstOf();
267     Type *unSharedOf();
268     Type *wildOf();
269     Type *wildConstOf();
270     Type *sharedWildOf();
271     Type *sharedWildConstOf();
272     void fixTo(Type *t);
273     void check();
274     Type *addSTC(StorageClass stc);
275     Type *castMod(MOD mod);
276     Type *addMod(MOD mod);
277     virtual Type *addStorageClass(StorageClass stc);
278     Type *pointerTo();
279     Type *referenceTo();
280     Type *arrayOf();
281     Type *sarrayOf(dinteger_t dim);
282     bool hasDeprecatedAliasThis();
283     Type *aliasthisOf();
284     virtual Type *makeConst();
285     virtual Type *makeImmutable();
286     virtual Type *makeShared();
287     virtual Type *makeSharedConst();
288     virtual Type *makeWild();
289     virtual Type *makeWildConst();
290     virtual Type *makeSharedWild();
291     virtual Type *makeSharedWildConst();
292     virtual Type *makeMutable();
293     virtual Dsymbol *toDsymbol(Scope *sc);
294     Type *toBasetype();
295     virtual bool isBaseOf(Type *t, int *poffset);
296     virtual MATCH implicitConvTo(Type *to);
297     virtual MATCH constConv(Type *to);
298     virtual unsigned char deduceWild(Type *t, bool isRef);
299     virtual Type *substWildTo(unsigned mod);
300 
301     Type *unqualify(unsigned m);
302 
303     virtual Type *toHeadMutable();
304     virtual ClassDeclaration *isClassHandle();
305     virtual structalign_t alignment();
306     virtual Expression *defaultInitLiteral(const Loc &loc);
307     virtual bool isZeroInit(const Loc &loc = Loc());                // if initializer is 0
308     Identifier *getTypeInfoIdent();
309     virtual int hasWild() const;
310     virtual bool hasPointers();
311     virtual bool hasVoidInitPointers();
312     virtual bool hasInvariant();
313     virtual Type *nextOf();
314     Type *baseElemOf();
315     uinteger_t sizemask();
316     virtual bool needsDestruction();
317     virtual bool needsCopyOrPostblit();
318     virtual bool needsNested();
319 
320     TypeFunction *toTypeFunction();
321 
322     // For eliminating dynamic_cast
323     virtual TypeBasic *isTypeBasic();
324     TypeFunction *isPtrToFunction();
325     TypeFunction *isFunction_Delegate_PtrToFunction();
326     TypeError *isTypeError();
327     TypeVector *isTypeVector();
328     TypeSArray *isTypeSArray();
329     TypeDArray *isTypeDArray();
330     TypeAArray *isTypeAArray();
331     TypePointer *isTypePointer();
332     TypeReference *isTypeReference();
333     TypeFunction *isTypeFunction();
334     TypeDelegate *isTypeDelegate();
335     TypeIdentifier *isTypeIdentifier();
336     TypeInstance *isTypeInstance();
337     TypeTypeof *isTypeTypeof();
338     TypeReturn *isTypeReturn();
339     TypeStruct *isTypeStruct();
340     TypeEnum *isTypeEnum();
341     TypeClass *isTypeClass();
342     TypeTuple *isTypeTuple();
343     TypeSlice *isTypeSlice();
344     TypeNull *isTypeNull();
345     TypeMixin *isTypeMixin();
346     TypeTraits *isTypeTraits();
347     TypeNoreturn *isTypeNoreturn();
348     TypeTag *isTypeTag();
349 
accept(Visitor * v)350     void accept(Visitor *v) { v->visit(this); }
351 };
352 
353 class TypeError : public Type
354 {
355 public:
356     const char *kind();
357     TypeError *syntaxCopy();
358 
359     d_uns64 size(const Loc &loc);
360     Expression *defaultInitLiteral(const Loc &loc);
accept(Visitor * v)361     void accept(Visitor *v) { v->visit(this); }
362 };
363 
364 class TypeNext : public Type
365 {
366 public:
367     Type *next;
368 
369     void checkDeprecated(const Loc &loc, Scope *sc);
370     int hasWild() const;
371     Type *nextOf();
372     Type *makeConst();
373     Type *makeImmutable();
374     Type *makeShared();
375     Type *makeSharedConst();
376     Type *makeWild();
377     Type *makeWildConst();
378     Type *makeSharedWild();
379     Type *makeSharedWildConst();
380     Type *makeMutable();
381     MATCH constConv(Type *to);
382     unsigned char deduceWild(Type *t, bool isRef);
383     void transitive();
accept(Visitor * v)384     void accept(Visitor *v) { v->visit(this); }
385 };
386 
387 class TypeBasic : public Type
388 {
389 public:
390     const char *dstring;
391     unsigned flags;
392 
393     const char *kind();
394     TypeBasic *syntaxCopy();
395     d_uns64 size(const Loc &loc) /*const*/;
396     unsigned alignsize();
397     bool isintegral();
398     bool isfloating() /*const*/;
399     bool isreal() /*const*/;
400     bool isimaginary() /*const*/;
401     bool iscomplex() /*const*/;
402     bool isscalar() /*const*/;
403     bool isunsigned() /*const*/;
404     MATCH implicitConvTo(Type *to);
405     bool isZeroInit(const Loc &loc) /*const*/;
406 
407     // For eliminating dynamic_cast
408     TypeBasic *isTypeBasic();
accept(Visitor * v)409     void accept(Visitor *v) { v->visit(this); }
410 };
411 
412 class TypeVector : public Type
413 {
414 public:
415     Type *basetype;
416 
417     static TypeVector *create(Type *basetype);
418     const char *kind();
419     TypeVector *syntaxCopy();
420     d_uns64 size(const Loc &loc);
421     unsigned alignsize();
422     bool isintegral();
423     bool isfloating();
424     bool isscalar();
425     bool isunsigned();
426     bool isBoolean() /*const*/;
427     MATCH implicitConvTo(Type *to);
428     Expression *defaultInitLiteral(const Loc &loc);
429     TypeBasic *elementType();
430     bool isZeroInit(const Loc &loc);
431 
accept(Visitor * v)432     void accept(Visitor *v) { v->visit(this); }
433 };
434 
435 class TypeArray : public TypeNext
436 {
437 public:
accept(Visitor * v)438     void accept(Visitor *v) { v->visit(this); }
439 };
440 
441 // Static array, one with a fixed dimension
442 class TypeSArray : public TypeArray
443 {
444 public:
445     Expression *dim;
446 
447     const char *kind();
448     TypeSArray *syntaxCopy();
449     d_uns64 size(const Loc &loc);
450     unsigned alignsize();
451     bool isString();
452     bool isZeroInit(const Loc &loc);
453     structalign_t alignment();
454     MATCH constConv(Type *to);
455     MATCH implicitConvTo(Type *to);
456     Expression *defaultInitLiteral(const Loc &loc);
457     bool hasPointers();
458     bool hasInvariant();
459     bool needsDestruction();
460     bool needsCopyOrPostblit();
461     bool needsNested();
462 
accept(Visitor * v)463     void accept(Visitor *v) { v->visit(this); }
464 };
465 
466 // Dynamic array, no dimension
467 class TypeDArray : public TypeArray
468 {
469 public:
470     const char *kind();
471     TypeDArray *syntaxCopy();
472     d_uns64 size(const Loc &loc) /*const*/;
473     unsigned alignsize() /*const*/;
474     bool isString();
475     bool isZeroInit(const Loc &loc) /*const*/;
476     bool isBoolean() /*const*/;
477     MATCH implicitConvTo(Type *to);
478     bool hasPointers() /*const*/;
479 
accept(Visitor * v)480     void accept(Visitor *v) { v->visit(this); }
481 };
482 
483 class TypeAArray : public TypeArray
484 {
485 public:
486     Type *index;                // key type
487     Loc loc;
488 
489     static TypeAArray *create(Type *t, Type *index);
490     const char *kind();
491     TypeAArray *syntaxCopy();
492     d_uns64 size(const Loc &loc);
493     bool isZeroInit(const Loc &loc) /*const*/;
494     bool isBoolean() /*const*/;
495     bool hasPointers() /*const*/;
496     MATCH implicitConvTo(Type *to);
497     MATCH constConv(Type *to);
498 
accept(Visitor * v)499     void accept(Visitor *v) { v->visit(this); }
500 };
501 
502 class TypePointer : public TypeNext
503 {
504 public:
505     static TypePointer *create(Type *t);
506     const char *kind();
507     TypePointer *syntaxCopy();
508     d_uns64 size(const Loc &loc) /*const*/;
509     MATCH implicitConvTo(Type *to);
510     MATCH constConv(Type *to);
511     bool isscalar() /*const*/;
512     bool isZeroInit(const Loc &loc) /*const*/;
513     bool hasPointers() /*const*/;
514 
accept(Visitor * v)515     void accept(Visitor *v) { v->visit(this); }
516 };
517 
518 class TypeReference : public TypeNext
519 {
520 public:
521     const char *kind();
522     TypeReference *syntaxCopy();
523     d_uns64 size(const Loc &loc) /*const*/;
524     bool isZeroInit(const Loc &loc) /*const*/;
accept(Visitor * v)525     void accept(Visitor *v) { v->visit(this); }
526 };
527 
528 enum RET
529 {
530     RETregs     = 1,    // returned in registers
531     RETstack    = 2     // returned on stack
532 };
533 
534 enum class TRUST : unsigned char
535 {
536     default_ = 0,
537     system = 1,    // @system (same as TRUSTdefault)
538     trusted = 2,   // @trusted
539     safe = 3       // @safe
540 };
541 
542 enum TRUSTformat
543 {
544     TRUSTformatDefault,  // do not emit @system when trust == TRUSTdefault
545     TRUSTformatSystem    // emit @system when trust == TRUSTdefault
546 };
547 
548 enum class PURE : unsigned char
549 {
550     impure = 0,     // not pure at all
551     fwdref = 1,     // it's pure, but not known which level yet
552     weak = 2,       // no mutable globals are read or written
553     const_ = 3,     // parameters are values or const
554     strong = 4      // parameters are values or immutable
555 };
556 
557 class Parameter : public ASTNode
558 {
559 public:
560     StorageClass storageClass;
561     Type *type;
562     Identifier *ident;
563     Expression *defaultArg;
564     UserAttributeDeclaration *userAttribDecl;   // user defined attributes
565 
566     static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident,
567                              Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);
568     Parameter *syntaxCopy();
569     Type *isLazyArray();
570     // kludge for template.isType()
dyncast()571     DYNCAST dyncast() const { return DYNCAST_PARAMETER; }
accept(Visitor * v)572     void accept(Visitor *v) { v->visit(this); }
573 
574     static size_t dim(Parameters *parameters);
575     static Parameter *getNth(Parameters *parameters, d_size_t nth);
576     const char *toChars() const;
577     bool isCovariant(bool returnByRef, const Parameter *p, bool previewIn) const;
578 };
579 
580 struct ParameterList
581 {
582     Parameters* parameters;
583     StorageClass stc;
584     VarArg varargs;
585 
586     size_t length();
587     Parameter *operator[](size_t i) { return Parameter::getNth(parameters, i); }
588 };
589 
590 class TypeFunction : public TypeNext
591 {
592 public:
593     // .next is the return type
594 
595     ParameterList parameterList; // function parameters
596     LINK linkage;                // calling convention
597     unsigned funcFlags;
598     TRUST trust;                 // level of trust
599     PURE purity;                 // PURExxxx
600     char inuse;
601     Expressions *fargs;          // function arguments
602 
603     static TypeFunction *create(Parameters *parameters, Type *treturn, VarArg varargs, LINK linkage, StorageClass stc = 0);
604     const char *kind();
605     TypeFunction *syntaxCopy();
606     void purityLevel();
607     bool hasLazyParameters();
608     bool isDstyleVariadic() const;
609     bool parameterEscapes(Parameter *p);
610     StorageClass parameterStorageClass(Parameter *p);
611     Type *addStorageClass(StorageClass stc);
612 
613     Type *substWildTo(unsigned mod);
614     MATCH constConv(Type *to);
615 
616     bool isnothrow() const;
617     void isnothrow(bool v);
618     bool isnogc() const;
619     void isnogc(bool v);
620     bool isproperty() const;
621     void isproperty(bool v);
622     bool isref() const;
623     void isref(bool v);
624     bool isreturn() const;
625     void isreturn(bool v);
626     bool isScopeQual() const;
627     void isScopeQual(bool v);
628     bool isreturninferred() const;
629     void isreturninferred(bool v);
630     bool isscopeinferred() const;
631     void isscopeinferred(bool v);
632     bool islive() const;
633     void islive(bool v);
634     bool incomplete() const;
635     void incomplete(bool v);
636     bool isInOutParam() const;
637     void isInOutParam(bool v);
638     bool isInOutQual() const;
639     void isInOutQual(bool v);
640     bool iswild() const;
641 
accept(Visitor * v)642     void accept(Visitor *v) { v->visit(this); }
643 };
644 
645 class TypeDelegate : public TypeNext
646 {
647 public:
648     // .next is a TypeFunction
649 
650     static TypeDelegate *create(TypeFunction *t);
651     const char *kind();
652     TypeDelegate *syntaxCopy();
653     Type *addStorageClass(StorageClass stc);
654     d_uns64 size(const Loc &loc) /*const*/;
655     unsigned alignsize() /*const*/;
656     MATCH implicitConvTo(Type *to);
657     bool isZeroInit(const Loc &loc) /*const*/;
658     bool isBoolean() /*const*/;
659     bool hasPointers() /*const*/;
660 
accept(Visitor * v)661     void accept(Visitor *v) { v->visit(this); }
662 };
663 
664 class TypeTraits : public Type
665 {
666     Loc loc;
667     /// The expression to resolve as type or symbol.
668     TraitsExp *exp;
669     /// The symbol when exp doesn't represent a type.
670     Dsymbol *sym;
671 
672     const char *kind();
673     TypeTraits *syntaxCopy();
674     d_uns64 size(const Loc &loc);
675     Dsymbol *toDsymbol(Scope *sc);
accept(Visitor * v)676     void accept(Visitor *v) { v->visit(this); }
677 };
678 
679 class TypeMixin : public Type
680 {
681     Loc loc;
682     Expressions *exps;
683     RootObject *obj;
684 
685     const char *kind();
686     TypeMixin *syntaxCopy();
687     Dsymbol *toDsymbol(Scope *sc);
accept(Visitor * v)688     void accept(Visitor *v) { v->visit(this); }
689 };
690 
691 class TypeQualified : public Type
692 {
693 public:
694     Loc loc;
695     // array of Identifier and TypeInstance,
696     // representing ident.ident!tiargs.ident. ... etc.
697     Objects idents;
698 
699     void syntaxCopyHelper(TypeQualified *t);
700     void addIdent(Identifier *ident);
701     void addInst(TemplateInstance *inst);
702     void addIndex(RootObject *expr);
703     d_uns64 size(const Loc &loc);
704 
accept(Visitor * v)705     void accept(Visitor *v) { v->visit(this); }
706 };
707 
708 class TypeIdentifier : public TypeQualified
709 {
710 public:
711     Identifier *ident;
712     Dsymbol *originalSymbol; // The symbol representing this identifier, before alias resolution
713 
714     const char *kind();
715     TypeIdentifier *syntaxCopy();
716     Dsymbol *toDsymbol(Scope *sc);
accept(Visitor * v)717     void accept(Visitor *v) { v->visit(this); }
718 };
719 
720 /* Similar to TypeIdentifier, but with a TemplateInstance as the root
721  */
722 class TypeInstance : public TypeQualified
723 {
724 public:
725     TemplateInstance *tempinst;
726 
727     const char *kind();
728     TypeInstance *syntaxCopy();
729     Dsymbol *toDsymbol(Scope *sc);
accept(Visitor * v)730     void accept(Visitor *v) { v->visit(this); }
731 };
732 
733 class TypeTypeof : public TypeQualified
734 {
735 public:
736     Expression *exp;
737     int inuse;
738 
739     const char *kind();
740     TypeTypeof *syntaxCopy();
741     Dsymbol *toDsymbol(Scope *sc);
742     d_uns64 size(const Loc &loc);
accept(Visitor * v)743     void accept(Visitor *v) { v->visit(this); }
744 };
745 
746 class TypeReturn : public TypeQualified
747 {
748 public:
749     const char *kind();
750     TypeReturn *syntaxCopy();
751     Dsymbol *toDsymbol(Scope *sc);
accept(Visitor * v)752     void accept(Visitor *v) { v->visit(this); }
753 };
754 
755 // Whether alias this dependency is recursive or not.
756 enum AliasThisRec
757 {
758     RECno = 0,      // no alias this recursion
759     RECyes = 1,     // alias this has recursive dependency
760     RECfwdref = 2,  // not yet known
761     RECtypeMask = 3,// mask to read no/yes/fwdref
762 
763     RECtracing = 0x4, // mark in progress of implicitConvTo/deduceWild
764     RECtracingDT = 0x8  // mark in progress of deduceType
765 };
766 
767 class TypeStruct : public Type
768 {
769 public:
770     StructDeclaration *sym;
771     AliasThisRec att;
772     bool inuse;
773 
774     static TypeStruct *create(StructDeclaration *sym);
775     const char *kind();
776     d_uns64 size(const Loc &loc);
777     unsigned alignsize();
778     TypeStruct *syntaxCopy();
779     Dsymbol *toDsymbol(Scope *sc);
780     structalign_t alignment();
781     Expression *defaultInitLiteral(const Loc &loc);
782     bool isZeroInit(const Loc &loc);
783     bool isAssignable();
784     bool isBoolean() /*const*/;
785     bool needsDestruction() /*const*/;
786     bool needsCopyOrPostblit();
787     bool needsNested();
788     bool hasPointers();
789     bool hasVoidInitPointers();
790     bool hasInvariant();
791     MATCH implicitConvTo(Type *to);
792     MATCH constConv(Type *to);
793     unsigned char deduceWild(Type *t, bool isRef);
794     Type *toHeadMutable();
795 
accept(Visitor * v)796     void accept(Visitor *v) { v->visit(this); }
797 };
798 
799 class TypeEnum : public Type
800 {
801 public:
802     EnumDeclaration *sym;
803 
804     const char *kind();
805     TypeEnum *syntaxCopy();
806     d_uns64 size(const Loc &loc);
807     unsigned alignsize();
808     Type *memType(const Loc &loc = Loc());
809     Dsymbol *toDsymbol(Scope *sc);
810     bool isintegral();
811     bool isfloating();
812     bool isreal();
813     bool isimaginary();
814     bool iscomplex();
815     bool isscalar();
816     bool isunsigned();
817     bool isBoolean();
818     bool isString();
819     bool isAssignable();
820     bool needsDestruction();
821     bool needsCopyOrPostblit();
822     bool needsNested();
823     MATCH implicitConvTo(Type *to);
824     MATCH constConv(Type *to);
825     bool isZeroInit(const Loc &loc);
826     bool hasPointers();
827     bool hasVoidInitPointers();
828     bool hasInvariant();
829     Type *nextOf();
830 
accept(Visitor * v)831     void accept(Visitor *v) { v->visit(this); }
832 };
833 
834 class TypeClass : public Type
835 {
836 public:
837     ClassDeclaration *sym;
838     AliasThisRec att;
839     CPPMANGLE cppmangle;
840 
841     const char *kind();
842     d_uns64 size(const Loc &loc) /*const*/;
843     TypeClass *syntaxCopy();
844     Dsymbol *toDsymbol(Scope *sc);
845     ClassDeclaration *isClassHandle();
846     bool isBaseOf(Type *t, int *poffset);
847     MATCH implicitConvTo(Type *to);
848     MATCH constConv(Type *to);
849     unsigned char deduceWild(Type *t, bool isRef);
850     Type *toHeadMutable();
851     bool isZeroInit(const Loc &loc) /*const*/;
852     bool isscope() /*const*/;
853     bool isBoolean() /*const*/;
854     bool hasPointers() /*const*/;
855 
accept(Visitor * v)856     void accept(Visitor *v) { v->visit(this); }
857 };
858 
859 class TypeTuple : public Type
860 {
861 public:
862     // 'logically immutable' cached global - don't modify (neither pointer nor pointee)!
863     static TypeTuple *empty;
864 
865     Parameters *arguments;      // types making up the tuple
866 
867     static TypeTuple *create(Parameters *arguments);
868     static TypeTuple *create();
869     static TypeTuple *create(Type *t1);
870     static TypeTuple *create(Type *t1, Type *t2);
871     const char *kind();
872     TypeTuple *syntaxCopy();
873     bool equals(const RootObject *o) const;
accept(Visitor * v)874     void accept(Visitor *v) { v->visit(this); }
875 };
876 
877 class TypeSlice : public TypeNext
878 {
879 public:
880     Expression *lwr;
881     Expression *upr;
882 
883     const char *kind();
884     TypeSlice *syntaxCopy();
accept(Visitor * v)885     void accept(Visitor *v) { v->visit(this); }
886 };
887 
888 class TypeNull : public Type
889 {
890 public:
891     const char *kind();
892 
893     TypeNull *syntaxCopy();
894     MATCH implicitConvTo(Type *to);
895     bool isBoolean() /*const*/;
896 
897     d_uns64 size(const Loc &loc) /*const*/;
accept(Visitor * v)898     void accept(Visitor *v) { v->visit(this); }
899 };
900 
901 class TypeNoreturn final : public Type
902 {
903 public:
904     const char *kind();
905     TypeNoreturn *syntaxCopy();
906     MATCH implicitConvTo(Type* to);
907     MATCH constConv(Type* to);
908     bool isBoolean() /* const */;
909     d_uns64 size(const Loc& loc) /* const */;
910     unsigned alignsize();
911 
accept(Visitor * v)912     void accept(Visitor *v) { v->visit(this); }
913 };
914 
915 class TypeTag final : public Type
916 {
917 public:
918     TypeTag *syntaxCopy();
919 
accept(Visitor * v)920     void accept(Visitor *v) { v->visit(this); }
921 };
922 
923 /**************************************************************/
924 
925 bool arrayTypeCompatibleWithoutCasting(Type *t1, Type *t2);
926 
927 // If the type is a class or struct, returns the symbol for it, else null.
928 AggregateDeclaration *isAggregate(Type *t);
929