1
/**
2
 * Defines a D type.
3
 *
4
 * Copyright:   Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
5
 * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
6
 * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/mtype.d, _mtype.d)
8
 * Documentation:  https://dlang.org/phobos/dmd_mtype.html
9
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/mtype.d
10
 */
11

12
module dmd.mtype;
13

14
import core.checkedint;
15
import core.stdc.stdarg;
16
import core.stdc.stdio;
17
import core.stdc.stdlib;
18
import core.stdc.string;
19

20
import dmd.aggregate;
21
import dmd.arraytypes;
22
import dmd.attrib;
23
import dmd.ast_node;
24
import dmd.gluelayer;
25
import dmd.dclass;
26
import dmd.declaration;
27
import dmd.denum;
28
import dmd.dmangle;
29
import dmd.dscope;
30
import dmd.dstruct;
31
import dmd.dsymbol;
32
import dmd.dsymbolsem;
33
import dmd.dtemplate;
34
import dmd.errors;
35
import dmd.expression;
36
import dmd.expressionsem;
37
import dmd.func;
38
import dmd.globals;
39
import dmd.hdrgen;
40
import dmd.id;
41
import dmd.identifier;
42
import dmd.init;
43
import dmd.opover;
44
import dmd.root.ctfloat;
45
import dmd.root.outbuffer;
46
import dmd.root.rmem;
47
import dmd.root.rootobject;
48
import dmd.root.stringtable;
49
import dmd.target;
50
import dmd.tokens;
51
import dmd.typesem;
52
import dmd.visitor;
53

54
enum LOGDOTEXP = 0;         // log ::dotExp()
55
enum LOGDEFAULTINIT = 0;    // log ::defaultInit()
56

57
enum SIZE_INVALID = (~cast(d_uns64)0);   // error return from size() functions
58

59

60
/***************************
61
 * Return !=0 if modfrom can be implicitly converted to modto
62
 */
63
bool MODimplicitConv(MOD modfrom, MOD modto) pure nothrow @nogc @safe
64
{
65 1
    if (modfrom == modto)
66 1
        return true;
67

68
    //printf("MODimplicitConv(from = %x, to = %x)\n", modfrom, modto);
69
    auto X(T, U)(T m, U n)
70
    {
71 1
        return ((m << 4) | n);
72
    }
73

74 1
    switch (X(modfrom & ~MODFlags.shared_, modto & ~MODFlags.shared_))
75
    {
76 1
    case X(0, MODFlags.const_):
77 1
    case X(MODFlags.wild, MODFlags.const_):
78 1
    case X(MODFlags.wild, MODFlags.wildconst):
79 1
    case X(MODFlags.wildconst, MODFlags.const_):
80 1
        return (modfrom & MODFlags.shared_) == (modto & MODFlags.shared_);
81

82 1
    case X(MODFlags.immutable_, MODFlags.const_):
83 1
    case X(MODFlags.immutable_, MODFlags.wildconst):
84 1
        return true;
85 1
    default:
86 1
        return false;
87
    }
88
}
89

90
/***************************
91
 * Return MATCH.exact or MATCH.constant if a method of type '() modfrom' can call a method of type '() modto'.
92
 */
93
MATCH MODmethodConv(MOD modfrom, MOD modto) pure nothrow @nogc @safe
94
{
95 1
    if (modfrom == modto)
96 1
        return MATCH.exact;
97 1
    if (MODimplicitConv(modfrom, modto))
98 1
        return MATCH.constant;
99

100
    auto X(T, U)(T m, U n)
101
    {
102 1
        return ((m << 4) | n);
103
    }
104

105 1
    switch (X(modfrom, modto))
106
    {
107 1
    case X(0, MODFlags.wild):
108 1
    case X(MODFlags.immutable_, MODFlags.wild):
109 1
    case X(MODFlags.const_, MODFlags.wild):
110 1
    case X(MODFlags.wildconst, MODFlags.wild):
111 1
    case X(MODFlags.shared_, MODFlags.shared_ | MODFlags.wild):
112 1
    case X(MODFlags.shared_ | MODFlags.immutable_, MODFlags.shared_ | MODFlags.wild):
113 1
    case X(MODFlags.shared_ | MODFlags.const_, MODFlags.shared_ | MODFlags.wild):
114 1
    case X(MODFlags.shared_ | MODFlags.wildconst, MODFlags.shared_ | MODFlags.wild):
115 1
        return MATCH.constant;
116

117 1
    default:
118 1
        return MATCH.nomatch;
119
    }
120
}
121

122
/***************************
123
 * Merge mod bits to form common mod.
124
 */
125
MOD MODmerge(MOD mod1, MOD mod2) pure nothrow @nogc @safe
126
{
127 1
    if (mod1 == mod2)
128 1
        return mod1;
129

130
    //printf("MODmerge(1 = %x, 2 = %x)\n", mod1, mod2);
131 1
    MOD result = 0;
132 1
    if ((mod1 | mod2) & MODFlags.shared_)
133
    {
134
        // If either type is shared, the result will be shared
135 1
        result |= MODFlags.shared_;
136 1
        mod1 &= ~MODFlags.shared_;
137 1
        mod2 &= ~MODFlags.shared_;
138
    }
139 1
    if (mod1 == 0 || mod1 == MODFlags.mutable || mod1 == MODFlags.const_ || mod2 == 0 || mod2 == MODFlags.mutable || mod2 == MODFlags.const_)
140
    {
141
        // If either type is mutable or const, the result will be const.
142 1
        result |= MODFlags.const_;
143
    }
144
    else
145
    {
146
        // MODFlags.immutable_ vs MODFlags.wild
147
        // MODFlags.immutable_ vs MODFlags.wildconst
148
        //      MODFlags.wild vs MODFlags.wildconst
149 1
        assert(mod1 & MODFlags.wild || mod2 & MODFlags.wild);
150 1
        result |= MODFlags.wildconst;
151
    }
152 1
    return result;
153
}
154

155
/*********************************
156
 * Store modifier name into buf.
157
 */
158
void MODtoBuffer(OutBuffer* buf, MOD mod) nothrow
159
{
160 1
    buf.writestring(MODtoString(mod));
161
}
162

163
/*********************************
164
 * Returns:
165
 *   a human readable representation of `mod`,
166
 *   which is the token `mod` corresponds to
167
 */
168
const(char)* MODtoChars(MOD mod) nothrow pure
169
{
170
    /// Works because we return a literal
171 1
    return MODtoString(mod).ptr;
172
}
173

174
/// Ditto
175
string MODtoString(MOD mod) nothrow pure
176
{
177 1
    final switch (mod)
178
    {
179 1
    case 0:
180 1
        return "";
181

182 1
    case MODFlags.immutable_:
183 1
        return "immutable";
184

185 1
    case MODFlags.shared_:
186 1
        return "shared";
187

188 1
    case MODFlags.shared_ | MODFlags.const_:
189 1
        return "shared const";
190

191 1
    case MODFlags.const_:
192 1
        return "const";
193

194 1
    case MODFlags.shared_ | MODFlags.wild:
195 1
        return "shared inout";
196

197 1
    case MODFlags.wild:
198 1
        return "inout";
199

200 0
    case MODFlags.shared_ | MODFlags.wildconst:
201 0
        return "shared inout const";
202

203 0
    case MODFlags.wildconst:
204 0
        return "inout const";
205
    }
206
}
207

208

209
/************************************
210
 * Convert MODxxxx to STCxxx
211
 */
212
StorageClass ModToStc(uint mod) pure nothrow @nogc @safe
213
{
214 1
    StorageClass stc = 0;
215 1
    if (mod & MODFlags.immutable_)
216 1
        stc |= STC.immutable_;
217 1
    if (mod & MODFlags.const_)
218 1
        stc |= STC.const_;
219 1
    if (mod & MODFlags.wild)
220 1
        stc |= STC.wild;
221 1
    if (mod & MODFlags.shared_)
222 1
        stc |= STC.shared_;
223 1
    return stc;
224
}
225

226
private enum TFlags
227
{
228
    integral     = 1,
229
    floating     = 2,
230
    unsigned     = 4,
231
    real_        = 8,
232
    imaginary    = 0x10,
233
    complex      = 0x20,
234
}
235

236
enum ENUMTY : int
237
{
238
    Tarray,     // slice array, aka T[]
239
    Tsarray,    // static array, aka T[dimension]
240
    Taarray,    // associative array, aka T[type]
241
    Tpointer,
242
    Treference,
243
    Tfunction,
244
    Tident,
245
    Tclass,
246
    Tstruct,
247
    Tenum,
248

249
    Tdelegate,
250
    Tnone,
251
    Tvoid,
252
    Tint8,
253
    Tuns8,
254
    Tint16,
255
    Tuns16,
256
    Tint32,
257
    Tuns32,
258
    Tint64,
259

260
    Tuns64,
261
    Tfloat32,
262
    Tfloat64,
263
    Tfloat80,
264
    Timaginary32,
265
    Timaginary64,
266
    Timaginary80,
267
    Tcomplex32,
268
    Tcomplex64,
269
    Tcomplex80,
270

271
    Tbool,
272
    Tchar,
273
    Twchar,
274
    Tdchar,
275
    Terror,
276
    Tinstance,
277
    Ttypeof,
278
    Ttuple,
279
    Tslice,
280
    Treturn,
281

282
    Tnull,
283
    Tvector,
284
    Tint128,
285
    Tuns128,
286
    Ttraits,
287
    Tmixin,
288
    TMAX,
289
}
290

291
alias Tarray = ENUMTY.Tarray;
292
alias Tsarray = ENUMTY.Tsarray;
293
alias Taarray = ENUMTY.Taarray;
294
alias Tpointer = ENUMTY.Tpointer;
295
alias Treference = ENUMTY.Treference;
296
alias Tfunction = ENUMTY.Tfunction;
297
alias Tident = ENUMTY.Tident;
298
alias Tclass = ENUMTY.Tclass;
299
alias Tstruct = ENUMTY.Tstruct;
300
alias Tenum = ENUMTY.Tenum;
301
alias Tdelegate = ENUMTY.Tdelegate;
302
alias Tnone = ENUMTY.Tnone;
303
alias Tvoid = ENUMTY.Tvoid;
304
alias Tint8 = ENUMTY.Tint8;
305
alias Tuns8 = ENUMTY.Tuns8;
306
alias Tint16 = ENUMTY.Tint16;
307
alias Tuns16 = ENUMTY.Tuns16;
308
alias Tint32 = ENUMTY.Tint32;
309
alias Tuns32 = ENUMTY.Tuns32;
310
alias Tint64 = ENUMTY.Tint64;
311
alias Tuns64 = ENUMTY.Tuns64;
312
alias Tfloat32 = ENUMTY.Tfloat32;
313
alias Tfloat64 = ENUMTY.Tfloat64;
314
alias Tfloat80 = ENUMTY.Tfloat80;
315
alias Timaginary32 = ENUMTY.Timaginary32;
316
alias Timaginary64 = ENUMTY.Timaginary64;
317
alias Timaginary80 = ENUMTY.Timaginary80;
318
alias Tcomplex32 = ENUMTY.Tcomplex32;
319
alias Tcomplex64 = ENUMTY.Tcomplex64;
320
alias Tcomplex80 = ENUMTY.Tcomplex80;
321
alias Tbool = ENUMTY.Tbool;
322
alias Tchar = ENUMTY.Tchar;
323
alias Twchar = ENUMTY.Twchar;
324
alias Tdchar = ENUMTY.Tdchar;
325
alias Terror = ENUMTY.Terror;
326
alias Tinstance = ENUMTY.Tinstance;
327
alias Ttypeof = ENUMTY.Ttypeof;
328
alias Ttuple = ENUMTY.Ttuple;
329
alias Tslice = ENUMTY.Tslice;
330
alias Treturn = ENUMTY.Treturn;
331
alias Tnull = ENUMTY.Tnull;
332
alias Tvector = ENUMTY.Tvector;
333
alias Tint128 = ENUMTY.Tint128;
334
alias Tuns128 = ENUMTY.Tuns128;
335
alias Ttraits = ENUMTY.Ttraits;
336
alias Tmixin = ENUMTY.Tmixin;
337
alias TMAX = ENUMTY.TMAX;
338

339
alias TY = ubyte;
340

341
///Returns true if ty is char, wchar, or dchar
342
bool isSomeChar(TY ty) pure nothrow @nogc @safe
343
{
344 1
    return ty == Tchar || ty == Twchar || ty == Tdchar;
345
}
346

347
enum MODFlags : int
348
{
349
    const_       = 1,    // type is const
350
    immutable_   = 4,    // type is immutable
351
    shared_      = 2,    // type is shared
352
    wild         = 8,    // type is wild
353
    wildconst    = (MODFlags.wild | MODFlags.const_), // type is wild const
354
    mutable      = 0x10, // type is mutable (only used in wildcard matching)
355
}
356

357
alias MOD = ubyte;
358

359
/****************
360
 * dotExp() bit flags
361
 */
362
enum DotExpFlag
363
{
364
    gag     = 1,    // don't report "not a property" error and just return null
365
    noDeref = 2,    // the use of the expression will not attempt a dereference
366
}
367

368
/***************
369
 * Variadic argument lists
370
 * https://dlang.org/spec/function.html#variadic
371
 */
372
enum VarArg : ubyte
373
{
374
    none     = 0,  /// fixed number of arguments
375
    variadic = 1,  /// (T t, ...)  can be C-style (core.stdc.stdarg) or D-style (core.vararg)
376
    typesafe = 2,  /// (T t ...) typesafe https://dlang.org/spec/function.html#typesafe_variadic_functions
377
                   ///   or https://dlang.org/spec/function.html#typesafe_variadic_functions
378
}
379

380

381
/***********************************************************
382
 */
383
extern (C++) abstract class Type : ASTNode
384
{
385
    TY ty;
386
    MOD mod; // modifiers MODxxxx
387
    char* deco;
388

389
    static struct Mcache
390
    {
391
        /* These are cached values that are lazily evaluated by constOf(), immutableOf(), etc.
392
         * They should not be referenced by anybody but mtype.d.
393
         * They can be null if not lazily evaluated yet.
394
         * Note that there is no "shared immutable", because that is just immutable
395
         * The point of this is to reduce the size of each Type instance as
396
         * we bank on the idea that usually only one of variants exist.
397
         * It will also speed up code because these are rarely referenced and
398
         * so need not be in the cache.
399
         */
400
        Type cto;       // MODFlags.const_
401
        Type ito;       // MODFlags.immutable_
402
        Type sto;       // MODFlags.shared_
403
        Type scto;      // MODFlags.shared_ | MODFlags.const_
404
        Type wto;       // MODFlags.wild
405
        Type wcto;      // MODFlags.wildconst
406
        Type swto;      // MODFlags.shared_ | MODFlags.wild
407
        Type swcto;     // MODFlags.shared_ | MODFlags.wildconst
408
    }
409
    private Mcache* mcache;
410

411
    Type pto;       // merged pointer to this type
412
    Type rto;       // reference to this type
413
    Type arrayof;   // array of this type
414

415
    TypeInfoDeclaration vtinfo;     // TypeInfo object for this Type
416

417
    type* ctype;                    // for back end
418

419
    extern (C++) __gshared Type tvoid;
420
    extern (C++) __gshared Type tint8;
421
    extern (C++) __gshared Type tuns8;
422
    extern (C++) __gshared Type tint16;
423
    extern (C++) __gshared Type tuns16;
424
    extern (C++) __gshared Type tint32;
425
    extern (C++) __gshared Type tuns32;
426
    extern (C++) __gshared Type tint64;
427
    extern (C++) __gshared Type tuns64;
428
    extern (C++) __gshared Type tint128;
429
    extern (C++) __gshared Type tuns128;
430
    extern (C++) __gshared Type tfloat32;
431
    extern (C++) __gshared Type tfloat64;
432
    extern (C++) __gshared Type tfloat80;
433
    extern (C++) __gshared Type timaginary32;
434
    extern (C++) __gshared Type timaginary64;
435
    extern (C++) __gshared Type timaginary80;
436
    extern (C++) __gshared Type tcomplex32;
437
    extern (C++) __gshared Type tcomplex64;
438
    extern (C++) __gshared Type tcomplex80;
439
    extern (C++) __gshared Type tbool;
440
    extern (C++) __gshared Type tchar;
441
    extern (C++) __gshared Type twchar;
442
    extern (C++) __gshared Type tdchar;
443

444
    // Some special types
445
    extern (C++) __gshared Type tshiftcnt;
446
    extern (C++) __gshared Type tvoidptr;    // void*
447
    extern (C++) __gshared Type tstring;     // immutable(char)[]
448
    extern (C++) __gshared Type twstring;    // immutable(wchar)[]
449
    extern (C++) __gshared Type tdstring;    // immutable(dchar)[]
450
    extern (C++) __gshared Type terror;      // for error recovery
451
    extern (C++) __gshared Type tnull;       // for null type
452

453
    extern (C++) __gshared Type tsize_t;     // matches size_t alias
454
    extern (C++) __gshared Type tptrdiff_t;  // matches ptrdiff_t alias
455
    extern (C++) __gshared Type thash_t;     // matches hash_t alias
456

457
    extern (C++) __gshared ClassDeclaration dtypeinfo;
458
    extern (C++) __gshared ClassDeclaration typeinfoclass;
459
    extern (C++) __gshared ClassDeclaration typeinfointerface;
460
    extern (C++) __gshared ClassDeclaration typeinfostruct;
461
    extern (C++) __gshared ClassDeclaration typeinfopointer;
462
    extern (C++) __gshared ClassDeclaration typeinfoarray;
463
    extern (C++) __gshared ClassDeclaration typeinfostaticarray;
464
    extern (C++) __gshared ClassDeclaration typeinfoassociativearray;
465
    extern (C++) __gshared ClassDeclaration typeinfovector;
466
    extern (C++) __gshared ClassDeclaration typeinfoenum;
467
    extern (C++) __gshared ClassDeclaration typeinfofunction;
468
    extern (C++) __gshared ClassDeclaration typeinfodelegate;
469
    extern (C++) __gshared ClassDeclaration typeinfotypelist;
470
    extern (C++) __gshared ClassDeclaration typeinfoconst;
471
    extern (C++) __gshared ClassDeclaration typeinfoinvariant;
472
    extern (C++) __gshared ClassDeclaration typeinfoshared;
473
    extern (C++) __gshared ClassDeclaration typeinfowild;
474

475
    extern (C++) __gshared TemplateDeclaration rtinfo;
476

477
    extern (C++) __gshared Type[TMAX] basic;
478

479
    extern (D) __gshared StringTable!Type stringtable;
480
    extern (D) private __gshared ubyte[TMAX] sizeTy = ()
481
        {
482
            ubyte[TMAX] sizeTy = __traits(classInstanceSize, TypeBasic);
483
            sizeTy[Tsarray] = __traits(classInstanceSize, TypeSArray);
484
            sizeTy[Tarray] = __traits(classInstanceSize, TypeDArray);
485
            sizeTy[Taarray] = __traits(classInstanceSize, TypeAArray);
486
            sizeTy[Tpointer] = __traits(classInstanceSize, TypePointer);
487
            sizeTy[Treference] = __traits(classInstanceSize, TypeReference);
488
            sizeTy[Tfunction] = __traits(classInstanceSize, TypeFunction);
489
            sizeTy[Tdelegate] = __traits(classInstanceSize, TypeDelegate);
490
            sizeTy[Tident] = __traits(classInstanceSize, TypeIdentifier);
491
            sizeTy[Tinstance] = __traits(classInstanceSize, TypeInstance);
492
            sizeTy[Ttypeof] = __traits(classInstanceSize, TypeTypeof);
493
            sizeTy[Tenum] = __traits(classInstanceSize, TypeEnum);
494
            sizeTy[Tstruct] = __traits(classInstanceSize, TypeStruct);
495
            sizeTy[Tclass] = __traits(classInstanceSize, TypeClass);
496
            sizeTy[Ttuple] = __traits(classInstanceSize, TypeTuple);
497
            sizeTy[Tslice] = __traits(classInstanceSize, TypeSlice);
498
            sizeTy[Treturn] = __traits(classInstanceSize, TypeReturn);
499
            sizeTy[Terror] = __traits(classInstanceSize, TypeError);
500
            sizeTy[Tnull] = __traits(classInstanceSize, TypeNull);
501
            sizeTy[Tvector] = __traits(classInstanceSize, TypeVector);
502
            sizeTy[Ttraits] = __traits(classInstanceSize, TypeTraits);
503
            sizeTy[Tmixin] = __traits(classInstanceSize, TypeMixin);
504
            return sizeTy;
505
        }();
506

507 1
    final extern (D) this(TY ty)
508
    {
509 1
        this.ty = ty;
510
    }
511

512
    const(char)* kind() const nothrow pure @nogc @safe
513
    {
514 0
        assert(false); // should be overridden
515
    }
516

517
    final Type copy() nothrow const
518
    {
519 1
        Type t = cast(Type)mem.xmalloc(sizeTy[ty]);
520 1
        memcpy(cast(void*)t, cast(void*)this, sizeTy[ty]);
521 1
        return t;
522
    }
523

524
    Type syntaxCopy()
525
    {
526 0
        fprintf(stderr, "this = %s, ty = %d\n", toChars(), ty);
527 0
        assert(0);
528
    }
529

530
    override bool equals(const RootObject o) const
531
    {
532 1
        Type t = cast(Type)o;
533
        //printf("Type::equals(%s, %s)\n", toChars(), t.toChars());
534
        // deco strings are unique
535
        // and semantic() has been run
536 1
        if (this == o || ((t && deco == t.deco) && deco !is null))
537
        {
538
            //printf("deco = '%s', t.deco = '%s'\n", deco, t.deco);
539 1
            return true;
540
        }
541
        //if (deco && t && t.deco) printf("deco = '%s', t.deco = '%s'\n", deco, t.deco);
542 1
        return false;
543
    }
544

545
    final bool equivalent(Type t)
546
    {
547 1
        return immutableOf().equals(t.immutableOf());
548
    }
549

550
    // kludge for template.isType()
551
    override final DYNCAST dyncast() const
552
    {
553 1
        return DYNCAST.type;
554
    }
555

556
    extern (D)
557
    final Mcache* getMcache()
558
    {
559 1
        if (!mcache)
560 1
            mcache = cast(Mcache*) mem.xcalloc(Mcache.sizeof, 1);
561 1
        return mcache;
562
    }
563

564
    /*******************************
565
     * Covariant means that 'this' can substitute for 't',
566
     * i.e. a pure function is a match for an impure type.
567
     * Params:
568
     *      t = type 'this' is covariant with
569
     *      pstc = if not null, store STCxxxx which would make it covariant
570
     * Returns:
571
     *      0       types are distinct
572
     *      1       this is covariant with t
573
     *      2       arguments match as far as overloading goes,
574
     *              but types are not covariant
575
     *      3       cannot determine covariance because of forward references
576
     *      *pstc   STCxxxx which would make it covariant
577
     */
578
    final int covariant(Type t, StorageClass* pstc = null)
579
    {
580
        version (none)
581
        {
582
            printf("Type::covariant(t = %s) %s\n", t.toChars(), toChars());
583
            printf("deco = %p, %p\n", deco, t.deco);
584
            //    printf("ty = %d\n", next.ty);
585
            printf("mod = %x, %x\n", mod, t.mod);
586
        }
587 1
        if (pstc)
588 1
            *pstc = 0;
589 1
        StorageClass stc = 0;
590

591 1
        bool notcovariant = false;
592

593 1
        if (equals(t))
594 1
            return 1; // covariant
595

596 1
        TypeFunction t1 = this.isTypeFunction();
597 1
        TypeFunction t2 = t.isTypeFunction();
598

599 1
        if (!t1 || !t2)
600 0
            goto Ldistinct;
601

602 1
        if (t1.parameterList.varargs != t2.parameterList.varargs)
603 1
            goto Ldistinct;
604

605 1
        if (t1.parameterList.parameters && t2.parameterList.parameters)
606
        {
607 1
            if (t1.parameterList.length != t2.parameterList.length)
608 1
                goto Ldistinct;
609

610 1
            foreach (i, fparam1; t1.parameterList)
611
            {
612 1
                Parameter fparam2 = t2.parameterList[i];
613

614 1
                if (!fparam1.type.equals(fparam2.type))
615
                {
616 1
                    Type tp1 = fparam1.type;
617 1
                    Type tp2 = fparam2.type;
618 1
                    if (tp1.ty == tp2.ty)
619
                    {
620 1
                        if (auto tc1 = tp1.isTypeClass())
621
                        {
622 1
                            if (tc1.sym == (cast(TypeClass)tp2).sym && MODimplicitConv(tp2.mod, tp1.mod))
623 1
                                goto Lcov;
624
                        }
625 1
                        else if (auto ts1 = tp1.isTypeStruct())
626
                        {
627 1
                            if (ts1.sym == (cast(TypeStruct)tp2).sym && MODimplicitConv(tp2.mod, tp1.mod))
628 1
                                goto Lcov;
629
                        }
630 1
                        else if (tp1.ty == Tpointer)
631
                        {
632 1
                            if (tp2.implicitConvTo(tp1))
633 1
                                goto Lcov;
634
                        }
635 1
                        else if (tp1.ty == Tarray)
636
                        {
637 1
                            if (tp2.implicitConvTo(tp1))
638 1
                                goto Lcov;
639
                        }
640 1
                        else if (tp1.ty == Tdelegate)
641
                        {
642 1
                            if (tp1.implicitConvTo(tp2))
643 1
                                goto Lcov;
644
                        }
645
                    }
646 1
                    goto Ldistinct;
647
                }
648
            Lcov:
649 1
                notcovariant |= !fparam1.isCovariant(t1.isref, fparam2);
650
            }
651
        }
652 1
        else if (t1.parameterList.parameters != t2.parameterList.parameters)
653
        {
654 1
            if (t1.parameterList.length || t2.parameterList.length)
655 0
                goto Ldistinct;
656
        }
657

658
        // The argument lists match
659 1
        if (notcovariant)
660 1
            goto Lnotcovariant;
661 1
        if (t1.linkage != t2.linkage)
662 1
            goto Lnotcovariant;
663

664
        {
665
            // Return types
666 1
            Type t1n = t1.next;
667 1
            Type t2n = t2.next;
668

669 1
            if (!t1n || !t2n) // happens with return type inference
670 1
                goto Lnotcovariant;
671

672 1
            if (t1n.equals(t2n))
673 1
                goto Lcovariant;
674 1
            if (t1n.ty == Tclass && t2n.ty == Tclass)
675
            {
676
                /* If same class type, but t2n is const, then it's
677
                 * covariant. Do this test first because it can work on
678
                 * forward references.
679
                 */
680 1
                if ((cast(TypeClass)t1n).sym == (cast(TypeClass)t2n).sym && MODimplicitConv(t1n.mod, t2n.mod))
681 1
                    goto Lcovariant;
682

683
                // If t1n is forward referenced:
684 1
                ClassDeclaration cd = (cast(TypeClass)t1n).sym;
685 1
                if (cd.semanticRun < PASS.semanticdone && !cd.isBaseInfoComplete())
686 1
                    cd.dsymbolSemantic(null);
687 1
                if (!cd.isBaseInfoComplete())
688
                {
689 0
                    return 3; // forward references
690
                }
691
            }
692 1
            if (t1n.ty == Tstruct && t2n.ty == Tstruct)
693
            {
694 1
                if ((cast(TypeStruct)t1n).sym == (cast(TypeStruct)t2n).sym && MODimplicitConv(t1n.mod, t2n.mod))
695 0
                    goto Lcovariant;
696
            }
697 1
            else if (t1n.ty == t2n.ty && t1n.implicitConvTo(t2n))
698 1
                goto Lcovariant;
699 1
            else if (t1n.ty == Tnull)
700
            {
701
                // NULL is covariant with any pointer type, but not with any
702
                // dynamic arrays, associative arrays or delegates.
703
                // https://issues.dlang.org/show_bug.cgi?id=8589
704
                // https://issues.dlang.org/show_bug.cgi?id=19618
705 1
                Type t2bn = t2n.toBasetype();
706 1
                if (t2bn.ty == Tnull || t2bn.ty == Tpointer || t2bn.ty == Tclass)
707 1
                    goto Lcovariant;
708
            }
709
        }
710 1
        goto Lnotcovariant;
711

712
    Lcovariant:
713 1
        if (t1.isref != t2.isref)
714 1
            goto Lnotcovariant;
715

716 1
        if (!t1.isref && (t1.isScopeQual || t2.isScopeQual))
717
        {
718 1
            StorageClass stc1 = t1.isScopeQual ? STC.scope_ : 0;
719 1
            StorageClass stc2 = t2.isScopeQual ? STC.scope_ : 0;
720 1
            if (t1.isreturn)
721
            {
722 1
                stc1 |= STC.return_;
723 1
                if (!t1.isScopeQual)
724 0
                    stc1 |= STC.ref_;
725
            }
726 1
            if (t2.isreturn)
727
            {
728 1
                stc2 |= STC.return_;
729 1
                if (!t2.isScopeQual)
730 0
                    stc2 |= STC.ref_;
731
            }
732 1
            if (!Parameter.isCovariantScope(t1.isref, stc1, stc2))
733 1
                goto Lnotcovariant;
734
        }
735

736
        // We can subtract 'return ref' from 'this', but cannot add it
737 1
        else if (t1.isreturn && !t2.isreturn)
738 1
            goto Lnotcovariant;
739

740
        /* Can convert mutable to const
741
         */
742 1
        if (!MODimplicitConv(t2.mod, t1.mod))
743
        {
744
            version (none)
745
            {
746
                //stop attribute inference with const
747
                // If adding 'const' will make it covariant
748
                if (MODimplicitConv(t2.mod, MODmerge(t1.mod, MODFlags.const_)))
749
                    stc |= STC.const_;
750
                else
751
                    goto Lnotcovariant;
752
            }
753
            else
754
            {
755 1
                goto Ldistinct;
756
            }
757
        }
758

759
        /* Can convert pure to impure, nothrow to throw, and nogc to gc
760
         */
761 1
        if (!t1.purity && t2.purity)
762 1
            stc |= STC.pure_;
763

764 1
        if (!t1.isnothrow && t2.isnothrow)
765 1
            stc |= STC.nothrow_;
766

767 1
        if (!t1.isnogc && t2.isnogc)
768 1
            stc |= STC.nogc;
769

770
        /* Can convert safe/trusted to system
771
         */
772 1
        if (t1.trust <= TRUST.system && t2.trust >= TRUST.trusted)
773
        {
774
            // Should we infer trusted or safe? Go with safe.
775 1
            stc |= STC.safe;
776
        }
777

778 1
        if (stc)
779
        {
780 1
            if (pstc)
781 1
                *pstc = stc;
782 1
            goto Lnotcovariant;
783
        }
784

785
        //printf("\tcovaraint: 1\n");
786 1
        return 1;
787

788
    Ldistinct:
789
        //printf("\tcovaraint: 0\n");
790 1
        return 0;
791

792
    Lnotcovariant:
793
        //printf("\tcovaraint: 2\n");
794 1
        return 2;
795
    }
796

797
    /********************************
798
     * For pretty-printing a type.
799
     */
800
    final override const(char)* toChars() const
801
    {
802 1
        OutBuffer buf;
803 1
        buf.reserve(16);
804 1
        HdrGenState hgs;
805 1
        hgs.fullQual = (ty == Tclass && !mod);
806

807 1
        .toCBuffer(this, &buf, null, &hgs);
808 1
        return buf.extractChars();
809
    }
810

811
    /// ditto
812
    final char* toPrettyChars(bool QualifyTypes = false)
813
    {
814 1
        OutBuffer buf;
815 1
        buf.reserve(16);
816 1
        HdrGenState hgs;
817 1
        hgs.fullQual = QualifyTypes;
818

819 1
        .toCBuffer(this, &buf, null, &hgs);
820 1
        return buf.extractChars();
821
    }
822

823
    static void _init()
824
    {
825 1
        stringtable._init(14_000);
826

827
        // Set basic types
828 1
        __gshared TY* basetab =
829
        [
830
            Tvoid,
831
            Tint8,
832
            Tuns8,
833
            Tint16,
834
            Tuns16,
835
            Tint32,
836
            Tuns32,
837
            Tint64,
838
            Tuns64,
839
            Tint128,
840
            Tuns128,
841
            Tfloat32,
842
            Tfloat64,
843
            Tfloat80,
844
            Timaginary32,
845
            Timaginary64,
846
            Timaginary80,
847
            Tcomplex32,
848
            Tcomplex64,
849
            Tcomplex80,
850
            Tbool,
851
            Tchar,
852
            Twchar,
853
            Tdchar,
854
            Terror
855
        ];
856

857 1
        for (size_t i = 0; basetab[i] != Terror; i++)
858
        {
859 1
            Type t = new TypeBasic(basetab[i]);
860 1
            t = t.merge();
861 1
            basic[basetab[i]] = t;
862
        }
863 1
        basic[Terror] = new TypeError();
864

865 1
        tvoid = basic[Tvoid];
866 1
        tint8 = basic[Tint8];
867 1
        tuns8 = basic[Tuns8];
868 1
        tint16 = basic[Tint16];
869 1
        tuns16 = basic[Tuns16];
870 1
        tint32 = basic[Tint32];
871 1
        tuns32 = basic[Tuns32];
872 1
        tint64 = basic[Tint64];
873 1
        tuns64 = basic[Tuns64];
874 1
        tint128 = basic[Tint128];
875 1
        tuns128 = basic[Tuns128];
876 1
        tfloat32 = basic[Tfloat32];
877 1
        tfloat64 = basic[Tfloat64];
878 1
        tfloat80 = basic[Tfloat80];
879

880 1
        timaginary32 = basic[Timaginary32];
881 1
        timaginary64 = basic[Timaginary64];
882 1
        timaginary80 = basic[Timaginary80];
883

884 1
        tcomplex32 = basic[Tcomplex32];
885 1
        tcomplex64 = basic[Tcomplex64];
886 1
        tcomplex80 = basic[Tcomplex80];
887

888 1
        tbool = basic[Tbool];
889 1
        tchar = basic[Tchar];
890 1
        twchar = basic[Twchar];
891 1
        tdchar = basic[Tdchar];
892

893 1
        tshiftcnt = tint32;
894 1
        terror = basic[Terror];
895 1
        tnull = basic[Tnull];
896 1
        tnull = new TypeNull();
897 1
        tnull.deco = tnull.merge().deco;
898

899 1
        tvoidptr = tvoid.pointerTo();
900 1
        tstring = tchar.immutableOf().arrayOf();
901 1
        twstring = twchar.immutableOf().arrayOf();
902 1
        tdstring = tdchar.immutableOf().arrayOf();
903

904 1
        const isLP64 = global.params.isLP64;
905

906 1
        tsize_t    = basic[isLP64 ? Tuns64 : Tuns32];
907 1
        tptrdiff_t = basic[isLP64 ? Tint64 : Tint32];
908 1
        thash_t = tsize_t;
909
    }
910

911
    /**
912
     * Deinitializes the global state of the compiler.
913
     *
914
     * This can be used to restore the state set by `_init` to its original
915
     * state.
916
     */
917
    static void deinitialize()
918
    {
919 0
        stringtable = stringtable.init;
920
    }
921

922
    final d_uns64 size()
923
    {
924 1
        return size(Loc.initial);
925
    }
926

927
    d_uns64 size(const ref Loc loc)
928
    {
929 1
        error(loc, "no size for type `%s`", toChars());
930 1
        return SIZE_INVALID;
931
    }
932

933
    uint alignsize()
934
    {
935 1
        return cast(uint)size(Loc.initial);
936
    }
937

938
    final Type trySemantic(const ref Loc loc, Scope* sc)
939
    {
940
        //printf("+trySemantic(%s) %d\n", toChars(), global.errors);
941

942
        // Needed to display any deprecations that were gagged
943 1
        auto tcopy = this.syntaxCopy();
944

945 1
        const errors = global.startGagging();
946 1
        Type t = typeSemantic(this, loc, sc);
947 1
        if (global.endGagging(errors) || t.ty == Terror) // if any errors happened
948
        {
949 1
            t = null;
950
        }
951
        else
952
        {
953
            // If `typeSemantic` succeeded, there may have been deprecations that
954
            // were gagged due the the `startGagging` above.  Run again to display
955
            // those deprecations.  https://issues.dlang.org/show_bug.cgi?id=19107
956 1
            if (global.gaggedWarnings > 0)
957 1
                typeSemantic(tcopy, loc, sc);
958
        }
959
        //printf("-trySemantic(%s) %d\n", toChars(), global.errors);
960 1
        return t;
961
    }
962

963
    /*************************************
964
     * This version does a merge even if the deco is already computed.
965
     * Necessary for types that have a deco, but are not merged.
966
     */
967
    final Type merge2()
968
    {
969
        //printf("merge2(%s)\n", toChars());
970 1
        Type t = this;
971 1
        assert(t);
972 1
        if (!t.deco)
973 1
            return t.merge();
974

975 1
        auto sv = stringtable.lookup(t.deco, strlen(t.deco));
976 1
        if (sv && sv.value)
977
        {
978 1
            t = sv.value;
979 1
            assert(t.deco);
980
        }
981
        else
982 0
            assert(0);
983 1
        return t;
984
    }
985

986
    /*********************************
987
     * Store this type's modifier name into buf.
988
     */
989
    final void modToBuffer(OutBuffer* buf) nothrow const
990
    {
991 1
        if (mod)
992
        {
993 1
            buf.writeByte(' ');
994 1
            MODtoBuffer(buf, mod);
995
        }
996
    }
997

998
    /*********************************
999
     * Return this type's modifier name.
1000
     */
1001
    final char* modToChars() nothrow const
1002
    {
1003 1
        OutBuffer buf;
1004 1
        buf.reserve(16);
1005 1
        modToBuffer(&buf);
1006 1
        return buf.extractChars();
1007
    }
1008

1009
    bool isintegral()
1010
    {
1011 1
        return false;
1012
    }
1013

1014
    // real, imaginary, or complex
1015
    bool isfloating()
1016
    {
1017 1
        return false;
1018
    }
1019

1020
    bool isreal()
1021
    {
1022 1
        return false;
1023
    }
1024

1025
    bool isimaginary()
1026
    {
1027 1
        return false;
1028
    }
1029

1030
    bool iscomplex()
1031
    {
1032 1
        return false;
1033
    }
1034

1035
    bool isscalar()
1036
    {
1037 1
        return false;
1038
    }
1039

1040
    bool isunsigned()
1041
    {
1042 1
        return false;
1043
    }
1044

1045
    bool isscope()
1046
    {
1047 1
        return false;
1048
    }
1049

1050
    bool isString()
1051
    {
1052 1
        return false;
1053
    }
1054

1055
    /**************************
1056
     * When T is mutable,
1057
     * Given:
1058
     *      T a, b;
1059
     * Can we bitwise assign:
1060
     *      a = b;
1061
     * ?
1062
     */
1063
    bool isAssignable()
1064
    {
1065 1
        return true;
1066
    }
1067

1068
    /**************************
1069
     * Returns true if T can be converted to boolean value.
1070
     */
1071
    bool isBoolean()
1072
    {
1073 1
        return isscalar();
1074
    }
1075

1076
    /*********************************
1077
     * Check type to see if it is based on a deprecated symbol.
1078
     */
1079
    void checkDeprecated(const ref Loc loc, Scope* sc)
1080
    {
1081 1
        if (Dsymbol s = toDsymbol(sc))
1082
        {
1083 1
            s.checkDeprecated(loc, sc);
1084
        }
1085
    }
1086

1087
    final bool isConst() const nothrow pure @nogc @safe
1088
    {
1089 1
        return (mod & MODFlags.const_) != 0;
1090
    }
1091

1092
    final bool isImmutable() const nothrow pure @nogc @safe
1093
    {
1094 1
        return (mod & MODFlags.immutable_) != 0;
1095
    }
1096

1097
    final bool isMutable() const nothrow pure @nogc @safe
1098
    {
1099 1
        return (mod & (MODFlags.const_ | MODFlags.immutable_ | MODFlags.wild)) == 0;
1100
    }
1101

1102
    final bool isShared() const nothrow pure @nogc @safe
1103
    {
1104 1
        return (mod & MODFlags.shared_) != 0;
1105
    }
1106

1107
    final bool isSharedConst() const nothrow pure @nogc @safe
1108
    {
1109 0
        return (mod & (MODFlags.shared_ | MODFlags.const_)) == (MODFlags.shared_ | MODFlags.const_);
1110
    }
1111

1112
    final bool isWild() const nothrow pure @nogc @safe
1113
    {
1114 1
        return (mod & MODFlags.wild) != 0;
1115
    }
1116

1117
    final bool isWildConst() const nothrow pure @nogc @safe
1118
    {
1119 1
        return (mod & MODFlags.wildconst) == MODFlags.wildconst;
1120
    }
1121

1122
    final bool isSharedWild() const nothrow pure @nogc @safe
1123
    {
1124 0
        return (mod & (MODFlags.shared_ | MODFlags.wild)) == (MODFlags.shared_ | MODFlags.wild);
1125
    }
1126

1127
    final bool isNaked() const nothrow pure @nogc @safe
1128
    {
1129 1
        return mod == 0;
1130
    }
1131

1132
    /********************************
1133
     * Return a copy of this type with all attributes null-initialized.
1134
     * Useful for creating a type with different modifiers.
1135
     */
1136
    final Type nullAttributes() nothrow const
1137
    {
1138 1
        uint sz = sizeTy[ty];
1139 1
        Type t = cast(Type)mem.xmalloc(sz);
1140 1
        memcpy(cast(void*)t, cast(void*)this, sz);
1141
        // t.mod = NULL;  // leave mod unchanged
1142 1
        t.deco = null;
1143 1
        t.arrayof = null;
1144 1
        t.pto = null;
1145 1
        t.rto = null;
1146 1
        t.vtinfo = null;
1147 1
        t.ctype = null;
1148 1
        t.mcache = null;
1149 1
        if (t.ty == Tstruct)
1150 1
            (cast(TypeStruct)t).att = AliasThisRec.fwdref;
1151 1
        if (t.ty == Tclass)
1152 1
            (cast(TypeClass)t).att = AliasThisRec.fwdref;
1153 1
        return t;
1154
    }
1155

1156
    /********************************
1157
     * Convert to 'const'.
1158
     */
1159
    final Type constOf()
1160
    {
1161
        //printf("Type::constOf() %p %s\n", this, toChars());
1162 1
        if (mod == MODFlags.const_)
1163 1
            return this;
1164 1
        if (mcache && mcache.cto)
1165
        {
1166 1
            assert(mcache.cto.mod == MODFlags.const_);
1167 1
            return mcache.cto;
1168
        }
1169 1
        Type t = makeConst();
1170 1
        t = t.merge();
1171 1
        t.fixTo(this);
1172
        //printf("-Type::constOf() %p %s\n", t, t.toChars());
1173 1
        return t;
1174
    }
1175

1176
    /********************************
1177
     * Convert to 'immutable'.
1178
     */
1179
    final Type immutableOf()
1180
    {
1181
        //printf("Type::immutableOf() %p %s\n", this, toChars());
1182 1
        if (isImmutable())
1183 1
            return this;
1184 1
        if (mcache && mcache.ito)
1185
        {
1186 1
            assert(mcache.ito.isImmutable());
1187 1
            return mcache.ito;
1188
        }
1189 1
        Type t = makeImmutable();
1190 1
        t = t.merge();
1191 1
        t.fixTo(this);
1192
        //printf("\t%p\n", t);
1193 1
        return t;
1194
    }
1195

1196
    /********************************
1197
     * Make type mutable.
1198
     */
1199
    final Type mutableOf()
1200
    {
1201
        //printf("Type::mutableOf() %p, %s\n", this, toChars());
1202 1
        Type t = this;
1203 1
        if (isImmutable())
1204
        {
1205 1
            getMcache();
1206 1
            t = mcache.ito; // immutable => naked
1207 1
            assert(!t || (t.isMutable() && !t.isShared()));
1208
        }
1209 1
        else if (isConst())
1210
        {
1211 1
            getMcache();
1212 1
            if (isShared())
1213
            {
1214 1
                if (isWild())
1215 1
                    t = mcache.swcto; // shared wild const -> shared
1216
                else
1217 1
                    t = mcache.sto; // shared const => shared
1218
            }
1219
            else
1220
            {
1221 1
                if (isWild())
1222 1
                    t = mcache.wcto; // wild const -> naked
1223
                else
1224 1
                    t = mcache.cto; // const => naked
1225
            }
1226 1
            assert(!t || t.isMutable());
1227
        }
1228 1
        else if (isWild())
1229
        {
1230 1
            getMcache();
1231 1
            if (isShared())
1232 1
                t = mcache.sto; // shared wild => shared
1233
            else
1234 1
                t = mcache.wto; // wild => naked
1235 1
            assert(!t || t.isMutable());
1236
        }
1237 1
        if (!t)
1238
        {
1239 1
            t = makeMutable();
1240 1
            t = t.merge();
1241 1
            t.fixTo(this);
1242
        }
1243
        else
1244 1
            t = t.merge();
1245 1
        assert(t.isMutable());
1246 1
        return t;
1247
    }
1248

1249
    final Type sharedOf()
1250
    {
1251
        //printf("Type::sharedOf() %p, %s\n", this, toChars());
1252 1
        if (mod == MODFlags.shared_)
1253 1
            return this;
1254 1
        if (mcache && mcache.sto)
1255
        {
1256 1
            assert(mcache.sto.mod == MODFlags.shared_);
1257 1
            return mcache.sto;
1258
        }
1259 1
        Type t = makeShared();
1260 1
        t = t.merge();
1261 1
        t.fixTo(this);
1262
        //printf("\t%p\n", t);
1263 1
        return t;
1264
    }
1265

1266
    final Type sharedConstOf()
1267
    {
1268
        //printf("Type::sharedConstOf() %p, %s\n", this, toChars());
1269 1
        if (mod == (MODFlags.shared_ | MODFlags.const_))
1270 1
            return this;
1271 1
        if (mcache && mcache.scto)
1272
        {
1273 1
            assert(mcache.scto.mod == (MODFlags.shared_ | MODFlags.const_));
1274 1
            return mcache.scto;
1275
        }
1276 1
        Type t = makeSharedConst();
1277 1
        t = t.merge();
1278 1
        t.fixTo(this);
1279
        //printf("\t%p\n", t);
1280 1
        return t;
1281
    }
1282

1283
    /********************************
1284
     * Make type unshared.
1285
     *      0            => 0
1286
     *      const        => const
1287
     *      immutable    => immutable
1288
     *      shared       => 0
1289
     *      shared const => const
1290
     *      wild         => wild
1291
     *      wild const   => wild const
1292
     *      shared wild  => wild
1293
     *      shared wild const => wild const
1294
     */
1295
    final Type unSharedOf()
1296
    {
1297
        //printf("Type::unSharedOf() %p, %s\n", this, toChars());
1298 1
        Type t = this;
1299

1300 1
        if (isShared())
1301
        {
1302 1
            getMcache();
1303 1
            if (isWild())
1304
            {
1305 1
                if (isConst())
1306 1
                    t = mcache.wcto; // shared wild const => wild const
1307
                else
1308 1
                    t = mcache.wto; // shared wild => wild
1309
            }
1310
            else
1311
            {
1312 1
                if (isConst())
1313 1
                    t = mcache.cto; // shared const => const
1314
                else
1315 1
                    t = mcache.sto; // shared => naked
1316
            }
1317 1
            assert(!t || !t.isShared());
1318
        }
1319

1320 1
        if (!t)
1321
        {
1322 1
            t = this.nullAttributes();
1323 1
            t.mod = mod & ~MODFlags.shared_;
1324 1
            t.ctype = ctype;
1325 1
            t = t.merge();
1326 1
            t.fixTo(this);
1327
        }
1328
        else
1329 1
            t = t.merge();
1330 1
        assert(!t.isShared());
1331 1
        return t;
1332
    }
1333

1334
    /********************************
1335
     * Convert to 'wild'.
1336
     */
1337
    final Type wildOf()
1338
    {
1339
        //printf("Type::wildOf() %p %s\n", this, toChars());
1340 1
        if (mod == MODFlags.wild)
1341 1
            return this;
1342 1
        if (mcache && mcache.wto)
1343
        {
1344 1
            assert(mcache.wto.mod == MODFlags.wild);
1345 1
            return mcache.wto;
1346
        }
1347 1
        Type t = makeWild();
1348 1
        t = t.merge();
1349 1
        t.fixTo(this);
1350
        //printf("\t%p %s\n", t, t.toChars());
1351 1
        return t;
1352
    }
1353

1354
    final Type wildConstOf()
1355
    {
1356
        //printf("Type::wildConstOf() %p %s\n", this, toChars());
1357 1
        if (mod == MODFlags.wildconst)
1358 1
            return this;
1359 1
        if (mcache && mcache.wcto)
1360
        {
1361 1
            assert(mcache.wcto.mod == MODFlags.wildconst);
1362 1
            return mcache.wcto;
1363
        }
1364 1
        Type t = makeWildConst();
1365 1
        t = t.merge();
1366 1
        t.fixTo(this);
1367
        //printf("\t%p %s\n", t, t.toChars());
1368 1
        return t;
1369
    }
1370

1371
    final Type sharedWildOf()
1372
    {
1373
        //printf("Type::sharedWildOf() %p, %s\n", this, toChars());
1374 1
        if (mod == (MODFlags.shared_ | MODFlags.wild))
1375 1
            return this;
1376 1
        if (mcache && mcache.swto)
1377
        {
1378 1
            assert(mcache.swto.mod == (MODFlags.shared_ | MODFlags.wild));
1379 1
            return mcache.swto;
1380
        }
1381 1
        Type t = makeSharedWild();
1382 1
        t = t.merge();
1383 1
        t.fixTo(this);
1384
        //printf("\t%p %s\n", t, t.toChars());
1385 1
        return t;
1386
    }
1387

1388
    final Type sharedWildConstOf()
1389
    {
1390
        //printf("Type::sharedWildConstOf() %p, %s\n", this, toChars());
1391 1
        if (mod == (MODFlags.shared_ | MODFlags.wildconst))
1392 1
            return this;
1393 1
        if (mcache && mcache.swcto)
1394
        {
1395 1
            assert(mcache.swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
1396 1
            return mcache.swcto;
1397
        }
1398 1
        Type t = makeSharedWildConst();
1399 1
        t = t.merge();
1400 1
        t.fixTo(this);
1401
        //printf("\t%p %s\n", t, t.toChars());
1402 1
        return t;
1403
    }
1404

1405
    /**********************************
1406
     * For our new type 'this', which is type-constructed from t,
1407
     * fill in the cto, ito, sto, scto, wto shortcuts.
1408
     */
1409
    final void fixTo(Type t)
1410
    {
1411
        // If fixing this: immutable(T*) by t: immutable(T)*,
1412
        // cache t to this.xto won't break transitivity.
1413 1
        Type mto = null;
1414 1
        Type tn = nextOf();
1415 1
        if (!tn || ty != Tsarray && tn.mod == t.nextOf().mod)
1416
        {
1417 1
            switch (t.mod)
1418
            {
1419 1
            case 0:
1420 1
                mto = t;
1421 1
                break;
1422

1423 1
            case MODFlags.const_:
1424 1
                getMcache();
1425 1
                mcache.cto = t;
1426 1
                break;
1427

1428 1
            case MODFlags.wild:
1429 1
                getMcache();
1430 1
                mcache.wto = t;
1431 1
                break;
1432

1433 1
            case MODFlags.wildconst:
1434 1
                getMcache();
1435 1
                mcache.wcto = t;
1436 1
                break;
1437

1438 1
            case MODFlags.shared_:
1439 1
                getMcache();
1440 1
                mcache.sto = t;
1441 1
                break;
1442

1443 1
            case MODFlags.shared_ | MODFlags.const_:
1444 1
                getMcache();
1445 1
                mcache.scto = t;
1446 1
                break;
1447

1448 1
            case MODFlags.shared_ | MODFlags.wild:
1449 1
                getMcache();
1450 1
                mcache.swto = t;
1451 1
                break;
1452

1453 1
            case MODFlags.shared_ | MODFlags.wildconst:
1454 1
                getMcache();
1455 1
                mcache.swcto = t;
1456 1
                break;
1457

1458 1
            case MODFlags.immutable_:
1459 1
                getMcache();
1460 1
                mcache.ito = t;
1461 1
                break;
1462

1463 0
            default:
1464 0
                break;
1465
            }
1466
        }
1467 1
        assert(mod != t.mod);
1468

1469 1
        if (mod)
1470
        {
1471 1
            getMcache();
1472 1
            t.getMcache();
1473
        }
1474 1
        switch (mod)
1475
        {
1476 1
        case 0:
1477 1
            break;
1478

1479 1
        case MODFlags.const_:
1480 1
            mcache.cto = mto;
1481 1
            t.mcache.cto = this;
1482 1
            break;
1483

1484 1
        case MODFlags.wild:
1485 1
            mcache.wto = mto;
1486 1
            t.mcache.wto = this;
1487 1
            break;
1488

1489 1
        case MODFlags.wildconst:
1490 1
            mcache.wcto = mto;
1491 1
            t.mcache.wcto = this;
1492 1
            break;
1493

1494 1
        case MODFlags.shared_:
1495 1
            mcache.sto = mto;
1496 1
            t.mcache.sto = this;
1497 1
            break;
1498

1499 1
        case MODFlags.shared_ | MODFlags.const_:
1500 1
            mcache.scto = mto;
1501 1
            t.mcache.scto = this;
1502 1
            break;
1503

1504 1
        case MODFlags.shared_ | MODFlags.wild:
1505 1
            mcache.swto = mto;
1506 1
            t.mcache.swto = this;
1507 1
            break;
1508

1509 1
        case MODFlags.shared_ | MODFlags.wildconst:
1510 1
            mcache.swcto = mto;
1511 1
            t.mcache.swcto = this;
1512 1
            break;
1513

1514 1
        case MODFlags.immutable_:
1515 1
            t.mcache.ito = this;
1516 1
            if (t.mcache.cto)
1517 1
                t.mcache.cto.getMcache().ito = this;
1518 1
            if (t.mcache.sto)
1519 1
                t.mcache.sto.getMcache().ito = this;
1520 1
            if (t.mcache.scto)
1521 1
                t.mcache.scto.getMcache().ito = this;
1522 1
            if (t.mcache.wto)
1523 1
                t.mcache.wto.getMcache().ito = this;
1524 1
            if (t.mcache.wcto)
1525 1
                t.mcache.wcto.getMcache().ito = this;
1526 1
            if (t.mcache.swto)
1527 1
                t.mcache.swto.getMcache().ito = this;
1528 1
            if (t.mcache.swcto)
1529 1
                t.mcache.swcto.getMcache().ito = this;
1530 1
            break;
1531

1532 0
        default:
1533 0
            assert(0);
1534
        }
1535

1536 1
        check();
1537 1
        t.check();
1538
        //printf("fixTo: %s, %s\n", toChars(), t.toChars());
1539
    }
1540

1541
    /***************************
1542
     * Look for bugs in constructing types.
1543
     */
1544
    final void check()
1545
    {
1546 1
        if (mcache)
1547 1
        with (mcache)
1548 1
        switch (mod)
1549
        {
1550 1
        case 0:
1551 1
            if (cto)
1552 1
                assert(cto.mod == MODFlags.const_);
1553 1
            if (ito)
1554 1
                assert(ito.mod == MODFlags.immutable_);
1555 1
            if (sto)
1556 1
                assert(sto.mod == MODFlags.shared_);
1557 1
            if (scto)
1558 1
                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));
1559 1
            if (wto)
1560 1
                assert(wto.mod == MODFlags.wild);
1561 1
            if (wcto)
1562 1
                assert(wcto.mod == MODFlags.wildconst);
1563 1
            if (swto)
1564 1
                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));
1565 1
            if (swcto)
1566 1
                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
1567 1
            break;
1568

1569 1
        case MODFlags.const_:
1570 1
            if (cto)
1571 1
                assert(cto.mod == 0);
1572 1
            if (ito)
1573 1
                assert(ito.mod == MODFlags.immutable_);
1574 1
            if (sto)
1575 1
                assert(sto.mod == MODFlags.shared_);
1576 1
            if (scto)
1577 1
                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));
1578 1
            if (wto)
1579 1
                assert(wto.mod == MODFlags.wild);
1580 1
            if (wcto)
1581 1
                assert(wcto.mod == MODFlags.wildconst);
1582 1
            if (swto)
1583 1
                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));
1584 1
            if (swcto)
1585 1
                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
1586 1
            break;
1587

1588 1
        case MODFlags.wild:
1589 1
            if (cto)
1590 1
                assert(cto.mod == MODFlags.const_);
1591 1
            if (ito)
1592 1
                assert(ito.mod == MODFlags.immutable_);
1593 1
            if (sto)
1594 0
                assert(sto.mod == MODFlags.shared_);
1595 1
            if (scto)
1596 0
                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));
1597 1
            if (wto)
1598 1
                assert(wto.mod == 0);
1599 1
            if (wcto)
1600 1
                assert(wcto.mod == MODFlags.wildconst);
1601 1
            if (swto)
1602 1
                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));
1603 1
            if (swcto)
1604 0
                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
1605 1
            break;
1606

1607 1
        case MODFlags.wildconst:
1608 1
            assert(!cto || cto.mod == MODFlags.const_);
1609 1
            assert(!ito || ito.mod == MODFlags.immutable_);
1610 1
            assert(!sto || sto.mod == MODFlags.shared_);
1611 1
            assert(!scto || scto.mod == (MODFlags.shared_ | MODFlags.const_));
1612 1
            assert(!wto || wto.mod == MODFlags.wild);
1613 1
            assert(!wcto || wcto.mod == 0);
1614 1
            assert(!swto || swto.mod == (MODFlags.shared_ | MODFlags.wild));
1615 1
            assert(!swcto || swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
1616 1
            break;
1617

1618 1
        case MODFlags.shared_:
1619 1
            if (cto)
1620 1
                assert(cto.mod == MODFlags.const_);
1621 1
            if (ito)
1622 1
                assert(ito.mod == MODFlags.immutable_);
1623 1
            if (sto)
1624 1
                assert(sto.mod == 0);
1625 1
            if (scto)
1626 1
                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));
1627 1
            if (wto)
1628 0
                assert(wto.mod == MODFlags.wild);
1629 1
            if (wcto)
1630 0
                assert(wcto.mod == MODFlags.wildconst);
1631 1
            if (swto)
1632 1
                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));
1633 1
            if (swcto)
1634 1
                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
1635 1
            break;
1636

1637 1
        case MODFlags.shared_ | MODFlags.const_:
1638 1
            if (cto)
1639 1
                assert(cto.mod == MODFlags.const_);
1640 1
            if (ito)
1641 1
                assert(ito.mod == MODFlags.immutable_);
1642 1
            if (sto)
1643 1
                assert(sto.mod == MODFlags.shared_);
1644 1
            if (scto)
1645 1
                assert(scto.mod == 0);
1646 1
            if (wto)
1647 0
                assert(wto.mod == MODFlags.wild);
1648 1
            if (wcto)
1649 0
                assert(wcto.mod == MODFlags.wildconst);
1650 1
            if (swto)
1651 0
                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));
1652 1
            if (swcto)
1653 1
                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
1654 1
            break;
1655

1656 1
        case MODFlags.shared_ | MODFlags.wild:
1657 1
            if (cto)
1658 1
                assert(cto.mod == MODFlags.const_);
1659 1
            if (ito)
1660 1
                assert(ito.mod == MODFlags.immutable_);
1661 1
            if (sto)
1662 1
                assert(sto.mod == MODFlags.shared_);
1663 1
            if (scto)
1664 0
                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));
1665 1
            if (wto)
1666 1
                assert(wto.mod == MODFlags.wild);
1667 1
            if (wcto)
1668 0
                assert(wcto.mod == MODFlags.wildconst);
1669 1
            if (swto)
1670 1
                assert(swto.mod == 0);
1671 1
            if (swcto)
1672 1
                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
1673 1
            break;
1674

1675 1
        case MODFlags.shared_ | MODFlags.wildconst:
1676 1
            assert(!cto || cto.mod == MODFlags.const_);
1677 1
            assert(!ito || ito.mod == MODFlags.immutable_);
1678 1
            assert(!sto || sto.mod == MODFlags.shared_);
1679 1
            assert(!scto || scto.mod == (MODFlags.shared_ | MODFlags.const_));
1680 1
            assert(!wto || wto.mod == MODFlags.wild);
1681 1
            assert(!wcto || wcto.mod == MODFlags.wildconst);
1682 1
            assert(!swto || swto.mod == (MODFlags.shared_ | MODFlags.wild));
1683 1
            assert(!swcto || swcto.mod == 0);
1684 1
            break;
1685

1686 1
        case MODFlags.immutable_:
1687 1
            if (cto)
1688 1
                assert(cto.mod == MODFlags.const_);
1689 1
            if (ito)
1690 0
                assert(ito.mod == 0);
1691 1
            if (sto)
1692 1
                assert(sto.mod == MODFlags.shared_);
1693 1
            if (scto)
1694 1
                assert(scto.mod == (MODFlags.shared_ | MODFlags.const_));
1695 1
            if (wto)
1696 1
                assert(wto.mod == MODFlags.wild);
1697 1
            if (wcto)
1698 1
                assert(wcto.mod == MODFlags.wildconst);
1699 1
            if (swto)
1700 1
                assert(swto.mod == (MODFlags.shared_ | MODFlags.wild));
1701 1
            if (swcto)
1702 0
                assert(swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
1703 1
            break;
1704

1705 0
        default:
1706 0
            assert(0);
1707
        }
1708

1709 1
        Type tn = nextOf();
1710 1
        if (tn && ty != Tfunction && tn.ty != Tfunction && ty != Tenum)
1711
        {
1712
            // Verify transitivity
1713 1
            switch (mod)
1714
            {
1715 1
            case 0:
1716 1
            case MODFlags.const_:
1717 1
            case MODFlags.wild:
1718 1
            case MODFlags.wildconst:
1719 1
            case MODFlags.shared_:
1720 1
            case MODFlags.shared_ | MODFlags.const_:
1721 1
            case MODFlags.shared_ | MODFlags.wild:
1722 1
            case MODFlags.shared_ | MODFlags.wildconst:
1723 1
            case MODFlags.immutable_:
1724 1
                assert(tn.mod == MODFlags.immutable_ || (tn.mod & mod) == mod);
1725 1
                break;
1726

1727 0
            default:
1728 0
                assert(0);
1729
            }
1730 1
            tn.check();
1731
        }
1732
    }
1733

1734
    /*************************************
1735
     * Apply STCxxxx bits to existing type.
1736
     * Use *before* semantic analysis is run.
1737
     */
1738
    final Type addSTC(StorageClass stc)
1739
    {
1740 1
        Type t = this;
1741 1
        if (t.isImmutable())
1742
        {
1743
        }
1744 1
        else if (stc & STC.immutable_)
1745
        {
1746 1
            t = t.makeImmutable();
1747
        }
1748
        else
1749
        {
1750 1
            if ((stc & STC.shared_) && !t.isShared())
1751
            {
1752 1
                if (t.isWild())
1753
                {
1754 1
                    if (t.isConst())
1755 1
                        t = t.makeSharedWildConst();
1756
                    else
1757 1
                        t = t.makeSharedWild();
1758
                }
1759
                else
1760
                {
1761 1
                    if (t.isConst())
1762 1
                        t = t.makeSharedConst();
1763
                    else
1764 1
                        t = t.makeShared();
1765
                }
1766
            }
1767 1
            if ((stc & STC.const_) && !t.isConst())
1768
            {
1769 1
                if (t.isShared())
1770
                {
1771 1
                    if (t.isWild())
1772 0
                        t = t.makeSharedWildConst();
1773
                    else
1774 1
                        t = t.makeSharedConst();
1775
                }
1776
                else
1777
                {
1778 1
                    if (t.isWild())
1779 1
                        t = t.makeWildConst();
1780
                    else
1781 1
                        t = t.makeConst();
1782
                }
1783
            }
1784 1
            if ((stc & STC.wild) && !t.isWild())
1785
            {
1786 1
                if (t.isShared())
1787
                {
1788 1
                    if (t.isConst())
1789 1
                        t = t.makeSharedWildConst();
1790
                    else
1791 1
                        t = t.makeSharedWild();
1792
                }
1793
                else
1794
                {
1795 1
                    if (t.isConst())
1796 1
                        t = t.makeWildConst();
1797
                    else
1798 1
                        t = t.makeWild();
1799
                }
1800
            }
1801
        }
1802 1
        return t;
1803
    }
1804

1805
    /************************************
1806
     * Apply MODxxxx bits to existing type.
1807
     */
1808
    final Type castMod(MOD mod)
1809
    {
1810 1
        Type t;
1811 1
        switch (mod)
1812
        {
1813 1
        case 0:
1814 1
            t = unSharedOf().mutableOf();
1815 1
            break;
1816

1817 1
        case MODFlags.const_:
1818 1
            t = unSharedOf().constOf();
1819 1
            break;
1820

1821 1
        case MODFlags.wild:
1822 1
            t = unSharedOf().wildOf();
1823 1
            break;
1824

1825 1
        case MODFlags.wildconst:
1826 1
            t = unSharedOf().wildConstOf();
1827 1
            break;
1828

1829 1
        case MODFlags.shared_:
1830 1
            t = mutableOf().sharedOf();
1831 1
            break;
1832

1833 1
        case MODFlags.shared_ | MODFlags.const_:
1834 1
            t = sharedConstOf();
1835 1
            break;
1836

1837 1
        case MODFlags.shared_ | MODFlags.wild:
1838 1
            t = sharedWildOf();
1839 1
            break;
1840

1841 0
        case MODFlags.shared_ | MODFlags.wildconst:
1842 0
            t = sharedWildConstOf();
1843 0
            break;
1844

1845 1
        case MODFlags.immutable_:
1846 1
            t = immutableOf();
1847 1
            break;
1848

1849 0
        default:
1850 0
            assert(0);
1851
        }
1852 1
        return t;
1853
    }
1854

1855
    /************************************
1856
     * Add MODxxxx bits to existing type.
1857
     * We're adding, not replacing, so adding const to
1858
     * a shared type => "shared const"
1859
     */
1860
    final Type addMod(MOD mod)
1861
    {
1862
        /* Add anything to immutable, and it remains immutable
1863
         */
1864 1
        Type t = this;
1865 1
        if (!t.isImmutable())
1866
        {
1867
            //printf("addMod(%x) %s\n", mod, toChars());
1868 1
            switch (mod)
1869
            {
1870 1
            case 0:
1871 1
                break;
1872

1873 1
            case MODFlags.const_:
1874 1
                if (isShared())
1875
                {
1876 1
                    if (isWild())
1877 0
                        t = sharedWildConstOf();
1878
                    else
1879 1
                        t = sharedConstOf();
1880
                }
1881
                else
1882
                {
1883 1
                    if (isWild())
1884 1
                        t = wildConstOf();
1885
                    else
1886 1
                        t = constOf();
1887
                }
1888 1
                break;
1889

1890 1
            case MODFlags.wild:
1891 1
                if (isShared())
1892
                {
1893 1
                    if (isConst())
1894 1
                        t = sharedWildConstOf();
1895
                    else
1896 1
                        t = sharedWildOf();
1897
                }
1898
                else
1899
                {
1900 1
                    if (isConst())
1901 1
                        t = wildConstOf();
1902
                    else
1903 1
                        t = wildOf();
1904
                }
1905 1
                break;
1906

1907 1
            case MODFlags.wildconst:
1908 1
                if (isShared())
1909 1
                    t = sharedWildConstOf();
1910
                else
1911 1
                    t = wildConstOf();
1912 1
                break;
1913

1914 1
            case MODFlags.shared_:
1915 1
                if (isWild())
1916
                {
1917 1
                    if (isConst())
1918 1
                        t = sharedWildConstOf();
1919
                    else
1920 1
                        t = sharedWildOf();
1921
                }
1922
                else
1923
                {
1924 1
                    if (isConst())
1925 1
                        t = sharedConstOf();
1926
                    else
1927 1
                        t = sharedOf();
1928
                }
1929 1
                break;
1930

1931 1
            case MODFlags.shared_ | MODFlags.const_:
1932 1
                if (isWild())
1933 1
                    t = sharedWildConstOf();
1934
                else
1935 1
                    t = sharedConstOf();
1936 1
                break;
1937

1938 1
            case MODFlags.shared_ | MODFlags.wild:
1939 1
                if (isConst())
1940 1
                    t = sharedWildConstOf();
1941
                else
1942 1
                    t = sharedWildOf();
1943 1
                break;
1944

1945 1
            case MODFlags.shared_ | MODFlags.wildconst:
1946 1
                t = sharedWildConstOf();
1947 1
                break;
1948

1949 1
            case MODFlags.immutable_:
1950 1
                t = immutableOf();
1951 1
                break;
1952

1953 0
            default:
1954 0
                assert(0);
1955
            }
1956
        }
1957 1
        return t;
1958
    }
1959

1960
    /************************************
1961
     * Add storage class modifiers to type.
1962
     */
1963
    Type addStorageClass(StorageClass stc)
1964
    {
1965
        /* Just translate to MOD bits and let addMod() do the work
1966
         */
1967 1
        MOD mod = 0;
1968 1
        if (stc & STC.immutable_)
1969 1
            mod = MODFlags.immutable_;
1970
        else
1971
        {
1972 1
            if (stc & (STC.const_ | STC.in_))
1973 1
                mod |= MODFlags.const_;
1974 1
            if (stc & STC.wild)
1975 1
                mod |= MODFlags.wild;
1976 1
            if (stc & STC.shared_)
1977 1
                mod |= MODFlags.shared_;
1978
        }
1979 1
        return addMod(mod);
1980
    }
1981

1982
    final Type pointerTo()
1983
    {
1984 1
        if (ty == Terror)
1985 1
            return this;
1986 1
        if (!pto)
1987
        {
1988 1
            Type t = new TypePointer(this);
1989 1
            if (ty == Tfunction)
1990
            {
1991 1
                t.deco = t.merge().deco;
1992 1
                pto = t;
1993
            }
1994
            else
1995 1
                pto = t.merge();
1996
        }
1997 1
        return pto;
1998
    }
1999

2000
    final Type referenceTo()
2001
    {
2002 1
        if (ty == Terror)
2003 0
            return this;
2004 1
        if (!rto)
2005
        {
2006 1
            Type t = new TypeReference(this);
2007 1
            rto = t.merge();
2008
        }
2009 1
        return rto;
2010
    }
2011

2012
    final Type arrayOf()
2013
    {
2014 1
        if (ty == Terror)
2015 0
            return this;
2016 1
        if (!arrayof)
2017
        {
2018 1
            Type t = new TypeDArray(this);
2019 1
            arrayof = t.merge();
2020
        }
2021 1
        return arrayof;
2022
    }
2023

2024
    // Make corresponding static array type without semantic
2025
    final Type sarrayOf(dinteger_t dim)
2026
    {
2027 1
        assert(deco);
2028 1
        Type t = new TypeSArray(this, new IntegerExp(Loc.initial, dim, Type.tsize_t));
2029
        // according to TypeSArray::semantic()
2030 1
        t = t.addMod(mod);
2031 1
        t = t.merge();
2032 1
        return t;
2033
    }
2034

2035
    final bool hasDeprecatedAliasThis()
2036
    {
2037 1
        auto ad = isAggregate(this);
2038 1
        return ad && ad.aliasthis && (ad.aliasthis.isDeprecated || ad.aliasthis.sym.isDeprecated);
2039
    }
2040

2041
    final Type aliasthisOf()
2042
    {
2043 1
        auto ad = isAggregate(this);
2044 1
        if (!ad || !ad.aliasthis)
2045 1
            return null;
2046

2047 1
        auto s = ad.aliasthis.sym;
2048 1
        if (s.isAliasDeclaration())
2049 1
            s = s.toAlias();
2050

2051 1
        if (s.isTupleDeclaration())
2052 1
            return null;
2053

2054 1
        if (auto vd = s.isVarDeclaration())
2055
        {
2056 1
            auto t = vd.type;
2057 1
            if (vd.needThis())
2058 1
                t = t.addMod(this.mod);
2059 1
            return t;
2060
        }
2061 1
        if (auto fd = s.isFuncDeclaration())
2062
        {
2063 1
            fd = resolveFuncCall(Loc.initial, null, fd, null, this, null, FuncResolveFlag.quiet);
2064 1
            if (!fd || fd.errors || !fd.functionSemantic())
2065 1
                return Type.terror;
2066

2067 1
            auto t = fd.type.nextOf();
2068 1
            if (!t) // issue 14185
2069 1
                return Type.terror;
2070 1
            t = t.substWildTo(mod == 0 ? MODFlags.mutable : mod);
2071 1
            return t;
2072
        }
2073 1
        if (auto d = s.isDeclaration())
2074
        {
2075 0
            assert(d.type);
2076 0
            return d.type;
2077
        }
2078 1
        if (auto ed = s.isEnumDeclaration())
2079
        {
2080 1
            return ed.type;
2081
        }
2082 1
        if (auto td = s.isTemplateDeclaration())
2083
        {
2084 1
            assert(td._scope);
2085 1
            auto fd = resolveFuncCall(Loc.initial, null, td, null, this, null, FuncResolveFlag.quiet);
2086 1
            if (!fd || fd.errors || !fd.functionSemantic())
2087 1
                return Type.terror;
2088

2089 1
            auto t = fd.type.nextOf();
2090 1
            if (!t)
2091 0
                return Type.terror;
2092 1
            t = t.substWildTo(mod == 0 ? MODFlags.mutable : mod);
2093 1
            return t;
2094
        }
2095

2096
        //printf("%s\n", s.kind());
2097 0
        return null;
2098
    }
2099

2100
    extern (D) final bool checkAliasThisRec()
2101
    {
2102 1
        Type tb = toBasetype();
2103 1
        AliasThisRec* pflag;
2104 1
        if (tb.ty == Tstruct)
2105 1
            pflag = &(cast(TypeStruct)tb).att;
2106 1
        else if (tb.ty == Tclass)
2107 1
            pflag = &(cast(TypeClass)tb).att;
2108
        else
2109 0
            return false;
2110

2111 1
        AliasThisRec flag = cast(AliasThisRec)(*pflag & AliasThisRec.typeMask);
2112 1
        if (flag == AliasThisRec.fwdref)
2113
        {
2114 1
            Type att = aliasthisOf();
2115 1
            flag = att && att.implicitConvTo(this) ? AliasThisRec.yes : AliasThisRec.no;
2116
        }
2117 1
        *pflag = cast(AliasThisRec)(flag | (*pflag & ~AliasThisRec.typeMask));
2118 1
        return flag == AliasThisRec.yes;
2119
    }
2120

2121
    Type makeConst()
2122
    {
2123
        //printf("Type::makeConst() %p, %s\n", this, toChars());
2124 1
        if (mcache && mcache.cto)
2125 1
            return mcache.cto;
2126 1
        Type t = this.nullAttributes();
2127 1
        t.mod = MODFlags.const_;
2128
        //printf("-Type::makeConst() %p, %s\n", t, toChars());
2129 1
        return t;
2130
    }
2131

2132
    Type makeImmutable()
2133
    {
2134 1
        if (mcache && mcache.ito)
2135 1
            return mcache.ito;
2136 1
        Type t = this.nullAttributes();
2137 1
        t.mod = MODFlags.immutable_;
2138 1
        return t;
2139
    }
2140

2141
    Type makeShared()
2142
    {
2143 1
        if (mcache && mcache.sto)
2144 1
            return mcache.sto;
2145 1
        Type t = this.nullAttributes();
2146 1
        t.mod = MODFlags.shared_;
2147 1
        return t;
2148
    }
2149

2150
    Type makeSharedConst()
2151
    {
2152 1
        if (mcache && mcache.scto)
2153 1
            return mcache.scto;
2154 1
        Type t = this.nullAttributes();
2155 1
        t.mod = MODFlags.shared_ | MODFlags.const_;
2156 1
        return t;
2157
    }
2158

2159
    Type makeWild()
2160
    {
2161 1
        if (mcache && mcache.wto)
2162 1
            return mcache.wto;
2163 1
        Type t = this.nullAttributes();
2164 1
        t.mod = MODFlags.wild;
2165 1
        return t;
2166
    }
2167

2168
    Type makeWildConst()
2169
    {
2170 1
        if (mcache && mcache.wcto)
2171 1
            return mcache.wcto;
2172 1
        Type t = this.nullAttributes();
2173 1
        t.mod = MODFlags.wildconst;
2174 1
        return t;
2175
    }
2176

2177
    Type makeSharedWild()
2178
    {
2179 1
        if (mcache && mcache.swto)
2180 1
            return mcache.swto;
2181 1
        Type t = this.nullAttributes();
2182 1
        t.mod = MODFlags.shared_ | MODFlags.wild;
2183 1
        return t;
2184
    }
2185

2186
    Type makeSharedWildConst()
2187
    {
2188 1
        if (mcache && mcache.swcto)
2189 0
            return mcache.swcto;
2190 1
        Type t = this.nullAttributes();
2191 1
        t.mod = MODFlags.shared_ | MODFlags.wildconst;
2192 1
        return t;
2193
    }
2194

2195
    Type makeMutable()
2196
    {
2197 1
        Type t = this.nullAttributes();
2198 1
        t.mod = mod & MODFlags.shared_;
2199 1
        return t;
2200
    }
2201

2202
    Dsymbol toDsymbol(Scope* sc)
2203
    {
2204 1
        return null;
2205
    }
2206

2207
    /*******************************
2208
     * If this is a shell around another type,
2209
     * get that other type.
2210
     */
2211
    final Type toBasetype()
2212
    {
2213
        /* This function is used heavily.
2214
         * De-virtualize it so it can be easily inlined.
2215
         */
2216 1
        TypeEnum te;
2217 1
        return ((te = isTypeEnum()) !is null) ? te.toBasetype2() : this;
2218
    }
2219

2220
    bool isBaseOf(Type t, int* poffset)
2221
    {
2222 1
        return 0; // assume not
2223
    }
2224

2225
    /********************************
2226
     * Determine if 'this' can be implicitly converted
2227
     * to type 'to'.
2228
     * Returns:
2229
     *      MATCH.nomatch, MATCH.convert, MATCH.constant, MATCH.exact
2230
     */
2231
    MATCH implicitConvTo(Type to)
2232
    {
2233
        //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
2234
        //printf("from: %s\n", toChars());
2235
        //printf("to  : %s\n", to.toChars());
2236 1
        if (this.equals(to))
2237 1
            return MATCH.exact;
2238 1
        return MATCH.nomatch;
2239
    }
2240

2241
    /*******************************
2242
     * Determine if converting 'this' to 'to' is an identity operation,
2243
     * a conversion to const operation, or the types aren't the same.
2244
     * Returns:
2245
     *      MATCH.exact      'this' == 'to'
2246
     *      MATCH.constant      'to' is const
2247
     *      MATCH.nomatch    conversion to mutable or invariant
2248
     */
2249
    MATCH constConv(Type to)
2250
    {
2251
        //printf("Type::constConv(this = %s, to = %s)\n", toChars(), to.toChars());
2252 1
        if (equals(to))
2253 1
            return MATCH.exact;
2254 1
        if (ty == to.ty && MODimplicitConv(mod, to.mod))
2255 1
            return MATCH.constant;
2256 1
        return MATCH.nomatch;
2257
    }
2258

2259
    /***************************************
2260
     * Compute MOD bits matching `this` argument type to wild parameter type.
2261
     * Params:
2262
     *  t = corresponding parameter type
2263
     *  isRef = parameter is `ref` or `out`
2264
     * Returns:
2265
     *  MOD bits
2266
     */
2267
    MOD deduceWild(Type t, bool isRef)
2268
    {
2269
        //printf("Type::deduceWild this = '%s', tprm = '%s'\n", toChars(), tprm.toChars());
2270 1
        if (t.isWild())
2271
        {
2272 1
            if (isImmutable())
2273 1
                return MODFlags.immutable_;
2274 1
            else if (isWildConst())
2275
            {
2276 1
                if (t.isWildConst())
2277 1
                    return MODFlags.wild;
2278
                else
2279 1
                    return MODFlags.wildconst;
2280
            }
2281 1
            else if (isWild())
2282 1
                return MODFlags.wild;
2283 1
            else if (isConst())
2284 1
                return MODFlags.const_;
2285 1
            else if (isMutable())
2286 1
                return MODFlags.mutable;
2287
            else
2288 0
                assert(0);
2289
        }
2290 1
        return 0;
2291
    }
2292

2293
    Type substWildTo(uint mod)
2294
    {
2295
        //printf("+Type::substWildTo this = %s, mod = x%x\n", toChars(), mod);
2296 1
        Type t;
2297

2298 1
        if (Type tn = nextOf())
2299
        {
2300
            // substitution has no effect on function pointer type.
2301 1
            if (ty == Tpointer && tn.ty == Tfunction)
2302
            {
2303 1
                t = this;
2304 1
                goto L1;
2305
            }
2306

2307 1
            t = tn.substWildTo(mod);
2308 1
            if (t == tn)
2309 1
                t = this;
2310
            else
2311
            {
2312 1
                if (ty == Tpointer)
2313 1
                    t = t.pointerTo();
2314 1
                else if (ty == Tarray)
2315 1
                    t = t.arrayOf();
2316 1
                else if (ty == Tsarray)
2317 1
                    t = new TypeSArray(t, (cast(TypeSArray)this).dim.syntaxCopy());
2318 1
                else if (ty == Taarray)
2319
                {
2320 1
                    t = new TypeAArray(t, (cast(TypeAArray)this).index.syntaxCopy());
2321
                }
2322 1
                else if (ty == Tdelegate)
2323
                {
2324 1
                    t = new TypeDelegate(t);
2325
                }
2326
                else
2327 0
                    assert(0);
2328

2329 1
                t = t.merge();
2330
            }
2331
        }
2332
        else
2333 1
            t = this;
2334

2335
    L1:
2336 1
        if (isWild())
2337
        {
2338 1
            if (mod == MODFlags.immutable_)
2339
            {
2340 1
                t = t.immutableOf();
2341
            }
2342 1
            else if (mod == MODFlags.wildconst)
2343
            {
2344 1
                t = t.wildConstOf();
2345
            }
2346 1
            else if (mod == MODFlags.wild)
2347
            {
2348 1
                if (isWildConst())
2349 1
                    t = t.wildConstOf();
2350
                else
2351 1
                    t = t.wildOf();
2352
            }
2353 1
            else if (mod == MODFlags.const_)
2354
            {
2355 1
                t = t.constOf();
2356
            }
2357
            else
2358
            {
2359 1
                if (isWildConst())
2360 1
                    t = t.constOf();
2361
                else
2362 1
                    t = t.mutableOf();
2363
            }
2364
        }
2365 1
        if (isConst())
2366 1
            t = t.addMod(MODFlags.const_);
2367 1
        if (isShared())
2368 1
            t = t.addMod(MODFlags.shared_);
2369

2370
        //printf("-Type::substWildTo t = %s\n", t.toChars());
2371 1
        return t;
2372
    }
2373

2374
    final Type unqualify(uint m)
2375
    {
2376 1
        Type t = mutableOf().unSharedOf();
2377

2378 1
        Type tn = ty == Tenum ? null : nextOf();
2379 1
        if (tn && tn.ty != Tfunction)
2380
        {
2381 1
            Type utn = tn.unqualify(m);
2382 1
            if (utn != tn)
2383
            {
2384 1
                if (ty == Tpointer)
2385 1
                    t = utn.pointerTo();
2386 1
                else if (ty == Tarray)
2387 1
                    t = utn.arrayOf();
2388 0
                else if (ty == Tsarray)
2389 0
                    t = new TypeSArray(utn, (cast(TypeSArray)this).dim);
2390 0
                else if (ty == Taarray)
2391
                {
2392 0
                    t = new TypeAArray(utn, (cast(TypeAArray)this).index);
2393
                }
2394
                else
2395 0
                    assert(0);
2396

2397 1
                t = t.merge();
2398
            }
2399
        }
2400 1
        t = t.addMod(mod & ~m);
2401 1
        return t;
2402
    }
2403

2404
    /**************************
2405
     * Return type with the top level of it being mutable.
2406
     */
2407
    inout(Type) toHeadMutable() inout
2408
    {
2409 1
        if (!mod)
2410 1
            return this;
2411 1
        Type unqualThis = cast(Type) this;
2412
        // `mutableOf` needs a mutable `this` only for caching
2413 1
        return cast(inout(Type)) unqualThis.mutableOf();
2414
    }
2415

2416
    inout(ClassDeclaration) isClassHandle() inout
2417
    {
2418 1
        return null;
2419
    }
2420

2421
    /************************************
2422
     * Return alignment to use for this type.
2423
     */
2424
    structalign_t alignment()
2425
    {
2426 1
        return STRUCTALIGN_DEFAULT;
2427
    }
2428

2429
    /***************************************
2430
     * Use when we prefer the default initializer to be a literal,
2431
     * rather than a global immutable variable.
2432
     */
2433
    Expression defaultInitLiteral(const ref Loc loc)
2434
    {
2435
        static if (LOGDEFAULTINIT)
2436
        {
2437
            printf("Type::defaultInitLiteral() '%s'\n", toChars());
2438
        }
2439 1
        return defaultInit(this, loc);
2440
    }
2441

2442
    // if initializer is 0
2443
    bool isZeroInit(const ref Loc loc)
2444
    {
2445 0
        return false; // assume not
2446
    }
2447

2448
    final Identifier getTypeInfoIdent()
2449
    {
2450
        // _init_10TypeInfo_%s
2451 1
        OutBuffer buf;
2452 1
        buf.reserve(32);
2453 1
        mangleToBuffer(this, &buf);
2454

2455 1
        const slice = buf[];
2456

2457
        // Allocate buffer on stack, fail over to using malloc()
2458 1
        char[128] namebuf;
2459 1
        const namelen = 19 + size_t.sizeof * 3 + slice.length + 1;
2460 1
        auto name = namelen <= namebuf.length ? namebuf.ptr : cast(char*)Mem.check(malloc(namelen));
2461

2462 1
        const length = sprintf(name, "_D%lluTypeInfo_%.*s6__initZ",
2463
                cast(ulong)(9 + slice.length), cast(int)slice.length, slice.ptr);
2464
        //printf("%p %s, deco = %s, name = %s\n", this, toChars(), deco, name);
2465 1
        assert(0 < length && length < namelen); // don't overflow the buffer
2466

2467 1
        auto id = Identifier.idPool(name, length);
2468

2469 1
        if (name != namebuf.ptr)
2470 1
            free(name);
2471 1
        return id;
2472
    }
2473

2474
    /***************************************
2475
     * Return !=0 if the type or any of its subtypes is wild.
2476
     */
2477
    int hasWild() const
2478
    {
2479 1
        return mod & MODFlags.wild;
2480
    }
2481

2482
    /***************************************
2483
     * Return !=0 if type has pointers that need to
2484
     * be scanned by the GC during a collection cycle.
2485
     */
2486
    bool hasPointers()
2487
    {
2488
        //printf("Type::hasPointers() %s, %d\n", toChars(), ty);
2489 1
        return false;
2490
    }
2491

2492
    /*************************************
2493
     * Detect if type has pointer fields that are initialized to void.
2494
     * Local stack variables with such void fields can remain uninitialized,
2495
     * leading to pointer bugs.
2496
     * Returns:
2497
     *  true if so
2498
     */
2499
    bool hasVoidInitPointers()
2500
    {
2501 1
        return false;
2502
    }
2503

2504
    /*************************************
2505
     * If this is a type of something, return that something.
2506
     */
2507
    Type nextOf()
2508
    {
2509 1
        return null;
2510
    }
2511

2512
    /*************************************
2513
     * If this is a type of static array, return its base element type.
2514
     */
2515
    final Type baseElemOf()
2516
    {
2517 1
        Type t = toBasetype();
2518 1
        TypeSArray tsa;
2519 1
        while ((tsa = t.isTypeSArray()) !is null)
2520 1
            t = tsa.next.toBasetype();
2521 1
        return t;
2522
    }
2523

2524
    /*******************************************
2525
     * Compute number of elements for a (possibly multidimensional) static array,
2526
     * or 1 for other types.
2527
     * Params:
2528
     *  loc = for error message
2529
     * Returns:
2530
     *  number of elements, uint.max on overflow
2531
     */
2532
    final uint numberOfElems(const ref Loc loc)
2533
    {
2534
        //printf("Type::numberOfElems()\n");
2535 1
        uinteger_t n = 1;
2536 1
        Type tb = this;
2537 1
        while ((tb = tb.toBasetype()).ty == Tsarray)
2538
        {
2539 1
            bool overflow = false;
2540 1
            n = mulu(n, (cast(TypeSArray)tb).dim.toUInteger(), overflow);
2541 1
            if (overflow || n >= uint.max)
2542
            {
2543 1
                error(loc, "static array `%s` size overflowed to %llu", toChars(), cast(ulong)n);
2544 1
                return uint.max;
2545
            }
2546 1
            tb = (cast(TypeSArray)tb).next;
2547
        }
2548 1
        return cast(uint)n;
2549
    }
2550

2551
    /****************************************
2552
     * Return the mask that an integral type will
2553
     * fit into.
2554
     */
2555
    final uinteger_t sizemask()
2556
    {
2557 1
        uinteger_t m;
2558 1
        switch (toBasetype().ty)
2559
        {
2560 1
        case Tbool:
2561 1
            m = 1;
2562 1
            break;
2563 1
        case Tchar:
2564 1
        case Tint8:
2565 1
        case Tuns8:
2566 1
            m = 0xFF;
2567 1
            break;
2568 1
        case Twchar:
2569 1
        case Tint16:
2570 1
        case Tuns16:
2571 1
            m = 0xFFFFU;
2572 1
            break;
2573 1
        case Tdchar:
2574 1
        case Tint32:
2575 1
        case Tuns32:
2576 1
            m = 0xFFFFFFFFU;
2577 1
            break;
2578 1
        case Tint64:
2579 1
        case Tuns64:
2580 1
            m = 0xFFFFFFFFFFFFFFFFUL;
2581 1
            break;
2582 0
        default:
2583 0
            assert(0);
2584
        }
2585 1
        return m;
2586
    }
2587

2588
    /********************************
2589
     * true if when type goes out of scope, it needs a destructor applied.
2590
     * Only applies to value types, not ref types.
2591
     */
2592
    bool needsDestruction()
2593
    {
2594 1
        return false;
2595
    }
2596

2597
    /********************************
2598
     * true if when type is copied, it needs a copy constructor or postblit
2599
     * applied. Only applies to value types, not ref types.
2600
     */
2601
    bool needsCopyOrPostblit()
2602
    {
2603 1
        return false;
2604
    }
2605

2606
    /*********************************
2607
     *
2608
     */
2609
    bool needsNested()
2610
    {
2611 1
        return false;
2612
    }
2613

2614
    /*************************************
2615
     * https://issues.dlang.org/show_bug.cgi?id=14488
2616
     * Check if the inner most base type is complex or imaginary.
2617
     * Should only give alerts when set to emit transitional messages.
2618
     * Params:
2619
     *  loc = The source location.
2620
     *  sc = scope of the type
2621
     */
2622
    extern (D) final bool checkComplexTransition(const ref Loc loc, Scope* sc)
2623
    {
2624 1
        if (sc.isDeprecated())
2625 1
            return false;
2626

2627 1
        Type t = baseElemOf();
2628 1
        while (t.ty == Tpointer || t.ty == Tarray)
2629 1
            t = t.nextOf().baseElemOf();
2630

2631
        // Basetype is an opaque enum, nothing to check.
2632 1
        if (t.ty == Tenum && !(cast(TypeEnum)t).sym.memtype)
2633 1
            return false;
2634

2635 1
        if (t.isimaginary() || t.iscomplex())
2636
        {
2637 1
            Type rt;
2638 1
            switch (t.ty)
2639
            {
2640 1
            case Tcomplex32:
2641 1
            case Timaginary32:
2642 1
                rt = Type.tfloat32;
2643 1
                break;
2644

2645 1
            case Tcomplex64:
2646 1
            case Timaginary64:
2647 1
                rt = Type.tfloat64;
2648 1
                break;
2649

2650 1
            case Tcomplex80:
2651 1
            case Timaginary80:
2652 1
                rt = Type.tfloat80;
2653 1
                break;
2654

2655 0
            default:
2656 0
                assert(0);
2657
            }
2658 1
            if (t.iscomplex())
2659
            {
2660 1
                deprecation(loc, "use of complex type `%s` is deprecated, use `std.complex.Complex!(%s)` instead",
2661
                    toChars(), rt.toChars());
2662 1
                return true;
2663
            }
2664
            else
2665
            {
2666 1
                deprecation(loc, "use of imaginary type `%s` is deprecated, use `%s` instead",
2667
                    toChars(), rt.toChars());
2668 1
                return true;
2669
            }
2670
        }
2671 1
        return false;
2672
    }
2673

2674
    // For eliminating dynamic_cast
2675
    TypeBasic isTypeBasic()
2676
    {
2677 1
        return null;
2678
    }
2679

2680
    final pure inout nothrow @nogc
2681
    {
2682 0
        inout(TypeError)      isTypeError()      { return ty == Terror     ? cast(typeof(return))this : null; }
2683 1
        inout(TypeVector)     isTypeVector()     { return ty == Tvector    ? cast(typeof(return))this : null; }
2684 1
        inout(TypeSArray)     isTypeSArray()     { return ty == Tsarray    ? cast(typeof(return))this : null; }
2685 1
        inout(TypeDArray)     isTypeDArray()     { return ty == Tarray     ? cast(typeof(return))this : null; }
2686 1
        inout(TypeAArray)     isTypeAArray()     { return ty == Taarray    ? cast(typeof(return))this : null; }
2687 1
        inout(TypePointer)    isTypePointer()    { return ty == Tpointer   ? cast(typeof(return))this : null; }
2688 1
        inout(TypeReference)  isTypeReference()  { return ty == Treference ? cast(typeof(return))this : null; }
2689 1
        inout(TypeFunction)   isTypeFunction()   { return ty == Tfunction  ? cast(typeof(return))this : null; }
2690 1
        inout(TypeDelegate)   isTypeDelegate()   { return ty == Tdelegate  ? cast(typeof(return))this : null; }
2691 1
        inout(TypeIdentifier) isTypeIdentifier() { return ty == Tident     ? cast(typeof(return))this : null; }
2692 1
        inout(TypeInstance)   isTypeInstance()   { return ty == Tinstance  ? cast(typeof(return))this : null; }
2693 1
        inout(TypeTypeof)     isTypeTypeof()     { return ty == Ttypeof    ? cast(typeof(return))this : null; }
2694 0
        inout(TypeReturn)     isTypeReturn()     { return ty == Treturn    ? cast(typeof(return))this : null; }
2695 1
        inout(TypeStruct)     isTypeStruct()     { return ty == Tstruct    ? cast(typeof(return))this : null; }
2696 1
        inout(TypeEnum)       isTypeEnum()       { return ty == Tenum      ? cast(typeof(return))this : null; }
2697 1
        inout(TypeClass)      isTypeClass()      { return ty == Tclass     ? cast(typeof(return))this : null; }
2698 1
        inout(TypeTuple)      isTypeTuple()      { return ty == Ttuple     ? cast(typeof(return))this : null; }
2699 0
        inout(TypeSlice)      isTypeSlice()      { return ty == Tslice     ? cast(typeof(return))this : null; }
2700 0
        inout(TypeNull)       isTypeNull()       { return ty == Tnull      ? cast(typeof(return))this : null; }
2701 1
        inout(TypeMixin)      isTypeMixin()      { return ty == Tmixin     ? cast(typeof(return))this : null; }
2702 0
        inout(TypeTraits)     isTypeTraits()     { return ty == Ttraits    ? cast(typeof(return))this : null; }
2703
    }
2704

2705
    override void accept(Visitor v)
2706
    {
2707 0
        v.visit(this);
2708
    }
2709

2710
    final TypeFunction toTypeFunction()
2711
    {
2712 1
        if (ty != Tfunction)
2713 0
            assert(0);
2714 1
        return cast(TypeFunction)this;
2715
    }
2716
}
2717

2718
/***********************************************************
2719
 */
2720
extern (C++) final class TypeError : Type
2721
{
2722 1
    extern (D) this()
2723
    {
2724 1
        super(Terror);
2725
    }
2726

2727
    override const(char)* kind() const
2728
    {
2729 0
        return "error";
2730
    }
2731

2732
    override Type syntaxCopy()
2733
    {
2734
        // No semantic analysis done, no need to copy
2735 1
        return this;
2736
    }
2737

2738
    override d_uns64 size(const ref Loc loc)
2739
    {
2740 1
        return SIZE_INVALID;
2741
    }
2742

2743
    override Expression defaultInitLiteral(const ref Loc loc)
2744
    {
2745 0
        return ErrorExp.get();
2746
    }
2747

2748
    override void accept(Visitor v)
2749
    {
2750 1
        v.visit(this);
2751
    }
2752
}
2753

2754
/***********************************************************
2755
 */
2756
extern (C++) abstract class TypeNext : Type
2757
{
2758
    Type next;
2759

2760 1
    final extern (D) this(TY ty, Type next)
2761
    {
2762 1
        super(ty);
2763 1
        this.next = next;
2764
    }
2765

2766
    override final void checkDeprecated(const ref Loc loc, Scope* sc)
2767
    {
2768 1
        Type.checkDeprecated(loc, sc);
2769 1
        if (next) // next can be NULL if TypeFunction and auto return type
2770 1
            next.checkDeprecated(loc, sc);
2771
    }
2772

2773
    override final int hasWild() const
2774
    {
2775 1
        if (ty == Tfunction)
2776 1
            return 0;
2777 1
        if (ty == Tdelegate)
2778 1
            return Type.hasWild();
2779 1
        return mod & MODFlags.wild || (next && next.hasWild());
2780
    }
2781

2782
    /*******************************
2783
     * For TypeFunction, nextOf() can return NULL if the function return
2784
     * type is meant to be inferred, and semantic() hasn't yet ben run
2785
     * on the function. After semantic(), it must no longer be NULL.
2786
     */
2787
    override final Type nextOf()
2788
    {
2789 1
        return next;
2790
    }
2791

2792
    override final Type makeConst()
2793
    {
2794
        //printf("TypeNext::makeConst() %p, %s\n", this, toChars());
2795 1
        if (mcache && mcache.cto)
2796
        {
2797 0
            assert(mcache.cto.mod == MODFlags.const_);
2798 0
            return mcache.cto;
2799
        }
2800 1
        TypeNext t = cast(TypeNext)Type.makeConst();
2801 1
        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())
2802
        {
2803 1
            if (next.isShared())
2804
            {
2805 1
                if (next.isWild())
2806 1
                    t.next = next.sharedWildConstOf();
2807
                else
2808 1
                    t.next = next.sharedConstOf();
2809
            }
2810
            else
2811
            {
2812 1
                if (next.isWild())
2813 1
                    t.next = next.wildConstOf();
2814
                else
2815 1
                    t.next = next.constOf();
2816
            }
2817
        }
2818
        //printf("TypeNext::makeConst() returns %p, %s\n", t, t.toChars());
2819 1
        return t;
2820
    }
2821

2822
    override final Type makeImmutable()
2823
    {
2824
        //printf("TypeNext::makeImmutable() %s\n", toChars());
2825 1
        if (mcache && mcache.ito)
2826
        {
2827 0
            assert(mcache.ito.isImmutable());
2828 0
            return mcache.ito;
2829
        }
2830 1
        TypeNext t = cast(TypeNext)Type.makeImmutable();
2831 1
        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())
2832
        {
2833 1
            t.next = next.immutableOf();
2834
        }
2835 1
        return t;
2836
    }
2837

2838
    override final Type makeShared()
2839
    {
2840
        //printf("TypeNext::makeShared() %s\n", toChars());
2841 1
        if (mcache && mcache.sto)
2842
        {
2843 0
            assert(mcache.sto.mod == MODFlags.shared_);
2844 0
            return mcache.sto;
2845
        }
2846 1
        TypeNext t = cast(TypeNext)Type.makeShared();
2847 1
        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())
2848
        {
2849 1
            if (next.isWild())
2850
            {
2851 1
                if (next.isConst())
2852 0
                    t.next = next.sharedWildConstOf();
2853
                else
2854 1
                    t.next = next.sharedWildOf();
2855
            }
2856
            else
2857
            {
2858 1
                if (next.isConst())
2859 1
                    t.next = next.sharedConstOf();
2860
                else
2861 1
                    t.next = next.sharedOf();
2862
            }
2863
        }
2864
        //printf("TypeNext::makeShared() returns %p, %s\n", t, t.toChars());
2865 1
        return t;
2866
    }
2867

2868
    override final Type makeSharedConst()
2869
    {
2870
        //printf("TypeNext::makeSharedConst() %s\n", toChars());
2871 1
        if (mcache && mcache.scto)
2872
        {
2873 0
            assert(mcache.scto.mod == (MODFlags.shared_ | MODFlags.const_));
2874 0
            return mcache.scto;
2875
        }
2876 1
        TypeNext t = cast(TypeNext)Type.makeSharedConst();
2877 1
        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())
2878
        {
2879 1
            if (next.isWild())
2880 1
                t.next = next.sharedWildConstOf();
2881
            else
2882 1
                t.next = next.sharedConstOf();
2883
        }
2884
        //printf("TypeNext::makeSharedConst() returns %p, %s\n", t, t.toChars());
2885 1
        return t;
2886
    }
2887

2888
    override final Type makeWild()
2889
    {
2890
        //printf("TypeNext::makeWild() %s\n", toChars());
2891 1
        if (mcache && mcache.wto)
2892
        {
2893 0
            assert(mcache.wto.mod == MODFlags.wild);
2894 0
            return mcache.wto;
2895
        }
2896 1
        TypeNext t = cast(TypeNext)Type.makeWild();
2897 1
        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())
2898
        {
2899 1
            if (next.isShared())
2900
            {
2901 1
                if (next.isConst())
2902 1
                    t.next = next.sharedWildConstOf();
2903
                else
2904 1
                    t.next = next.sharedWildOf();
2905
            }
2906
            else
2907
            {
2908 1
                if (next.isConst())
2909 1
                    t.next = next.wildConstOf();
2910
                else
2911 1
                    t.next = next.wildOf();
2912
            }
2913
        }
2914
        //printf("TypeNext::makeWild() returns %p, %s\n", t, t.toChars());
2915 1
        return t;
2916
    }
2917

2918
    override final Type makeWildConst()
2919
    {
2920
        //printf("TypeNext::makeWildConst() %s\n", toChars());
2921 1
        if (mcache && mcache.wcto)
2922
        {
2923 0
            assert(mcache.wcto.mod == MODFlags.wildconst);
2924 0
            return mcache.wcto;
2925
        }
2926 1
        TypeNext t = cast(TypeNext)Type.makeWildConst();
2927 1
        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())
2928
        {
2929 1
            if (next.isShared())
2930 0
                t.next = next.sharedWildConstOf();
2931
            else
2932 1
                t.next = next.wildConstOf();
2933
        }
2934
        //printf("TypeNext::makeWildConst() returns %p, %s\n", t, t.toChars());
2935 1
        return t;
2936
    }
2937

2938
    override final Type makeSharedWild()
2939
    {
2940
        //printf("TypeNext::makeSharedWild() %s\n", toChars());
2941 1
        if (mcache && mcache.swto)
2942
        {
2943 0
            assert(mcache.swto.isSharedWild());
2944 0
            return mcache.swto;
2945
        }
2946 1
        TypeNext t = cast(TypeNext)Type.makeSharedWild();
2947 1
        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())
2948
        {
2949 1
            if (next.isConst())
2950 1
                t.next = next.sharedWildConstOf();
2951
            else
2952 1
                t.next = next.sharedWildOf();
2953
        }
2954
        //printf("TypeNext::makeSharedWild() returns %p, %s\n", t, t.toChars());
2955 1
        return t;
2956
    }
2957

2958
    override final Type makeSharedWildConst()
2959
    {
2960
        //printf("TypeNext::makeSharedWildConst() %s\n", toChars());
2961 1
        if (mcache && mcache.swcto)
2962
        {
2963 0
            assert(mcache.swcto.mod == (MODFlags.shared_ | MODFlags.wildconst));
2964 0
            return mcache.swcto;
2965
        }
2966 1
        TypeNext t = cast(TypeNext)Type.makeSharedWildConst();
2967 1
        if (ty != Tfunction && next.ty != Tfunction && !next.isImmutable())
2968
        {
2969 1
            t.next = next.sharedWildConstOf();
2970
        }
2971
        //printf("TypeNext::makeSharedWildConst() returns %p, %s\n", t, t.toChars());
2972 1
        return t;
2973
    }
2974

2975
    override final Type makeMutable()
2976
    {
2977
        //printf("TypeNext::makeMutable() %p, %s\n", this, toChars());
2978 1
        TypeNext t = cast(TypeNext)Type.makeMutable();
2979 1
        if (ty == Tsarray)
2980
        {
2981 1
            t.next = next.mutableOf();
2982
        }
2983
        //printf("TypeNext::makeMutable() returns %p, %s\n", t, t.toChars());
2984 1
        return t;
2985
    }
2986

2987
    override MATCH constConv(Type to)
2988
    {
2989
        //printf("TypeNext::constConv from = %s, to = %s\n", toChars(), to.toChars());
2990 1
        if (equals(to))
2991 1
            return MATCH.exact;
2992

2993 1
        if (!(ty == to.ty && MODimplicitConv(mod, to.mod)))
2994 1
            return MATCH.nomatch;
2995

2996 1
        Type tn = to.nextOf();
2997