in CoreCLRProfiler/native/coreclr_headers/src/inc/formattype.cpp [469:749]
PCCOR_SIGNATURE PrettyPrintType(
PCCOR_SIGNATURE typePtr, // type to convert,
CQuickBytes *out, // where to put the pretty printed string
IMDInternalImport *pIMDI) // ptr to IMDInternal class with ComSig
{
CONTRACTL
{
THROWS;
GC_NOTRIGGER;
}
CONTRACTL_END;
mdToken tk;
const char* str;
int typ;
CQuickBytes tmp;
CQuickBytes Appendix;
BOOL Reiterate;
int n;
do {
Reiterate = FALSE;
switch(typ = *typePtr++) {
case ELEMENT_TYPE_VOID :
str = "void"; goto APPEND;
case ELEMENT_TYPE_BOOLEAN :
str = "bool"; goto APPEND;
case ELEMENT_TYPE_CHAR :
str = "char"; goto APPEND;
case ELEMENT_TYPE_I1 :
str = "int8"; goto APPEND;
case ELEMENT_TYPE_U1 :
str = "uint8"; goto APPEND;
case ELEMENT_TYPE_I2 :
str = "int16"; goto APPEND;
case ELEMENT_TYPE_U2 :
str = "uint16"; goto APPEND;
case ELEMENT_TYPE_I4 :
str = "int32"; goto APPEND;
case ELEMENT_TYPE_U4 :
str = "uint32"; goto APPEND;
case ELEMENT_TYPE_I8 :
str = "int64"; goto APPEND;
case ELEMENT_TYPE_U8 :
str = "uint64"; goto APPEND;
case ELEMENT_TYPE_R4 :
str = "float32"; goto APPEND;
case ELEMENT_TYPE_R8 :
str = "float64"; goto APPEND;
case ELEMENT_TYPE_U :
str = "native uint"; goto APPEND;
case ELEMENT_TYPE_I :
str = "native int"; goto APPEND;
case ELEMENT_TYPE_OBJECT :
str = "object"; goto APPEND;
case ELEMENT_TYPE_STRING :
str = "string"; goto APPEND;
case ELEMENT_TYPE_TYPEDBYREF :
str = "typedref"; goto APPEND;
APPEND:
appendStr(out, KEYWORD((char*)str));
break;
case ELEMENT_TYPE_VALUETYPE :
str = "valuetype ";
goto DO_CLASS;
case ELEMENT_TYPE_CLASS :
str = "class ";
goto DO_CLASS;
DO_CLASS:
appendStr(out, KEYWORD((char*)str));
typePtr += CorSigUncompressToken(typePtr, &tk);
if(IsNilToken(tk))
{
appendStr(out, "[ERROR! NIL TOKEN]");
}
else PrettyPrintClass(out, tk, pIMDI);
REGISTER_REF(g_tkRefUser,tk)
break;
case ELEMENT_TYPE_SZARRAY :
insertStr(&Appendix,"[]");
Reiterate = TRUE;
break;
case ELEMENT_TYPE_ARRAY :
{
typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
PREFIX_ASSUME(typePtr != NULL);
unsigned rank = CorSigUncompressData(typePtr);
// <TODO> what is the syntax for the rank 0 case? </TODO>
if (rank == 0) {
appendStr(out, ERRORMSG("[BAD: RANK == 0!]"));
}
else {
_ASSERTE(rank != 0);
#ifdef _PREFAST_
#pragma prefast(push)
#pragma prefast(disable:22009 "Suppress PREFAST warnings about integer overflow")
#endif
int* lowerBounds = (int*) _alloca(sizeof(int)*2*rank);
int* sizes = &lowerBounds[rank];
memset(lowerBounds, 0, sizeof(int)*2*rank);
unsigned numSizes = CorSigUncompressData(typePtr);
_ASSERTE(numSizes <= rank);
unsigned i;
for(i =0; i < numSizes; i++)
sizes[i] = CorSigUncompressData(typePtr);
unsigned numLowBounds = CorSigUncompressData(typePtr);
_ASSERTE(numLowBounds <= rank);
for(i = 0; i < numLowBounds; i++)
typePtr+=CorSigUncompressSignedInt(typePtr,&lowerBounds[i]);
appendChar(out, '[');
if (rank == 1 && numSizes == 0 && numLowBounds == 0)
appendStr(out, "...");
else {
for(i = 0; i < rank; i++)
{
//if (sizes[i] != 0 || lowerBounds[i] != 0)
{
if (lowerBounds[i] == 0 && i < numSizes)
appendStrNum(out, sizes[i]);
else
{
if(i < numLowBounds)
{
appendStrNum(out, lowerBounds[i]);
appendStr(out, "...");
if (/*sizes[i] != 0 && */i < numSizes)
appendStrNum(out, lowerBounds[i] + sizes[i] - 1);
}
}
}
if (i < rank-1)
appendChar(out, ',');
}
}
appendChar(out, ']');
#ifdef _PREFAST_
#pragma prefast(pop)
#endif
}
} break;
case ELEMENT_TYPE_VAR :
appendChar(out, '!');
n = CorSigUncompressData(typePtr);
#ifdef __ILDASM__
if(!PrettyPrintGP(g_tkVarOwner,out,n))
#endif
appendStrNum(out, n);
break;
case ELEMENT_TYPE_MVAR :
appendChar(out, '!');
appendChar(out, '!');
n = CorSigUncompressData(typePtr);
#ifdef __ILDASM__
if(!PrettyPrintGP(g_tkMVarOwner,out,n))
#endif
appendStrNum(out, n);
break;
case ELEMENT_TYPE_FNPTR :
appendStr(out, KEYWORD("method "));
typePtr = PrettyPrintSignature(typePtr, 0x7FFF, "*", out, pIMDI, NULL);
break;
case ELEMENT_TYPE_GENERICINST :
{
typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
appendStr(out, LTN());
unsigned numArgs = CorSigUncompressData(typePtr);
bool needComma = false;
while(numArgs--)
{
if (needComma)
appendChar(out, ',');
typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
needComma = true;
}
appendStr(out, GTN());
break;
}
#ifndef __ILDASM__
case ELEMENT_TYPE_INTERNAL :
{
// ELEMENT_TYPE_INTERNAL <TypeHandle>
_ASSERTE(sizeof(TypeHandle) == sizeof(void *));
TypeHandle typeHandle;
typePtr += CorSigUncompressPointer(typePtr, (void **)&typeHandle);
MethodTable *pMT = NULL;
if (typeHandle.IsTypeDesc())
{
pMT = typeHandle.AsTypeDesc()->GetMethodTable();
if (pMT)
{
PrettyPrintClass(out, pMT->GetCl(), pMT->GetMDImport());
// It could be a "native version" of the managed type used in interop
if (typeHandle.AsTypeDesc()->IsNativeValueType())
appendStr(out, "_NativeValueType");
}
else
appendStr(out, "(null)");
}
else
{
pMT = typeHandle.AsMethodTable();
if (pMT)
PrettyPrintClass(out, pMT->GetCl(), pMT->GetMDImport());
else
appendStr(out, "(null)");
}
char sz[32];
if(IsCompilationProcess())
{
sprintf_s(sz, COUNTOF(sz), " /* TOKEN: 0x%x */", pMT != NULL ? pMT->GetCl() : 0);
}
else
{
sprintf_s(sz, COUNTOF(sz), " /* MT: 0x%p */", pMT);
}
appendStr(out, sz);
break;
}
#endif
// Modifiers or depedent types
case ELEMENT_TYPE_CMOD_OPT :
str = " modopt("; goto ADDCLASSTOCMOD;
case ELEMENT_TYPE_CMOD_REQD :
str = " modreq(";
ADDCLASSTOCMOD:
typePtr += CorSigUncompressToken(typePtr, &tk);
if (IsNilToken(tk))
{
Debug_ReportError("Nil token in custom modifier");
}
tmp.Shrink(0);
appendStr(&tmp, KEYWORD((char*)str));
PrettyPrintClass(&tmp, tk, pIMDI);
appendChar(&tmp,')');
str = (const char *) asString(&tmp);
goto MODIFIER;
case ELEMENT_TYPE_PINNED :
str = " pinned"; goto MODIFIER;
case ELEMENT_TYPE_PTR :
str = "*"; goto MODIFIER;
case ELEMENT_TYPE_BYREF :
str = AMP(); goto MODIFIER;
MODIFIER:
insertStr(&Appendix, str);
Reiterate = TRUE;
break;
default:
case ELEMENT_TYPE_SENTINEL :
case ELEMENT_TYPE_END :
//_ASSERTE(!"Unknown Type");
if(typ)
{
char sz[64];
sprintf_s(sz,COUNTOF(sz),"/* UNKNOWN TYPE (0x%X)*/",typ);
appendStr(out, ERRORMSG(sz));
}
break;
} // end switch
} while(Reiterate);
appendStr(out,asString(&Appendix));
return(typePtr);
}