PCCOR_SIGNATURE PrettyPrintType()

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);
}