/// <summary> /// Read a type from a signature. /// </summary> /// <param name="p">Pointer to the signature to be read</param> /// <param name="f">CLIFileReader in use</param> /// <returns> /// A CLIType object representing a type. It is similar to a Reflection.Type /// object though it is less expensive and contains enough information to /// access type definitions in CLIFile table. /// </returns> private static CLITypeNode ReadTypeNode(ref MapPtr p, CLIFile f) { ELEMENT_TYPE t = (ELEMENT_TYPE)SignatureUtil.ReadCompressedInt(ref p); switch (t) { case ELEMENT_TYPE.ELEMENT_TYPE_BOOLEAN: case ELEMENT_TYPE.ELEMENT_TYPE_CHAR: case ELEMENT_TYPE.ELEMENT_TYPE_I1: case ELEMENT_TYPE.ELEMENT_TYPE_U1: case ELEMENT_TYPE.ELEMENT_TYPE_I2: case ELEMENT_TYPE.ELEMENT_TYPE_U2: case ELEMENT_TYPE.ELEMENT_TYPE_I4: case ELEMENT_TYPE.ELEMENT_TYPE_U4: case ELEMENT_TYPE.ELEMENT_TYPE_I8: case ELEMENT_TYPE.ELEMENT_TYPE_U8: case ELEMENT_TYPE.ELEMENT_TYPE_R4: case ELEMENT_TYPE.ELEMENT_TYPE_R8: case ELEMENT_TYPE.ELEMENT_TYPE_I: case ELEMENT_TYPE.ELEMENT_TYPE_U: case ELEMENT_TYPE.ELEMENT_TYPE_STRING: case ELEMENT_TYPE.ELEMENT_TYPE_OBJECT: case ELEMENT_TYPE.ELEMENT_TYPE_TYPEDBYREF: case ELEMENT_TYPE.ELEMENT_TYPE_VOID: return(BaseType.TypeOf(t).type); case ELEMENT_TYPE.ELEMENT_TYPE_VAR: return(new VariableType(f, SignatureUtil.ReadCompressedInt(ref p))); case ELEMENT_TYPE.ELEMENT_TYPE_MVAR: return(new MethodVariableType(f, SignatureUtil.ReadCompressedInt(ref p))); case ELEMENT_TYPE.ELEMENT_TYPE_VALUETYPE: case ELEMENT_TYPE.ELEMENT_TYPE_CLASS: return(new CompoundType(f, SignatureUtil.ReadCompressedInt(ref p))); case ELEMENT_TYPE.ELEMENT_TYPE_GENERICINST: { ELEMENT_TYPE isClass = (ELEMENT_TYPE)SignatureUtil.ReadCompressedInt(ref p); int ttk = SignatureUtil.ReadCompressedInt(ref p); int count = SignatureUtil.ReadCompressedInt(ref p); CLIType[] args = new CLIType[count]; for (int i = 0; i < count; i++) { args[i] = new CLIType(f, ReadTypeNode(ref p, f)); } return(new CompoundType(f, ttk, args)); } case ELEMENT_TYPE.ELEMENT_TYPE_PTR: { int sz; ELEMENT_TYPE opt = (ELEMENT_TYPE)SignatureUtil.ReadCompressedInt(p, out sz); ELEMENT_TYPE?cmod = null; if (opt == ELEMENT_TYPE.ELEMENT_TYPE_CMOD_OPT || opt == ELEMENT_TYPE.ELEMENT_TYPE_CMOD_REQD) { cmod = opt; p += 1; } CLITypeNode ptrt = new PointerType(ReadTypeNode(ref p, f)); if (cmod.HasValue) { ptrt = new CustomModType(cmod.Value, ptrt); } return(ptrt); } case ELEMENT_TYPE.ELEMENT_TYPE_FNPTR: return(new FunPointerType(f, p)); case ELEMENT_TYPE.ELEMENT_TYPE_ARRAY: { CLITypeNode at = ReadTypeNode(ref p, f); int rank = SignatureUtil.ReadCompressedInt(ref p); int sz = SignatureUtil.ReadCompressedInt(ref p); int[] szs = new int[sz]; for (int i = 0; i < sz; i++) { szs[i] = SignatureUtil.ReadCompressedInt(ref p); } sz = SignatureUtil.ReadCompressedInt(ref p); int[] lb = new int[sz]; for (int i = 0; i < sz; i++) { lb[i] = SignatureUtil.ReadCompressedInt(ref p); } return(new ArrayType(at, rank, szs, lb)); } case ELEMENT_TYPE.ELEMENT_TYPE_SZARRAY: { int sz; ELEMENT_TYPE opt = (ELEMENT_TYPE)SignatureUtil.ReadCompressedInt(p, out sz); ELEMENT_TYPE?cmod = null; if (opt == ELEMENT_TYPE.ELEMENT_TYPE_CMOD_OPT || opt == ELEMENT_TYPE.ELEMENT_TYPE_CMOD_REQD) { cmod = opt; p += 1; } CLITypeNode sat = new ArrayType(ReadTypeNode(ref p, f)); if (cmod.HasValue) { sat = new CustomModType(cmod.Value, sat); } return(sat); } default: throw new Exception("Internal error in CLI File Reader library!"); } }
public static CLIType Promote(CLIType nt1, CLIType nt2) { if (!(nt1.type is BaseType) || !(nt2.type is BaseType)) { throw new Exception("Internal error"); } BaseType t1 = (BaseType)nt1.type; BaseType t2 = (BaseType)nt2.type; switch (t1.type) { case ELEMENT_TYPE.ELEMENT_TYPE_CHAR: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_CHAR: case ELEMENT_TYPE.ELEMENT_TYPE_U1: case ELEMENT_TYPE.ELEMENT_TYPE_U2: case ELEMENT_TYPE.ELEMENT_TYPE_U4: case ELEMENT_TYPE.ELEMENT_TYPE_U8: return(nt2); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_I1: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_I1: case ELEMENT_TYPE.ELEMENT_TYPE_I2: case ELEMENT_TYPE.ELEMENT_TYPE_I4: case ELEMENT_TYPE.ELEMENT_TYPE_I8: return(nt2); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_U1: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_CHAR: return(nt1); case ELEMENT_TYPE.ELEMENT_TYPE_U1: case ELEMENT_TYPE.ELEMENT_TYPE_U2: case ELEMENT_TYPE.ELEMENT_TYPE_U4: case ELEMENT_TYPE.ELEMENT_TYPE_U8: return(nt2); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_I2: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_I1: return(nt1); case ELEMENT_TYPE.ELEMENT_TYPE_I2: case ELEMENT_TYPE.ELEMENT_TYPE_I4: case ELEMENT_TYPE.ELEMENT_TYPE_I8: return(nt2); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_U2: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_CHAR: case ELEMENT_TYPE.ELEMENT_TYPE_U1: return(nt1); case ELEMENT_TYPE.ELEMENT_TYPE_U2: case ELEMENT_TYPE.ELEMENT_TYPE_U4: case ELEMENT_TYPE.ELEMENT_TYPE_U8: return(nt2); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_I4: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_I1: case ELEMENT_TYPE.ELEMENT_TYPE_I2: case ELEMENT_TYPE.ELEMENT_TYPE_I4: return(nt1); case ELEMENT_TYPE.ELEMENT_TYPE_I8: return(nt2); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_U4: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_CHAR: case ELEMENT_TYPE.ELEMENT_TYPE_U1: case ELEMENT_TYPE.ELEMENT_TYPE_U2: case ELEMENT_TYPE.ELEMENT_TYPE_U4: return(nt1); case ELEMENT_TYPE.ELEMENT_TYPE_U8: return(nt2); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_I8: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_I1: case ELEMENT_TYPE.ELEMENT_TYPE_I2: case ELEMENT_TYPE.ELEMENT_TYPE_I4: case ELEMENT_TYPE.ELEMENT_TYPE_I8: return(nt1); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_U8: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_CHAR: case ELEMENT_TYPE.ELEMENT_TYPE_U1: case ELEMENT_TYPE.ELEMENT_TYPE_U2: case ELEMENT_TYPE.ELEMENT_TYPE_U4: case ELEMENT_TYPE.ELEMENT_TYPE_U8: return(nt1); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_R4: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_R4: case ELEMENT_TYPE.ELEMENT_TYPE_R8: return(nt2); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_R8: switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_R4: case ELEMENT_TYPE.ELEMENT_TYPE_R8: return(nt1); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_I: // FIXME: Check this switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_I1: case ELEMENT_TYPE.ELEMENT_TYPE_I2: case ELEMENT_TYPE.ELEMENT_TYPE_I4: return(nt1); } return(null); case ELEMENT_TYPE.ELEMENT_TYPE_U: // FIXME: Check this switch (t2.type) { case ELEMENT_TYPE.ELEMENT_TYPE_CHAR: case ELEMENT_TYPE.ELEMENT_TYPE_U1: case ELEMENT_TYPE.ELEMENT_TYPE_U2: case ELEMENT_TYPE.ELEMENT_TYPE_U4: return(nt1); } return(null); default: return(null); } }