diff dmd/Type.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 7427ded8caf7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/Type.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,2445 @@
+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;
+
+/* 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 (XXX) { /// 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);
+	}
+
+    int 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.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;
+	}
+	
+    int isString()
+	{
+		return false;
+	}
+	
+	/**************************
+	 * Given:
+	 *	T a, b;
+	 * Can we assign:
+	 *	a = b;
+	 * ?
+	 */
+    int 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)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)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();
+		}
+	}
+
+    Type castMod(uint mod)
+	{
+		assert(false);
+	}
+	
+	/************************************
+	 * 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 = 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 sc = new Scope();
+			e = e.semantic(sc);
+		}
+		else if (ident is Id.stringof_)
+		{	
+			string s = toChars();
+			e = new StringExp(loc, s, 'c');
+			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 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;
+		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(cast(void*)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;
+	}
+	
+    ulong sizemask()
+	{
+		assert(false);
+	}
+	
+    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
+	}
+}
\ No newline at end of file