Mercurial > projects > ddmd
view dmd/Type.d @ 90:39648eb578f6
more Expressions work
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 30 Aug 2010 20:27:56 +0100 |
parents | b17640f0e4e8 |
children | 3a0b150c9841 ae5b11064a9a |
line wrap: on
line source
module dmd.Type; import dmd.TY; import dmd.Argument; import dmd.TOK; import dmd.STC; import dmd.TypeArray; import dmd.DotVarExp; import dmd.ErrorExp; import dmd.StringExp; import dmd.IntegerExp; import dmd.VarExp; import dmd.TemplateParameter; import dmd.TypeInfoSharedDeclaration; import dmd.TypeInfoConstDeclaration; import dmd.TypeInfoInvariantDeclaration; import dmd.Module; import dmd.Id; import dmd.Util; import dmd.VarDeclaration; import dmd.Loc; import dmd.Scope; import dmd.OutBuffer; import dmd.Identifier; import dmd.HdrGenState; import dmd.Expression; import dmd.Dsymbol; import dmd.MATCH; import dmd.TypeInfoDeclaration; import dmd.ClassDeclaration; import dmd.StringTable; import dmd.ArrayTypes; import dmd.TypeBasic; import dmd.DYNCAST; import dmd.MOD; import dmd.Lexer; import dmd.TypeSArray; import dmd.TypeDArray; import dmd.TypeAArray; import dmd.TypePointer; import dmd.TypeReference; import dmd.TypeFunction; import dmd.TypeDelegate; import dmd.TypeIdentifier; import dmd.TypeInstance; import dmd.TypeTypeof; import dmd.TypeReturn; import dmd.TypeStruct; import dmd.TypeEnum; import dmd.TypeTypedef; import dmd.TypeClass; import dmd.TypeTuple; import dmd.TypeSlice; import dmd.Global; import dmd.StringValue; import dmd.backend.Symbol; import dmd.backend.TYPE; import dmd.backend.dt_t; import dmd.backend.Util; import dmd.backend.TYM; import dmd.backend.mTY; import core.stdc.stdio; import core.memory; /* These have default values for 32 bit code, they get * adjusted for 64 bit code. */ int PTRSIZE = 4; int Tsize_t; int Tptrdiff_t; /* REALSIZE = size a real consumes in memory * REALPAD = 'padding' added to the CPU real size to bring it up to REALSIZE * REALALIGNSIZE = alignment for reals */ version (TARGET_OSX) { int REALSIZE = 16; int REALPAD = 6; int REALALIGNSIZE = 16; } else version (POSIX) { /// TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS int REALSIZE = 12; int REALPAD = 2; int REALALIGNSIZE = 4; } else { int REALSIZE = 10; int REALPAD = 0; int REALALIGNSIZE = 2; } /**** * Given an identifier, figure out which TemplateParameter it is. * Return -1 if not found. */ int templateIdentifierLookup(Identifier id, TemplateParameters parameters) { for (size_t i = 0; i < parameters.dim; i++) { TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; if (tp.ident.equals(id)) return i; } return -1; } int templateParameterLookup(Type tparam, TemplateParameters parameters) { assert(tparam.ty == Tident); TypeIdentifier tident = cast(TypeIdentifier)tparam; //printf("\ttident = '%s'\n", tident.toChars()); if (tident.idents.dim == 0) { return templateIdentifierLookup(tident.ident, parameters); } return -1; } class Type { TY ty; MOD mod; // modifiers MODxxxx /* pick this order of numbers so switch statements work better */ /// #define MODconst 1 // type is const /// #define MODinvariant 4 // type is invariant /// #define MODshared 2 // type is shared string deco; /* These are cached values that are lazily evaluated by constOf(), invariantOf(), etc. * They should not be referenced by anybody but mtype.c. * They can be null if not lazily evaluated yet. * Note that there is no "shared immutable", because that is just immutable */ Type cto; // MODconst ? mutable version of this type : const version Type ito; // MODinvariant ? mutable version of this type : invariant version Type sto; // MODshared ? mutable version of this type : shared mutable version Type scto; // MODshared|MODconst ? mutable version of this type : shared const version Type pto; // merged pointer to this type Type rto; // reference to this type Type arrayof; // array of this type TypeInfoDeclaration vtinfo; // TypeInfo object for this Type type* ctype; // for back end static ClassDeclaration typeinfo; static ClassDeclaration typeinfoclass; static ClassDeclaration typeinfointerface; static ClassDeclaration typeinfostruct; static ClassDeclaration typeinfotypedef; static ClassDeclaration typeinfopointer; static ClassDeclaration typeinfoarray; static ClassDeclaration typeinfostaticarray; static ClassDeclaration typeinfoassociativearray; static ClassDeclaration typeinfoenum; static ClassDeclaration typeinfofunction; static ClassDeclaration typeinfodelegate; static ClassDeclaration typeinfotypelist; static ClassDeclaration typeinfoconst; static ClassDeclaration typeinfoinvariant; static ClassDeclaration typeinfoshared; static Type basic[TY.TMAX]; static ubyte mangleChar[TY.TMAX]; static ubyte sizeTy[TY.TMAX]; static StringTable stringtable; // These tables are for implicit conversion of binary ops; // the indices are the type of operand one, followed by operand two. static ubyte impcnvResult[TY.TMAX][TY.TMAX] = [ [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,20,20,20,20,20,20,21,22,23,24,25,23,24,25,29,30,31,37,20,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,21,21,21,21,21,21,22,23,24,25,23,24,25,29,30,31,37,21,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,22,22,22,22,22,22,22,22,23,24,25,23,24,25,29,30,31,37,22,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,23,23,23,23,23,23,23,23,23,24,25,23,24,25,29,30,31,37,23,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,24,24,24,24,24,24,24,24,24,24,25,24,24,25,30,30,31,37,24,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,25,25,25,25,25,25,25,25,25,25,25,25,25,25,31,31,31,37,25,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,23,23,23,23,23,23,23,23,23,24,25,26,27,28,29,30,31,37,23,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,24,24,24,24,24,24,24,24,24,24,25,27,27,28,30,30,31,37,24,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,25,25,25,25,25,25,25,25,25,25,25,28,28,28,31,31,31,37,25,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,29,29,29,29,29,29,29,29,29,30,31,29,30,31,29,30,31,37,29,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,31,37,30,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,37,31,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,29,30,31,37,33,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], ]; static ubyte impcnvType1[TY.TMAX][TY.TMAX] = [ [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,23,24,25,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,23,24,25,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,23,24,25,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,23,24,25,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,23,24,25,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,20,20,20,20,20,20,21,22,23,24,25,23,24,25,23,24,25,37,20,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,21,21,21,21,21,21,22,23,24,25,23,24,25,23,24,25,37,21,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,22,22,22,22,22,22,22,22,23,24,25,23,24,25,23,24,25,37,22,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,23,23,23,23,23,23,23,23,23,24,25,23,24,25,23,24,25,37,23,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,24,24,24,24,24,24,24,24,24,24,25,24,24,25,24,24,25,37,24,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,37,25,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,26,26,26,26,26,26,26,26,26,27,28,26,27,28,26,27,28,37,26,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,27,27,27,27,27,27,27,27,27,27,28,27,27,28,27,27,28,37,27,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,37,28,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,29,29,29,29,29,29,29,29,29,30,31,29,30,31,29,30,31,37,29,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,31,37,30,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,37,31,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,23,24,25,23,24,25,37,33,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], ]; static ubyte impcnvType2[TY.TMAX][TY.TMAX] = [ [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,26,27,28,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,26,27,28,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,26,27,28,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,26,27,28,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,26,27,28,29,30,31,37,19,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,20,20,20,20,20,20,21,22,23,24,25,26,27,28,29,30,31,37,20,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,21,21,21,21,21,21,21,22,23,24,25,26,27,28,29,30,31,37,21,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,22,22,22,22,22,22,22,22,23,24,25,26,27,28,29,30,31,37,22,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,23,23,23,23,23,23,23,23,23,24,25,26,27,28,29,30,31,37,23,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,24,24,24,24,24,24,24,24,24,24,25,27,27,28,30,30,31,37,24,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,25,25,25,25,25,25,25,25,25,25,25,28,28,28,31,31,31,37,25,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,23,23,23,23,23,23,23,23,23,24,25,26,27,28,29,30,31,37,23,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,24,24,24,24,24,24,24,24,24,24,25,27,27,28,30,30,31,37,24,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,25,25,25,25,25,25,25,25,25,25,25,28,28,28,31,31,31,37,25,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,23,23,23,23,23,23,23,23,23,24,25,26,27,28,29,30,31,37,23,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,24,24,24,24,24,24,24,24,24,24,25,27,27,28,30,30,31,37,24,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,25,25,25,25,25,25,25,25,25,25,25,28,28,28,31,31,31,37,25,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,19,19,19,19,19,20,21,22,23,24,25,26,27,28,29,30,31,37,33,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], [37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37], ]; // If !=0, give warning on implicit conversion static const(bool) impcnvWarn[TY.TMAX][TY.TMAX] = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], ]; static this() { stringtable = new StringTable(); } static ~this() { delete stringtable; } this(TY ty) { this.ty = ty; } Type syntaxCopy() { assert(false); } bool equals(Object o) { Type t = cast(Type)o; //printf("Type.equals(%s, %s)\n", toChars(), t.toChars()); if (this is o || (t && deco == t.deco) && // deco strings are unique deco !is null) // and semantic() has been run { //printf("deco = '%s', t.deco = '%s'\n", deco, t.deco); return 1; } //if (deco && t && t.deco) printf("deco = '%s', t.deco = '%s'\n", deco, t.deco); return 0; } DYNCAST dyncast() { return DYNCAST.DYNCAST_TYPE; } // kludge for template.isType() /******************************* * Returns: * 0 types are distinct * 1 this is covariant with t * 2 arguments match as far as overloading goes, * but types are not covariant * 3 cannot determine covariance because of forward references */ int covariant(Type t) { static if (false) { printf("Type.covariant(t = %s) %s\n", t.toChars(), toChars()); printf("deco = %p, %p\n", deco, t.deco); // printf("ty = %d\n", next.ty); printf("mod = %x, %x\n", mod, t.mod); } int inoutmismatch = 0; TypeFunction t1; TypeFunction t2; if (equals(t)) return 1; // covariant if (ty != TY.Tfunction || t.ty != TY.Tfunction) goto Ldistinct; t1 = cast(TypeFunction)this; t2 = cast(TypeFunction)t; if (t1.varargs != t2.varargs) goto Ldistinct; if (t1.parameters && t2.parameters) { size_t dim = Argument.dim(t1.parameters); if (dim != Argument.dim(t2.parameters)) goto Ldistinct; for (size_t i = 0; i < dim; i++) { Argument arg1 = Argument.getNth(t1.parameters, i); Argument arg2 = Argument.getNth(t2.parameters, i); if (!arg1.type.equals(arg2.type)) { ///static if (false) { /// // turn on this for contravariant argument types, see bugzilla 3075 /// // We can add const, but not subtract it /// if (arg2.type.implicitConvTo(arg1.type) < MATCH.MATCHconst) ///} goto Ldistinct; } if ((arg1.storageClass & ~STC.STCscope) != (arg2.storageClass & ~STC.STCscope)) inoutmismatch = 1; // We can add scope, but not subtract it if (!(arg1.storageClass & STC.STCscope) && (arg2.storageClass & STC.STCscope)) inoutmismatch = 1; } } else if (t1.parameters != t2.parameters) goto Ldistinct; // The argument lists match if (inoutmismatch) goto Lnotcovariant; if (t1.linkage != t2.linkage) goto Lnotcovariant; { // Return types Type t1n = t1.next; Type t2n = t2.next; if (t1n is null || t2n is null) // happens with return type inference goto Lnotcovariant; if (t1n.equals(t2n)) goto Lcovariant; if (t1n.ty == TY.Tclass && t2n.ty == TY.Tclass) { /* If same class type, but t2n is const, then it's * covariant. Do this test first because it can work on * forward references. */ if ((cast(TypeClass)t1n).sym == (cast(TypeClass)t2n).sym && t2n.mod == MOD.MODconst) goto Lcovariant; // If t1n is forward referenced: ClassDeclaration cd = (cast(TypeClass)t1n).sym; if (!cd.baseClass && cd.baseclasses.dim && !cd.isInterfaceDeclaration()) { return 3; } } if (t1n.implicitConvTo(t2n)) goto Lcovariant; } goto Lnotcovariant; Lcovariant: /* Can convert mutable to const */ if (t1.mod != t2.mod) { if (!(t1.mod & MOD.MODconst) && (t2.mod & MOD.MODconst)) goto Lnotcovariant; if (!(t1.mod & MOD.MODshared) && (t2.mod & MOD.MODshared)) goto Lnotcovariant; } /* Can convert pure to impure, and nothrow to throw */ if (!t1.ispure && t2.ispure) goto Lnotcovariant; if (!t1.isnothrow && t2.isnothrow) goto Lnotcovariant; if (t1.isref != t2.isref) goto Lnotcovariant; //printf("\tcovaraint: 1\n"); return 1; Ldistinct: //printf("\tcovaraint: 0\n"); return 0; Lnotcovariant: //printf("\tcovaraint: 2\n"); return 2; } string toChars() { scope OutBuffer buf = new OutBuffer(); HdrGenState hgs; toCBuffer(buf, null, &hgs); return buf.toChars(); } static char needThisPrefix() { return 'M'; // name mangling prefix for functions needing 'this' } static void init() { Lexer.initKeywords(); for (int i = 0; i < TY.TMAX; i++) sizeTy[i] = TypeBasic.sizeof; sizeTy[TY.Tsarray] = TypeSArray.sizeof; sizeTy[TY.Tarray] = TypeDArray.sizeof; //sizeTy[TY.Tnarray] = TypeNArray.sizeof; sizeTy[TY.Taarray] = TypeAArray.sizeof; sizeTy[TY.Tpointer] = TypePointer.sizeof; sizeTy[TY.Treference] = TypeReference.sizeof; sizeTy[TY.Tfunction] = TypeFunction.sizeof; sizeTy[TY.Tdelegate] = TypeDelegate.sizeof; sizeTy[TY.Tident] = TypeIdentifier.sizeof; sizeTy[TY.Tinstance] = TypeInstance.sizeof; sizeTy[TY.Ttypeof] = TypeTypeof.sizeof; sizeTy[TY.Tenum] = TypeEnum.sizeof; sizeTy[TY.Ttypedef] = TypeTypedef.sizeof; sizeTy[TY.Tstruct] = TypeStruct.sizeof; sizeTy[TY.Tclass] = TypeClass.sizeof; sizeTy[TY.Ttuple] = TypeTuple.sizeof; sizeTy[TY.Tslice] = TypeSlice.sizeof; sizeTy[TY.Treturn] = TypeReturn.sizeof; mangleChar[TY.Tarray] = 'A'; mangleChar[TY.Tsarray] = 'G'; mangleChar[TY.Tnarray] = '@'; mangleChar[TY.Taarray] = 'H'; mangleChar[TY.Tpointer] = 'P'; mangleChar[TY.Treference] = 'R'; mangleChar[TY.Tfunction] = 'F'; mangleChar[TY.Tident] = 'I'; mangleChar[TY.Tclass] = 'C'; mangleChar[TY.Tstruct] = 'S'; mangleChar[TY.Tenum] = 'E'; mangleChar[TY.Ttypedef] = 'T'; mangleChar[TY.Tdelegate] = 'D'; mangleChar[TY.Tnone] = 'n'; mangleChar[TY.Tvoid] = 'v'; mangleChar[TY.Tint8] = 'g'; mangleChar[TY.Tuns8] = 'h'; mangleChar[TY.Tint16] = 's'; mangleChar[TY.Tuns16] = 't'; mangleChar[TY.Tint32] = 'i'; mangleChar[TY.Tuns32] = 'k'; mangleChar[TY.Tint64] = 'l'; mangleChar[TY.Tuns64] = 'm'; mangleChar[TY.Tfloat32] = 'f'; mangleChar[TY.Tfloat64] = 'd'; mangleChar[TY.Tfloat80] = 'e'; mangleChar[TY.Timaginary32] = 'o'; mangleChar[TY.Timaginary64] = 'p'; mangleChar[TY.Timaginary80] = 'j'; mangleChar[TY.Tcomplex32] = 'q'; mangleChar[TY.Tcomplex64] = 'r'; mangleChar[TY.Tcomplex80] = 'c'; mangleChar[TY.Tbool] = 'b'; mangleChar[TY.Tascii] = 'a'; mangleChar[TY.Twchar] = 'u'; mangleChar[TY.Tdchar] = 'w'; mangleChar[TY.Tbit] = '@'; mangleChar[TY.Tinstance] = '@'; mangleChar[TY.Terror] = '@'; mangleChar[TY.Ttypeof] = '@'; mangleChar[TY.Ttuple] = 'B'; mangleChar[TY.Tslice] = '@'; mangleChar[TY.Treturn] = '@'; debug { for (int i = 0; i < TY.TMAX; i++) { if (!mangleChar[i]) { writef("ty = %d\n", i); } assert(mangleChar[i]); } } // Set basic types static TY[] basetab = [ TY.Tvoid, TY.Tint8, TY.Tuns8, TY.Tint16, TY.Tuns16, TY.Tint32, TY.Tuns32, TY.Tint64, TY.Tuns64, TY.Tfloat32, TY.Tfloat64, TY.Tfloat80, TY.Timaginary32, TY.Timaginary64, TY.Timaginary80, TY.Tcomplex32, TY.Tcomplex64, TY.Tcomplex80, TY.Tbool, TY.Tascii, TY.Twchar, TY.Tdchar ]; foreach (bt; basetab) { Type t = new TypeBasic(bt); t = t.merge(); basic[bt] = t; } basic[TY.Terror] = basic[TY.Tint32]; tvoidptr = tvoid.pointerTo(); if (global.params.isX86_64) { PTRSIZE = 8; if (global.params.isLinux || global.params.isFreeBSD || global.params.isSolaris) REALSIZE = 10; else REALSIZE = 8; Tsize_t = TY.Tuns64; Tptrdiff_t = TY.Tint64; } else { PTRSIZE = 4; version (TARGET_OSX) { REALSIZE = 16; REALPAD = 6; } else version (XXX) { //#elif TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS REALSIZE = 12; REALPAD = 2; } else { REALSIZE = 10; REALPAD = 0; } Tsize_t = TY.Tuns32; Tptrdiff_t = TY.Tint32; } } ulong size() { return size(Loc(0)); } ulong size(Loc loc) { error(loc, "no size for type %s", toChars()); return 1; } uint alignsize() { return cast(uint)size(Loc(0)); /// } Type semantic(Loc loc, Scope sc) { return merge(); } Type trySemantic(Loc loc, Scope sc) { uint errors = global.errors; global.gag++; // suppress printing of error messages Type t = semantic(loc, sc); global.gag--; if (errors != global.errors) // if any errors happened { global.errors = errors; t = null; } return t; } /******************************** * Name mangling. * Input: * flag 0x100 do not do const/invariant */ void toDecoBuffer(OutBuffer buf, int flag = 0) { if (flag != mod && flag != 0x100) { if (mod & MOD.MODshared) buf.writeByte('O'); if (mod & MOD.MODconst) buf.writeByte('x'); else if (mod & MOD.MODinvariant) buf.writeByte('y'); // Cannot be both const and invariant assert((mod & (MOD.MODconst | MOD.MODinvariant)) != (MOD.MODconst | MOD.MODinvariant)); } buf.writeByte(mangleChar[ty]); } Type merge() { Type t = this; assert(t); //printf("merge(%s)\n", toChars()); if (deco is null) { OutBuffer buf = new OutBuffer(); //if (next) //next = next.merge(); toDecoBuffer(buf); StringValue* sv = stringtable.update(buf.extractString()); if (sv.ptrvalue) { t = cast(Type) sv.ptrvalue; debug { if (!t.deco) writef("t = %s\n", t.toChars()); } assert(t.deco); //printf("old value, deco = '%s' %p\n", t.deco, t.deco); } else { sv.ptrvalue = cast(void*)this; deco = sv.lstring.string_; //printf("new value, deco = '%s' %p\n", t.deco, t.deco); } } return t; } /************************************* * This version does a merge even if the deco is already computed. * Necessary for types that have a deco, but are not merged. */ Type merge2() { //printf("merge2(%s)\n", toChars()); Type t = this; assert(t); if (!t.deco) return t.merge(); StringValue* sv = stringtable.lookup(t.deco); if (sv && sv.ptrvalue) { t = cast(Type)sv.ptrvalue; assert(t.deco); } else assert(0); return t; } void toCBuffer(OutBuffer buf, Identifier ident, HdrGenState* hgs) { toCBuffer2(buf, hgs, MOD.MODundefined); if (ident) { buf.writeByte(' '); buf.writestring(ident.toChars()); } } void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { toCBuffer3(buf, hgs, mod); return; } buf.writestring(toChars()); } void toCBuffer3(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { string p; if (this.mod & MOD.MODshared) buf.writestring("shared("); switch (this.mod & (MOD.MODconst | MOD.MODinvariant)) { case MOD.MODundefined: toCBuffer2(buf, hgs, this.mod); break; case MOD.MODconst: p = "const("; goto L1; case MOD.MODinvariant: p = "immutable("; L1: buf.writestring(p); toCBuffer2(buf, hgs, this.mod); buf.writeByte(')'); break; } if (this.mod & MOD.MODshared) buf.writeByte(')'); } } void modToBuffer(OutBuffer buf) { if (mod & MOD.MODshared) buf.writestring(" shared"); if (mod & MOD.MODconst) buf.writestring(" const"); if (mod & MOD.MODinvariant) buf.writestring(" immutable"); } version (CPP_MANGLE) { void toCppMangle(OutBuffer buf, CppMangleState* cms) { assert(false); } } bool isintegral() { return false; } bool isfloating() // real, imaginary, or complex { return false; } bool isreal() { return false; } bool isimaginary() { return false; } bool iscomplex() { return false; } bool isscalar() { return false; } bool isunsigned() { return false; } bool isauto() { return false; } bool isString() { return false; } /************************** * Given: * T a, b; * Can we assign: * a = b; * ? */ bool isAssignable() { return true; } bool checkBoolean() // if can be converted to boolean value { return isscalar(); } /********************************* * Check type to see if it is based on a deprecated symbol. */ void checkDeprecated(Loc loc, Scope sc) { Dsymbol s = toDsymbol(sc); if (s) s.checkDeprecated(loc, sc); } bool isConst() { return (mod & MOD.MODconst) != 0; } int isInvariant() { return mod & MOD.MODinvariant; } int isMutable() { return !(mod & (MOD.MODconst | MOD.MODinvariant)); } int isShared() { return mod & MOD.MODshared; } int isSharedConst() { return mod == (MOD.MODshared | MOD.MODconst); } /******************************** * Convert to 'const'. */ Type constOf() { static if (false) { //printf("Type.constOf() %p %s\n", this, toChars()); if (isConst()) return this; if (cto) return cto; Type t = makeConst(); t = t.merge(); cto = t; if (ito) ito.cto = t; //if (t.nextOf()) assert(t.nextOf().isConst()); //printf("-Type.constOf() %p %s\n", t, toChars()); return t; } else { //printf("Type.constOf() %p %s\n", this, toChars()); if (mod == MOD.MODconst) return this; if (cto) { assert(cto.mod == MOD.MODconst); return cto; } Type t = makeConst(); t = t.merge(); t.fixTo(this); //printf("-Type.constOf() %p %s\n", t, toChars()); return t; } } /******************************** * Convert to 'immutable'. */ Type invariantOf() { static if (false) { //printf("Type.invariantOf() %p %s\n", this, toChars()); if (isInvariant()) { return this; } if (ito) { //if (!ito.isInvariant()) printf("\tito is %p %s\n", ito, ito.toChars()); assert(ito.isInvariant()); return ito; } Type t = makeInvariant(); t = t.merge(); ito = t; if (cto) cto.ito = t; static if (false) {// fails for function types if (t.nextOf() && !t.nextOf().isInvariant()) { assert(0); } } //printf("\t%p\n", t); return t; } else { //printf("Type.invariantOf() %p %s\n", this, toChars()); if (isInvariant()) { return this; } if (ito) { assert(ito.isInvariant()); return ito; } Type t = makeInvariant(); t = t.merge(); t.fixTo(this); //printf("\t%p\n", t); return t; } } Type mutableOf() { static if (false) { //printf("Type.mutableOf() %p, %s\n", this, toChars()); Type t = this; if (isConst()) { t = cto; assert(!t || t.isMutable()); } else if (isInvariant()) { t = ito; assert(!t || t.isMutable()); } if (!t) { uint sz = this.classinfo.init.length; t = cast(Type)GC.malloc(sz); memcpy(cast(void*)t, cast(void*)this, sz); t.mod = 0; t.deco = null; t.arrayof = null; t.pto = null; t.rto = null; t.cto = null; t.ito = null; t.sto = null; t.scto = null; t.vtinfo = null; if (ty == Tsarray) { TypeSArray ta = cast(TypeSArray)t; //ta.next = ta.next.mutableOf(); } t = t.merge(); if (isConst()) { cto = t; t.cto = this; if (ito) ito.cto = this; } else if (isInvariant()) { ito = t; t.ito = this; if (cto) cto.ito = this; } } return t; } else { //printf("Type.mutableOf() %p, %s\n", this, toChars()); Type t = this; if (isConst()) { if (isShared()) t = sto; // shared const => shared else t = cto; assert(!t || t.isMutable()); } else if (isInvariant()) { t = ito; assert(!t || (t.isMutable() && !t.isShared())); } if (!t) { uint sz = this.classinfo.init.length; t = cast(Type)GC.malloc(sz); memcpy(cast(void*)t, cast(void*)this, sz); t.mod = MODundefined; t.deco = null; t.arrayof = null; t.pto = null; t.rto = null; t.cto = null; t.ito = null; t.sto = null; t.scto = null; t.vtinfo = null; t = t.merge(); t.fixTo(this); switch (mod) { case MODconst: t.cto = this; break; case MODinvariant: t.ito = this; break; case MODshared: t.sto = this; break; case MODshared | MODconst: t.scto = this; break; default: assert(0); } } return t; } } Type sharedOf() { //printf("Type.sharedOf() %p, %s\n", this, toChars()); if (mod == MOD.MODshared) { return this; } if (sto) { assert(sto.isShared()); return sto; } Type t = makeShared(); t = t.merge(); t.fixTo(this); //printf("\t%p\n", t); return t; } Type sharedConstOf() { //printf("Type.sharedConstOf() %p, %s\n", this, toChars()); if (mod == (MODshared | MODconst)) { return this; } if (scto) { assert(scto.mod == (MODshared | MODconst)); return scto; } Type t = makeSharedConst(); t = t.merge(); t.fixTo(this); //printf("\t%p\n", t); return t; } static uint X(MOD m, MOD n) { return (((m) << 3) | (n)); } /********************************** * For our new type 'this', which is type-constructed from t, * fill in the cto, ito, sto, scto shortcuts. */ void fixTo(Type t) { ito = t.ito; static if (false) { /* Cannot do these because these are not fully transitive: * there can be a shared ptr to immutable, for example. * Immutable subtypes are always immutable, though. */ cto = t.cto; sto = t.sto; scto = t.scto; } assert(mod != t.mod); switch (X(mod, t.mod)) { case X(MOD.MODundefined, MOD.MODconst): cto = t; break; case X(MOD.MODundefined, MOD.MODinvariant): ito = t; break; case X(MOD.MODundefined, MOD.MODshared): sto = t; break; case X(MOD.MODundefined, MOD.MODshared | MOD.MODconst): scto = t; break; case X(MOD.MODconst, MOD.MODundefined): cto = null; goto L2; case X(MOD.MODconst, MOD.MODinvariant): ito = t; goto L2; case X(MOD.MODconst, MOD.MODshared): sto = t; goto L2; case X(MOD.MODconst, MOD.MODshared | MOD.MODconst): scto = t; L2: t.cto = this; break; case X(MOD.MODinvariant, MOD.MODundefined): ito = null; goto L3; case X(MOD.MODinvariant, MOD.MODconst): cto = t; goto L3; case X(MOD.MODinvariant, MOD.MODshared): sto = t; goto L3; case X(MOD.MODinvariant, MOD.MODshared | MOD.MODconst): scto = t; L3: t.ito = this; if (t.cto) t.cto.ito = this; if (t.sto) t.sto.ito = this; if (t.scto) t.scto.ito = this; break; case X(MOD.MODshared, MOD.MODundefined): sto = null; goto L4; case X(MOD.MODshared, MOD.MODconst): cto = t; goto L4; case X(MOD.MODshared, MOD.MODinvariant): ito = t; goto L4; case X(MOD.MODshared, MOD.MODshared | MOD.MODconst): scto = t; L4: t.sto = this; break; case X(MOD.MODshared | MOD.MODconst, MOD.MODundefined): scto = null; break; case X(MOD.MODshared | MOD.MODconst, MOD.MODconst): cto = t; break; case X(MOD.MODshared | MOD.MODconst, MOD.MODinvariant): ito = t; break; case X(MOD.MODshared | MOD.MODconst, MOD.MODshared): sto = t; L5: t.scto = this; break; } check(); t.check(); //printf("fixTo: %s, %s\n", toChars(), t.toChars()); } /*************************** * Look for bugs in constructing types. */ void check() { switch (mod) { case MOD.MODundefined: if (cto) assert(cto.mod == MOD.MODconst); if (ito) assert(ito.mod == MOD.MODinvariant); if (sto) assert(sto.mod == MOD.MODshared); if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); break; case MOD.MODconst: if (cto) assert(cto.mod == MOD.MODundefined); if (ito) assert(ito.mod == MOD.MODinvariant); if (sto) assert(sto.mod == MOD.MODshared); if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); break; case MOD.MODinvariant: if (cto) assert(cto.mod == MOD.MODconst); if (ito) assert(ito.mod == MOD.MODundefined); if (sto) assert(sto.mod == MOD.MODshared); if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); break; case MOD.MODshared: if (cto) assert(cto.mod == MOD.MODconst); if (ito) assert(ito.mod == MOD.MODinvariant); if (sto) assert(sto.mod == MOD.MODundefined); if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); break; case MOD.MODshared | MOD.MODconst: if (cto) assert(cto.mod == MOD.MODconst); if (ito) assert(ito.mod == MOD.MODinvariant); if (sto) assert(sto.mod == MOD.MODshared); if (scto) assert(scto.mod == MOD.MODundefined); break; } Type tn = nextOf(); if (tn && ty != TY.Tfunction && ty != TY.Tdelegate) { // Verify transitivity switch (mod) { case MOD.MODundefined: break; case MOD.MODconst: assert(tn.mod & MOD.MODinvariant || tn.mod & MOD.MODconst); break; case MOD.MODinvariant: assert(tn.mod == MOD.MODinvariant); break; case MOD.MODshared: assert(tn.mod & MOD.MODinvariant || tn.mod & MOD.MODshared); break; case MOD.MODshared | MOD.MODconst: assert(tn.mod & MOD.MODinvariant || tn.mod & (MOD.MODshared | MOD.MODconst)); break; } tn.check(); } } /************************************ * Apply MODxxxx bits to existing type. */ Type castMod(uint mod) { Type t; switch (mod) { case 0: t = mutableOf(); break; case MODconst: t = constOf(); break; case MODinvariant: t = invariantOf(); break; case MODshared: t = sharedOf(); break; case MODshared | MODconst: t = sharedConstOf(); break; default: assert(0); } return t; } /************************************ * Add MODxxxx bits to existing type. * We're adding, not replacing, so adding const to * a shared type => "shared const" */ Type addMod(MOD mod) { Type t = this; /* Add anything to immutable, and it remains immutable */ if (!t.isInvariant()) { switch (mod) { case MOD.MODundefined: break; case MOD.MODconst: if (isShared()) t = sharedConstOf(); else t = constOf(); break; case MOD.MODinvariant: t = invariantOf(); break; case MOD.MODshared: if (isConst()) t = sharedConstOf(); else t = sharedOf(); break; case MOD.MODshared | MOD.MODconst: t = sharedConstOf(); break; } } return t; } Type addStorageClass(STC stc) { /* Just translate to MOD bits and let addMod() do the work */ MOD mod = MOD.MODundefined; if (stc & STC.STCimmutable) mod = MOD.MODinvariant; else { if (stc & (STC.STCconst | STC.STCin)) mod = MOD.MODconst; if (stc & STC.STCshared) mod |= MOD.MODshared; } return addMod(mod); } Type pointerTo() { if (pto is null) { Type t = new TypePointer(this); pto = t.merge(); } return pto; } Type referenceTo() { assert(false); } version (DumbClone) { final Type clone() { auto size = this.classinfo.init.length; auto ptr = GC.malloc(size); memcpy(ptr, cast(void*)this, size); return cast(Type)ptr; } } else { final Type cloneTo(Type t) { t.ctype = ctype; return t; } Type clone() { assert(this.classinfo is Type.classinfo); return cloneTo(new Type(ty)); } } Type arrayOf() { if (!arrayof) { Type t = new TypeDArray(this); arrayof = t.merge(); } return arrayof; } Type makeConst() { //printf("Type.makeConst() %p, %s\n", this, toChars()); if (cto) return cto; Type t = clone(); t.mod = MOD.MODconst; t.deco = null; t.arrayof = null; t.pto = null; t.rto = null; t.cto = null; t.ito = null; t.sto = null; t.scto = null; t.vtinfo = null; //printf("-Type.makeConst() %p, %s\n", t, toChars()); return t; } Type makeInvariant() { if (ito) { return ito; } Type t = clone(); t.mod = MOD.MODinvariant; t.deco = null; t.arrayof = null; t.pto = null; t.rto = null; t.cto = null; t.ito = null; t.sto = null; t.scto = null; t.vtinfo = null; return t; } Type makeShared() { if (sto) return sto; Type t = clone(); t.mod = MOD.MODshared; t.deco = null; t.arrayof = null; t.pto = null; t.rto = null; t.cto = null; t.ito = null; t.sto = null; t.scto = null; t.vtinfo = null; return t; } Type makeSharedConst() { if (scto) return scto; Type t = clone(); t.mod = MODshared | MODconst; t.deco = null; t.arrayof = null; t.pto = null; t.rto = null; t.cto = null; t.ito = null; t.sto = null; t.scto = null; t.vtinfo = null; return t; } Dsymbol toDsymbol(Scope sc) { return null; } /******************************* * If this is a shell around another type, * get that other type. */ Type toBasetype() { return this; } /************************** * Return type with the top level of it being mutable. */ Type toHeadMutable() { if (!mod) return this; return mutableOf(); } bool isBaseOf(Type t, int* poffset) { return false; // assume not } /******************************* * Determine if converting 'this' to 'to' is an identity operation, * a conversion to const operation, or the types aren't the same. * Returns: * MATCHequal 'this' == 'to' * MATCHconst 'to' is const * MATCHnomatch conversion to mutable or invariant */ MATCH constConv(Type to) { if (equals(to)) return MATCH.MATCHexact; if (ty == to.ty && to.mod == MOD.MODconst) return MATCH.MATCHconst; return MATCH.MATCHnomatch; } /******************************** * Determine if 'this' can be implicitly converted * to type 'to'. * Returns: * MATCHnomatch, MATCHconvert, MATCHconst, MATCHexact */ MATCH implicitConvTo(Type to) { //printf("Type.implicitConvTo(this=%p, to=%p)\n", this, to); //printf("from: %s\n", toChars()); //printf("to : %s\n", to.toChars()); if (this is to) return MATCHexact; return MATCHnomatch; } ClassDeclaration isClassHandle() { return null; } Expression getProperty(Loc loc, Identifier ident) { Expression e; version (LOGDOTEXP) { printf("Type.getProperty(type = '%s', ident = '%s')\n", toChars(), ident.toChars()); } if (ident == Id.__sizeof) { e = new IntegerExp(loc, size(loc), Type.tsize_t); } else if (ident == Id.size) { error(loc, ".size property should be replaced with .sizeof"); e = new ErrorExp(); } else if (ident is Id.alignof_) { e = new IntegerExp(loc, alignsize(), Type.tsize_t); } else if (ident == Id.typeinfo_) { if (!global.params.useDeprecated) error(loc, ".typeinfo deprecated, use typeid(type)"); e = getTypeInfo(null); } else if (ident == Id.init_) { if (ty == TY.Tvoid) error(loc, "void does not have an initializer"); e = defaultInit(loc); } else if (ident is Id.mangleof_) { string s; if (!deco) { s = toChars(); error(loc, "forward reference of type %s.mangleof", s); } else { s = deco; } e = new StringExp(loc, s, 'c'); scope Scope sc = new Scope(); e = e.semantic(sc); } else if (ident is Id.stringof_) { string s = toChars(); e = new StringExp(loc, s, 'c'); scope Scope sc = new Scope(); e = e.semantic(sc); } else { error(loc, "no property '%s' for type '%s'", ident.toChars(), toChars()); e = new ErrorExp(); } return e; } Expression dotExp(Scope sc, Expression e, Identifier ident) { VarDeclaration v = null; version (LOGDOTEXP) { printf("Type.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); } if (e.op == TOK.TOKdotvar) { DotVarExp dv = cast(DotVarExp)e; v = dv.var.isVarDeclaration(); } else if (e.op == TOK.TOKvar) { VarExp ve = cast(VarExp)e; v = ve.var.isVarDeclaration(); } if (v) { if (ident is Id.offset) { if (!global.params.useDeprecated) error(e.loc, ".offset deprecated, use .offsetof"); goto Loffset; } else if (ident is Id.offsetof) { Loffset: if (v.storage_class & STC.STCfield) { e = new IntegerExp(e.loc, v.offset, Type.tsize_t); return e; } } else if (ident is Id.init_) { static if (false) { if (v.init) { if (v.init.isVoidInitializer()) error(e.loc, "%s.init is void", v.toChars()); else { Loc loc = e.loc; e = v.init.toExpression(); if (e.op == TOK.TOKassign || e.op == TOK.TOKconstruct || e.op == TOK.TOKblit) { e = (cast(AssignExp)e).e2; /* Take care of case where we used a 0 * to initialize the struct. */ if (e.type == Type.tint32 && e.isBool(0) && v.type.toBasetype().ty == TY.Tstruct) { e = v.type.defaultInit(e.loc); } } e = e.optimize(WANTvalue | WANTinterpret); // if (!e.isConst()) // error(loc, ".init cannot be evaluated at compile time"); } return e; } } Expression ex = defaultInit(e.loc); return ex; } } if (ident is Id.typeinfo_) { if (!global.params.useDeprecated) error(e.loc, ".typeinfo deprecated, use typeid(type)"); e = getTypeInfo(sc); return e; } if (ident is Id.stringof_) { string s = e.toChars(); e = new StringExp(e.loc, s, 'c'); scope Scope sc2 = new Scope(); /// e = e.semantic(sc2); return e; } return getProperty(e.loc, ident); } uint memalign(uint salign) { return salign; } ///Expression defaultInit(Loc loc = Loc(0)) Expression defaultInit(Loc loc) { assert(false); } ///bool isZeroInit(Loc loc = Loc(0)) // if initializer is 0 bool isZeroInit(Loc loc) // if initializer is 0 { assert(false); } dt_t** toDt(dt_t** pdt) { //printf("Type.toDt()\n"); Expression e = defaultInit(Loc(0)); return e.toDt(pdt); } Identifier getTypeInfoIdent(int internal) { // _init_10TypeInfo_%s scope OutBuffer buf = new OutBuffer(); Identifier id; char* name; int len; if (internal) { buf.writeByte(mangleChar[ty]); if (ty == TY.Tarray) buf.writeByte(mangleChar[(cast(TypeArray)this).next.ty]); } else toDecoBuffer(buf); len = buf.offset; version (Bug4054) name = cast(char*)GC.malloc(19 + len.sizeof * 3 + len + 1); else name = cast(char*)alloca(19 + len.sizeof * 3 + len + 1); buf.writeByte(0); version (TARGET_OSX) { // The LINKc will prepend the _ len = sprintf(name, "D%dTypeInfo_%s6__initZ".ptr, 9 + len, buf.data); } else { len = sprintf(name, "_D%dTypeInfo_%s6__initZ".ptr, 9 + len, buf.data); } if (global.params.isWindows) name++; // C mangling will add it back in //printf("name = %s\n", name); id = Lexer.idPool(name[0..len-1].idup); return id; } /* These form the heart of template argument deduction. * Given 'this' being the type argument to the template instance, * it is matched against the template declaration parameter specialization * 'tparam' to determine the type to be used for the parameter. * Example: * template Foo(T:T*) // template declaration * Foo!(int*) // template instantiation * Input: * this = int* * tparam = T * parameters = [ T:T* ] // Array of TemplateParameter's * Output: * dedtypes = [ int ] // Array of Expression/Type's */ MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { static if (false) { printf("Type.deduceType()\n"); printf("\tthis = %d, ", ty); print(); printf("\ttparam = %d, ", tparam.ty); tparam.print(); } if (!tparam) goto Lnomatch; if (this == tparam) goto Lexact; if (tparam.ty == Tident) { // Determine which parameter tparam is int i = templateParameterLookup(tparam, parameters); if (i == -1) { if (!sc) goto Lnomatch; /* Need a loc to go with the semantic routine. */ Loc loc; if (parameters.dim) { TemplateParameter tp = cast(TemplateParameter)parameters.data[0]; loc = tp.loc; } /* BUG: what if tparam is a template instance, that * has as an argument another Tident? */ tparam = tparam.semantic(loc, sc); assert(tparam.ty != Tident); return deduceType(sc, tparam, parameters, dedtypes); } TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; // Found the corresponding parameter tp if (!tp.isTemplateTypeParameter()) goto Lnomatch; Type tt = this; Type at = cast(Type)dedtypes.data[i]; // 3*3 == 9 cases if (tparam.isMutable()) { // foo(U:U) T => T // foo(U:U) const(T) => const(T) // foo(U:U) invariant(T) => invariant(T) if (!at) { dedtypes.data[i] = cast(void*)this; goto Lexact; } } else if (mod == tparam.mod) { // foo(U:const(U)) const(T) => T // foo(U:invariant(U)) invariant(T) => T tt = mutableOf(); if (!at) { dedtypes.data[i] = cast(void*)tt; goto Lexact; } } else if (tparam.isConst()) { // foo(U:const(U)) T => T // foo(U:const(U)) invariant(T) => T tt = mutableOf(); if (!at) { dedtypes.data[i] = cast(void*)tt; goto Lconst; } } else { // foo(U:invariant(U)) T => nomatch // foo(U:invariant(U)) const(T) => nomatch if (!at) goto Lnomatch; } if (tt.equals(at)) goto Lexact; else if (tt.ty == Tclass && at.ty == Tclass) { return tt.implicitConvTo(at); } else if (tt.ty == Tsarray && at.ty == Tarray && tt.nextOf().implicitConvTo(at.nextOf()) >= MATCHconst) { goto Lexact; } else goto Lnomatch; } if (ty != tparam.ty) return implicitConvTo(tparam); // goto Lnomatch; if (nextOf()) return nextOf().deduceType(sc, tparam.nextOf(), parameters, dedtypes); Lexact: return MATCHexact; Lnomatch: return MATCHnomatch; version (DMDV2) { Lconst: return MATCHconst; } } void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { //printf("Type.resolve() %s, %d\n", toChars(), ty); Type t = semantic(loc, sc); *pt = t; *pe = null; *ps = null; } /******************************************* * Get a canonicalized form of the TypeInfo for use with the internal * runtime library routines. Canonicalized in that static arrays are * represented as dynamic arrays, enums are represented by their * underlying type, etc. This reduces the number of TypeInfo's needed, * so we can use the custom internal ones more. */ Expression getInternalTypeInfo(Scope sc) { TypeInfoDeclaration tid; Expression e; Type t; static TypeInfoDeclaration internalTI[TMAX]; //printf("Type.getInternalTypeInfo() %s\n", toChars()); t = toBasetype(); switch (t.ty) { case Tsarray: static if (false) { // convert to corresponding dynamic array type t = t.nextOf().mutableOf().arrayOf(); } break; case Tclass: if ((cast(TypeClass)t).sym.isInterfaceDeclaration()) break; goto Linternal; case Tarray: // convert to corresponding dynamic array type t = t.nextOf().mutableOf().arrayOf(); if (t.nextOf().ty != Tclass) break; goto Linternal; case Tfunction: case Tdelegate: case Tpointer: Linternal: tid = internalTI[t.ty]; if (!tid) { tid = new TypeInfoDeclaration(t, 1); internalTI[t.ty] = tid; } e = new VarExp(Loc(0), tid); e = e.addressOf(sc); e.type = tid.type; // do this so we don't get redundant dereference return e; default: break; } //printf("\tcalling getTypeInfo() %s\n", t.toChars()); return t.getTypeInfo(sc); } /**************************************************** * Get the exact TypeInfo. */ Expression getTypeInfo(Scope sc) { Expression e; Type t; //printf("Type.getTypeInfo() %p, %s\n", this, toChars()); t = merge2(); // do this since not all Type's are merge'd if (!t.vtinfo) { version (DMDV2) { if (t.isShared()) // does both 'shared' and 'shared const' t.vtinfo = new TypeInfoSharedDeclaration(t); else if (t.isConst()) t.vtinfo = new TypeInfoConstDeclaration(t); else if (t.isInvariant()) t.vtinfo = new TypeInfoInvariantDeclaration(t); else t.vtinfo = t.getTypeInfoDeclaration(); } else { t.vtinfo = t.getTypeInfoDeclaration(); } assert(t.vtinfo); vtinfo = t.vtinfo; /* If this has a custom implementation in std/typeinfo, then * do not generate a COMDAT for it. */ if (!t.builtinTypeInfo()) { // Generate COMDAT if (sc) // if in semantic() pass { // Find module that will go all the way to an object file Module m = sc.module_.importedFrom; m.members.push(t.vtinfo); } else // if in obj generation pass { t.vtinfo.toObjFile(global.params.multiobj); } } } e = new VarExp(Loc(0), t.vtinfo); e = e.addressOf(sc); e.type = t.vtinfo.type; // do this so we don't get redundant dereference return e; } TypeInfoDeclaration getTypeInfoDeclaration() { //printf("Type.getTypeInfoDeclaration() %s\n", toChars()); return new TypeInfoDeclaration(this, 0); } /* These decide if there's an instance for them already in std.typeinfo, * because then the compiler doesn't need to build one. */ bool builtinTypeInfo() { return false; } /******************************* * If one of the subtypes of this type is a TypeIdentifier, * i.e. it's an unresolved type, return that type. */ Type reliesOnTident() { return null; } Expression toExpression() { assert(false); } /*************************************** * Return true if type has pointers that need to * be scanned by the GC during a collection cycle. */ bool hasPointers() { return false; } /************************************* * If this is a type of something, return that something. */ Type nextOf() { return null; } /**************************************** * Return the mask that an integral type will * fit into. */ ulong sizemask() { ulong m; switch (toBasetype().ty) { case Tbool: m = 1; break; case Tchar: case Tint8: case Tuns8: m = 0xFF; break; case Twchar: case Tint16: case Tuns16: m = 0xFFFFUL; break; case Tdchar: case Tint32: case Tuns32: m = 0xFFFFFFFFUL; break; case Tint64: case Tuns64: m = 0xFFFFFFFFFFFFFFFFUL; break; default: assert(0); } return m; } static void error(T...)(Loc loc, string format, T t) { .error(loc, format, t); } static void warning(T...)(Loc loc, string format, T t) { assert(false); } // For backend /***************************** * Return back end type corresponding to D front end type. */ TYM totym() { TYM t; switch (ty) { case TY.Tvoid: t = TYM.TYvoid; break; case TY.Tint8: t = TYM.TYschar; break; case TY.Tuns8: t = TYM.TYuchar; break; case TY.Tint16: t = TYM.TYshort; break; case TY.Tuns16: t = TYM.TYushort; break; case TY.Tint32: t = TYM.TYint; break; case TY.Tuns32: t = TYM.TYuint; break; case TY.Tint64: t = TYM.TYllong; break; case TY.Tuns64: t = TYM.TYullong; break; case TY.Tfloat32: t = TYM.TYfloat; break; case TY.Tfloat64: t = TYM.TYdouble; break; case TY.Tfloat80: t = TYM.TYldouble; break; case TY.Timaginary32: t = TYM.TYifloat; break; case TY.Timaginary64: t = TYM.TYidouble; break; case TY.Timaginary80: t = TYM.TYildouble; break; case TY.Tcomplex32: t = TYM.TYcfloat; break; case TY.Tcomplex64: t = TYM.TYcdouble; break; case TY.Tcomplex80: t = TYM.TYcldouble; break; //case Tbit: t = TYM.TYuchar; break; case TY.Tbool: t = TYM.TYbool; break; case TY.Tchar: t = TYM.TYchar; break; version (XXX) { ///TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS case TY.Twchar: t = TYM.TYwchar_t; break; case TY.Tdchar: t = TYM.TYdchar; break; } else { case TY.Twchar: t = TYM.TYwchar_t; break; case TY.Tdchar: t = (global.params.symdebug == 1) ? TYM.TYdchar : TYM.TYulong; break; } case TY.Taarray: t = TYM.TYaarray; break; case TY.Tclass: case TY.Treference: case TY.Tpointer: t = TYM.TYnptr; break; case TY.Tdelegate: t = TYM.TYdelegate; break; case TY.Tarray: t = TYM.TYdarray; break; case TY.Tsarray: t = TYM.TYarray; break; case TY.Tstruct: t = TYM.TYstruct; break; case TY.Tenum: case TY.Ttypedef: t = toBasetype().totym(); break; case TY.Tident: case TY.Ttypeof: debug { writef("ty = %d, '%s'\n", ty, toChars()); } error (Loc(0), "forward reference of %s", toChars()); t = TYM.TYint; break; default: debug { writef("ty = %d, '%s'\n", ty, toChars()); } assert(0); } version (DMDV2) { // Add modifiers switch (mod) { case MOD.MODundefined: break; case MOD.MODconst: t |= mTY.mTYconst; break; case MOD.MODinvariant: t |= mTY.mTYimmutable; break; case MOD.MODshared: t |= mTY.mTYshared; break; case MOD.MODshared | MOD.MODconst: t |= mTY.mTYshared | mTY.mTYconst; break; default: assert(0); } } return t; } /*************************************** * Convert from D type to C type. * This is done so C debug info can be generated. */ type* toCtype() { if (!ctype) { ctype = type_fake(totym()); ctype.Tcount++; } return ctype; } type* toCParamtype() { return toCtype(); } Symbol* toSymbol() { assert(false); } // For eliminating dynamic_cast TypeBasic isTypeBasic() { return null; } static Type tvoid() { return basic[TY.Tvoid]; } static Type tint8() { return basic[TY.Tint8]; } static Type tuns8() { return basic[TY.Tuns8]; } static Type tint16() { return basic[TY.Tint16]; } static Type tuns16() { return basic[TY.Tuns16]; } static Type tint32() { return basic[TY.Tint32]; } static Type tuns32() { return basic[TY.Tuns32]; } static Type tint64() { return basic[TY.Tint64]; } static Type tuns64() { return basic[TY.Tuns64]; } static Type tfloat32() { return basic[TY.Tfloat32]; } static Type tfloat64() { return basic[TY.Tfloat64]; } static Type tfloat80() { return basic[TY.Tfloat80]; } static Type timaginary32() { return basic[TY.Timaginary32]; } static Type timaginary64() { return basic[TY.Timaginary64]; } static Type timaginary80() { return basic[TY.Timaginary80]; } static Type tcomplex32() { return basic[TY.Tcomplex32]; } static Type tcomplex64() { return basic[TY.Tcomplex64]; } static Type tcomplex80() { return basic[TY.Tcomplex80]; } static Type tbit() { return basic[TY.Tbit]; } static Type tbool() { return basic[TY.Tbool]; } static Type tchar() { return basic[TY.Tchar]; } static Type twchar() { return basic[TY.Twchar]; } static Type tdchar() { return basic[TY.Tdchar]; } // Some special types static Type tshiftcnt() { return tint32; // right side of shift expression } // #define tboolean tint32 // result of boolean expression static Type tboolean() { return tbool; // result of boolean expression } static Type tindex() { return tint32; // array/ptr index } static Type tvoidptr; // void* static Type terror() { return basic[TY.Terror]; // for error recovery } static Type tsize_t() { return basic[Tsize_t]; // matches size_t alias } static Type tptrdiff_t() { return basic[Tptrdiff_t]; // matches ptrdiff_t alias } static Type thash_t() { return tsize_t; // matches hash_t alias } }