in CoreCLRProfiler/native/coreclr_headers/src/inc/formattype.cpp [175:419]
PCCOR_SIGNATURE PrettyPrintSignature(
PCCOR_SIGNATURE typePtr, // type to convert,
unsigned typeLen, // the lenght of 'typePtr'
const char* name, // can be "", the name of the method for this sig 0 means local var sig
CQuickBytes *out, // where to put the pretty printed string
IMDInternalImport *pIMDI, // ptr to IMDInternalImport class with ComSig
const char* inlabel, // prefix for names (NULL if no names required)
BOOL printTyArity)
{
CONTRACTL
{
THROWS;
GC_NOTRIGGER;
}
CONTRACTL_END;
unsigned numArgs;
unsigned numTyArgs = 0;
PCCOR_SIGNATURE typeEnd = typePtr + typeLen;
unsigned ixArg= 0; //arg index
char argname[1024];
char label[MAX_PREFIX_SIZE];
const char* openpar = "(";
const char* closepar = ")";
ParamDescriptor* pszArgName = NULL; // ptr to array of names (if provided by debug info)
if(inlabel && *inlabel) // check for *inlabel is totally unnecessary, added to pacify the PREFIX
{
strcpy_s(label,MAX_PREFIX_SIZE,inlabel);
ixArg = label[strlen(label)-1] - '0';
label[strlen(label)-1] = 0;
if(label[0] == '@') // it's pointer!
{
#ifdef HOST_64BIT
pszArgName = (ParamDescriptor*)_atoi64(&label[1]);
#else // !HOST_64BIT
pszArgName = (ParamDescriptor*)(size_t)atoi(&label[1]);
#endif // HOST_64BIT
}
}
// 0 means a local var sig
if (name != 0)
{
// get the calling convention out
unsigned callConv = CorSigUncompressData(typePtr);
// should not be a local var sig
_ASSERTE(!isCallConv(callConv, IMAGE_CEE_CS_CALLCONV_LOCAL_SIG));
if (isCallConv(callConv, IMAGE_CEE_CS_CALLCONV_FIELD))
{
typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
if (*name)
{
appendChar(out, ' ');
appendStr(out, name);
}
return(typePtr);
}
if (callConv & IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS)
appendStr(out, KEYWORD("explicit "));
if (callConv & IMAGE_CEE_CS_CALLCONV_HASTHIS)
appendStr(out, KEYWORD("instance "));
if (isCallConv(callConv, IMAGE_CEE_CS_CALLCONV_GENERICINST))
{
openpar = LTN();
closepar = GTN();
}
else
{
const char* const callConvUndefined = (const char*)-1;
static const char* const callConvNames[16] = {
"",
"unmanaged cdecl ",
"unmanaged stdcall ",
"unmanaged thiscall ",
"unmanaged fastcall ",
"vararg ",
callConvUndefined, // field
callConvUndefined, // local sig
callConvUndefined, // property
"unmanaged ",
callConvUndefined,
callConvUndefined,
callConvUndefined,
callConvUndefined,
callConvUndefined,
callConvUndefined
};
static_assert_no_msg(COUNTOF(callConvNames) == (IMAGE_CEE_CS_CALLCONV_MASK + 1));
char tmp[32];
unsigned callConvIdx = callConv & IMAGE_CEE_CS_CALLCONV_MASK;
const char* name_cc = callConvNames[callConvIdx];
if (name_cc == callConvUndefined)
{
sprintf_s(tmp, COUNTOF(tmp), "callconv(%u) ", callConvIdx);
name_cc = tmp;
}
appendStr(out, KEYWORD(name_cc));
}
if (callConv & IMAGE_CEE_CS_CALLCONV_GENERIC)
{
numTyArgs = CorSigUncompressData(typePtr);
}
numArgs = CorSigUncompressData(typePtr);
if (!isCallConv(callConv, IMAGE_CEE_CS_CALLCONV_GENERICINST))
{
// do return type
if(pszArgName)
{
argname[0] = 0;
DumpParamAttr(argname,COUNTOF(argname),pszArgName[ixArg+numArgs].attr);
appendStr(out,argname);
}
typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
if(pszArgName)
{
argname[0] = ' '; argname[1] = 0;
DumpMarshaling(pIMDI,argname,COUNTOF(argname),pszArgName[ixArg+numArgs].tok);
appendStr(out,argname);
}
if(*name != 0)
{
appendChar(out, ' ');
appendStr(out, name);
}
if((numTyArgs != 0)&&printTyArity)
{
appendStr(out,LTN());
appendChar(out,'[');
appendStrNum(out,numTyArgs);
appendChar(out,']');
appendStr(out,GTN());
}
}
}
else
{
// get the calling convention out
#ifdef _DEBUG
unsigned callConv =
#endif
CorSigUncompressData(typePtr);
#ifdef _DEBUG
(void)callConv; //prevent "unused variable" warning from GCC
// should be a local var sig
_ASSERTE(callConv == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG);
#endif
numArgs = CorSigUncompressData(typePtr);
}
appendStr(out, openpar);
bool needComma = false;
while(typePtr < typeEnd)
{
if(name) // printing the arguments
{
PREFIX_ASSUME(typePtr != NULL);
if (*typePtr == ELEMENT_TYPE_SENTINEL)
{
if (needComma)
appendChar(out, ',');
appendStr(out, "...");
typePtr++;
}
else
{
if (numArgs <= 0)
break;
if (needComma)
appendChar(out, ',');
if(pszArgName)
{
argname[0] = 0;
DumpParamAttr(argname,COUNTOF(argname),pszArgName[ixArg].attr);
appendStr(out,argname);
}
typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
if(inlabel)
{
if(pszArgName)
{
argname[0] = ' '; argname[1] = 0;
DumpMarshaling(pIMDI,argname,COUNTOF(argname),pszArgName[ixArg].tok);
strcat_s(argname, COUNTOF(argname), ProperName(pszArgName[ixArg++].name));
}
else sprintf_s(argname,COUNTOF(argname)," %s_%d",label,ixArg++);
appendStr(out,argname);
}
--numArgs;
}
}
else // printing local vars
{
if (numArgs <= 0)
break;
if(pszArgName)
{
if(pszArgName[ixArg].attr == 0xFFFFFFFF)
{
CQuickBytes fake_out;
typePtr = PrettyPrintTypeOrDef(typePtr, &fake_out, pIMDI);
ixArg++;
numArgs--;
continue;
}
}
if (needComma)
appendChar(out, ',');
if(pszArgName)
{
sprintf_s(argname,COUNTOF(argname),"[%d] ",pszArgName[ixArg].attr);
appendStr(out,argname);
}
typePtr = PrettyPrintTypeOrDef(typePtr, out, pIMDI);
if(inlabel)
{
if(pszArgName)
{
sprintf_s(argname,COUNTOF(argname)," %s",ProperLocalName(pszArgName[ixArg++].name));
}
else sprintf_s(argname,COUNTOF(argname)," %s_%d",label,ixArg++);
appendStr(out,argname);
}
--numArgs;
}
needComma = true;
}
// Have we finished printing all the arguments?
if (numArgs > 0) {
appendStr(out, ERRORMSG(" [SIGNATURE ENDED PREMATURELY]"));
}
appendStr(out, closepar);
return(typePtr);
}