static PCCOR_SIGNATURE PrettyPrintType()

in CoreCLRProfiler/native/PrettyPrintSig.cpp [206:460]


static PCCOR_SIGNATURE PrettyPrintType(
               PCCOR_SIGNATURE    typePtr,      // type to convert,     
               size_t             typeLen,      // Maximum length of the type
               CQuickBytes *      out,          // where to put the pretty printed string       
               IMetaDataImport *  pIMDI)        // ptr to IMDInternal class with ComSig
{
    mdToken             tk;     
    const WCHAR *       str;    
    WCHAR               rcname[MAX_CLASS_NAME];
    HRESULT             hr;
    unsigned __int8     elt = *typePtr++;
    PCCOR_SIGNATURE     typeEnd = typePtr + typeLen;

    switch(elt) 
    {
    case ELEMENT_TYPE_VOID:
        str = W("void");
        goto APPEND;
        
    case ELEMENT_TYPE_BOOLEAN:
        str = W("bool");
        goto APPEND;
        
    case ELEMENT_TYPE_CHAR:
        str = W("wchar");
        goto APPEND; 
        
    case ELEMENT_TYPE_I1:
        str = W("int8");
        goto APPEND;
        
    case ELEMENT_TYPE_U1:
        str = W("unsigned int8");
        goto APPEND;
        
    case ELEMENT_TYPE_I2:
        str = W("int16");
        goto APPEND;
        
    case ELEMENT_TYPE_U2:
        str = W("unsigned int16");
        goto APPEND;
        
    case ELEMENT_TYPE_I4:
        str = W("int32");
        goto APPEND;
        
    case ELEMENT_TYPE_U4:
        str = W("unsigned int32");
        goto APPEND;
        
    case ELEMENT_TYPE_I8:
        str = W("int64");
        goto APPEND;
        
    case ELEMENT_TYPE_U8:
        str = W("unsigned int64");
        goto APPEND;
        
    case ELEMENT_TYPE_R4:
        str = W("float32");
        goto APPEND;
        
    case ELEMENT_TYPE_R8:
        str = W("float64");
        goto APPEND;
        
    case ELEMENT_TYPE_U:
        str = W("unsigned int");
        goto APPEND;
        
    case ELEMENT_TYPE_I:
        str = W("int");
        goto APPEND;
        
    case ELEMENT_TYPE_OBJECT:
        str = W("class System.Object");
        goto APPEND;
        
    case ELEMENT_TYPE_STRING:
        str = W("class System.String");
        goto APPEND;
        
    case ELEMENT_TYPE_CANON_ZAPSIG:
        str = W("class System.__Canon");
        goto APPEND;
        
    case ELEMENT_TYPE_TYPEDBYREF:
        str = W("refany");
        goto APPEND;
        
    APPEND: 
        appendStrW(out, str);
        break;

    case ELEMENT_TYPE_VALUETYPE:
        str = W("value class ");
        goto DO_CLASS;
        
    case ELEMENT_TYPE_CLASS:
        str = W("class "); 
        goto DO_CLASS;
        
    DO_CLASS:
        typePtr += CorSigUncompressToken(typePtr, &tk);
        appendStrW(out, str);
        rcname[0] = 0;
        str = rcname;
        
        if (TypeFromToken(tk) == mdtTypeRef)
        {
            hr = pIMDI->GetTypeRefProps(tk, 0, rcname, NumItems(rcname), 0);
        }
        else if (TypeFromToken(tk) == mdtTypeDef)
        {
            hr = pIMDI->GetTypeDefProps(tk, rcname, NumItems(rcname), 0, 0, 0);
        }
        else
        {
            _ASSERTE(!"Unknown token type encountered in signature.");
            str = W("<UNKNOWN>");
        }
        
        appendStrW(out, str);
        break;
        
    case ELEMENT_TYPE_SZARRAY:
        typePtr = PrettyPrintType(typePtr, (typeEnd - typePtr), out, pIMDI); 
        appendStrW(out, W("[]"));
        break;
    
    case ELEMENT_TYPE_ARRAY:
        {
            typePtr = PrettyPrintType(typePtr, (typeEnd - typePtr), out, pIMDI);
            unsigned rank = CorSigUncompressData(typePtr);
            PREFIX_ASSUME(rank <= 0xffffff);
            
            // <TODO>TODO what is the syntax for the rank 0 case? </TODO>
            if (rank == 0)
            {
                appendStrW(out, W("[??]"));
            }
            else 
            {
                _ASSERTE(rank != 0);
                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 int i;
                for(i =0; i < numSizes; i++)
                    sizes[i] = CorSigUncompressData(typePtr);
                
                unsigned numLowBounds = CorSigUncompressData(typePtr);
                _ASSERTE(numLowBounds <= rank); 
                for(i = 0; i < numLowBounds; i++)       
                    lowerBounds[i] = CorSigUncompressData(typePtr); 
                
                appendStrW(out, W("["));
                for(i = 0; i < rank; i++)       
                {       
                    if (sizes[i] != 0 && lowerBounds[i] != 0)   
                    {   
                        if (lowerBounds[i] == 0)        
                            appendStrNumW(out, sizes[i]);
                        else    
                        {       
                            appendStrNumW(out, lowerBounds[i]);
                            appendStrW(out, W("..."));
                            if (sizes[i] != 0)  
                                appendStrNumW(out, lowerBounds[i] + sizes[i] + 1);
                        }       
                    }   
                    if (i < rank-1) 
                        appendStrW(out, W(","));
                }       
                appendStrW(out, W("]"));  
            }
        }
        break;
        
    case ELEMENT_TYPE_MVAR:
        appendStrW(out, W("!!"));
        appendStrNumW(out, CorSigUncompressData(typePtr));
        break;
        
    case ELEMENT_TYPE_VAR:   
        appendStrW(out, W("!"));  
        appendStrNumW(out, CorSigUncompressData(typePtr));
        break;
        
    case ELEMENT_TYPE_GENERICINST:
        {
            typePtr = PrettyPrintType(typePtr, (typeEnd - typePtr), out, pIMDI); 
            unsigned ntypars = CorSigUncompressData(typePtr);
            appendStrW(out, W("<"));
            for (unsigned i = 0; i < ntypars; i++)
            {
                if (i > 0)
                    appendStrW(out, W(","));
                typePtr = PrettyPrintType(typePtr, (typeEnd - typePtr), out, pIMDI); 
            }
            appendStrW(out, W(">"));
        }
        break;
        
    case ELEMENT_TYPE_MODULE_ZAPSIG:
        appendStrW(out, W("[module#"));
        appendStrNumW(out, CorSigUncompressData(typePtr));
        appendStrW(out, W(", token#"));
        typePtr += CorSigUncompressToken(typePtr, &tk); 
        appendStrHexW(out, tk);
        appendStrW(out, W("]"));
        break;
            
    case ELEMENT_TYPE_FNPTR:
        appendStrW(out, W("fnptr "));
        PrettyPrintSigWorker(typePtr, (typeEnd - typePtr), W(""), out, pIMDI);
        break;

    case ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG:
    case ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG:
        appendStrW(out, W("native "));
        typePtr = PrettyPrintType(typePtr, (typeEnd - typePtr), out, pIMDI); 
        break;

    // Modifiers or depedant types  
    case ELEMENT_TYPE_PINNED:
        str = W(" pinned");
        goto MODIFIER;
        
    case ELEMENT_TYPE_PTR:
        str = W("*");
        goto MODIFIER;
        
    case ELEMENT_TYPE_BYREF:   
        str = W("&");
        goto MODIFIER;

    MODIFIER:
        typePtr = PrettyPrintType(typePtr, (typeEnd - typePtr), out, pIMDI); 
        appendStrW(out, str);
        break;
        
    default:
    case ELEMENT_TYPE_SENTINEL:
    case ELEMENT_TYPE_END:
        _ASSERTE(!"Unknown Type");
        return(typePtr);
        break;
    }
    return(typePtr);
} // static PCCOR_SIGNATURE PrettyPrintType()