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