in src/Microsoft.Diagnostics.Runtime/src/Builders/RuntimeBuilder.cs [1088:1208]
public ClrType? GetOrCreateTypeFromSignature(ClrModule? module, SigParser parser, IEnumerable<ClrGenericParameter> typeParameters, IEnumerable<ClrGenericParameter> methodParameters)
{
// ECMA 335 - II.23.2.12 - Type
if (!parser.GetElemType(out ClrElementType etype))
return null;
if (etype.IsPrimitive() || etype == ClrElementType.Void || etype == ClrElementType.Object || etype == ClrElementType.String)
return GetOrCreateBasicType(etype);
if (etype == ClrElementType.Array)
{
ClrType? innerType = GetOrCreateTypeFromSignature(module, parser, typeParameters, methodParameters);
innerType ??= GetOrCreateBasicType(ClrElementType.Void); // Need a placeholder if we can't determine type
// II.23.2.13
if (!parser.GetData(out int rank))
return null;
if (!parser.GetData(out int numSizes))
return null;
for (int i = 0; i < numSizes; i++)
if (!parser.GetData(out _))
return null;
if (!parser.GetData(out int numLowBounds))
return null;
for (int i = 0; i < numLowBounds; i++)
if (!parser.GetData(out _))
return null;
// We should probably use sizes and lower bounds, but this is so rare I won't worry about it for now
ClrType? result = GetOrCreateArrayType(innerType, rank);
return result;
}
if (etype == ClrElementType.Class || etype == ClrElementType.Struct)
{
if (!parser.GetToken(out int token))
return null;
ClrType? result = module != null ? GetOrCreateTypeFromToken(module, token) : null;
if (result == null)
{
// todo, create a type from metadata instead of returning a basic type?
result = GetOrCreateBasicType(etype);
}
return result;
}
if (etype == ClrElementType.FunctionPointer)
{
if (!parser.GetToken(out _))
return null;
// We don't have a type for function pointers so we'll make it a void pointer
ClrType inner = GetOrCreateBasicType(ClrElementType.Void);
return GetOrCreatePointerType(inner, 1);
}
if (etype == ClrElementType.GenericInstantiation)
{
if (!parser.GetElemType(out ClrElementType _))
return null;
if (!parser.GetToken(out int token))
return null;
if (!parser.GetData(out int count))
return null;
// Even though we don't make use of these types we need to move past them in the parser.
for (int i = 0; i < count; i++)
GetOrCreateTypeFromSignature(module, parser, typeParameters, methodParameters);
ClrType? result = module?.ResolveToken(token);
return result;
}
if (etype == ClrElementType.MVar || etype == ClrElementType.Var)
{
if (!parser.GetData(out int index))
return null;
ClrGenericParameter[] param = (etype == ClrElementType.Var ? typeParameters : methodParameters).ToArray();
if (index < 0 || index >= param.Length)
return null;
return new ClrmdGenericType(this, GetOrCreateHeap(), module, param[index]);
}
if (etype == ClrElementType.Pointer)
{
if (!parser.SkipCustomModifiers())
return null;
ClrType? innerType = GetOrCreateTypeFromSignature(module, parser, typeParameters, methodParameters);
if (innerType == null)
innerType = GetOrCreateBasicType(ClrElementType.Void);
return GetOrCreatePointerType(innerType, 1);
}
if (etype == ClrElementType.SZArray)
{
if (!parser.SkipCustomModifiers())
return null;
ClrType? innerType = GetOrCreateTypeFromSignature(module, parser, typeParameters, methodParameters);
if (innerType == null)
innerType = GetOrCreateBasicType(ClrElementType.Void);
return GetOrCreateArrayType(innerType, 1);
}
DebugOnly.Assert(false); // What could we have forgotten? Should only happen in a corrupted signature.
return null;
}