} //end if(g_fShowCA)
}
-// Sets *pbOverridingTypeSpec to TRUE if we are overriding a method declared by a type spec.
+// Sets *pbOverridingTypeSpec to TRUE if we are overriding a method declared by a type spec or
+// if the method has a signature which does not exactly match between the overrider and overridee.
+// That case is commonly caused by covariant overrides.
// In that case the syntax is slightly different (there are additional 'method' keywords).
// Refer to Expert .NET 2.0 IL Assembler page 242.
void PrettyPrintOverrideDecl(ULONG i, __inout __nullterminated char* szString, void* GUICookie, mdToken tkOverrider,
if(g_pImport->IsValidToken(tkDecl))
{
+ bool needsFullTokenPrint = false;
+ bool hasTkDeclParent = false;
+
+ // Determine if the decl is a typespec method, in which case the "method" syntax + full token print
+ // must be used to generate the disassembly.
if(SUCCEEDED(g_pImport->GetParentToken(tkDecl,&tkDeclParent)))
{
if(g_pImport->IsValidToken(tkDeclParent))
{
if(TypeFromToken(tkDeclParent)==mdtTypeSpec)
{
- szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr), " %s ",KEYWORD("method"));
- PrettyPrintToken(szString,tkDecl,g_pImport,GUICookie,tkOverrider);
-
- *pbOverridingTypeSpec = TRUE;
- return;
+ needsFullTokenPrint = true;
}
- PrettyPrintToken(szString, tkDeclParent, g_pImport,GUICookie,tkOverrider);
- strcat_s(szString, SZSTRING_SIZE,"::");
- szptr = &szString[strlen(szString)];
+ hasTkDeclParent = true;
}
}
else
szptr+=sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"%s",ERRORMSG("INVALID OVERRIDDEN METHOD'S PARENT TOKEN"));
}
+
+ // Determine if the sig of the decl does not match the sig of the body
+ // In that case the full "method" syntax must be used
+ if ((TypeFromToken(tkOverrider) == mdtMethodDef) && !needsFullTokenPrint)
+ {
+ PCCOR_SIGNATURE pComSigDecl;
+ ULONG cComSigDecl;
+ mdToken tkDeclSigTok = tkDecl;
+ bool successfullyGotDeclSig = false;
+ bool successfullyGotBodySig = false;
+
+ if (TypeFromToken(tkDeclSigTok) == mdtMethodSpec)
+ {
+ mdToken meth=0;
+ if (SUCCEEDED(g_pImport->GetMethodSpecProps(tkDeclSigTok, &meth, NULL, NULL)))
+ {
+ tkDeclSigTok = meth;
+ }
+ }
+
+ if (TypeFromToken(tkDeclSigTok) == mdtMethodDef)
+ {
+ if (SUCCEEDED(g_pImport->GetSigOfMethodDef(tkDeclSigTok, &cComSigDecl, &pComSigDecl)))
+ {
+ successfullyGotDeclSig = true;
+ }
+ }
+ else if (TypeFromToken(tkDeclSigTok) == mdtMemberRef)
+ {
+ const char *pszMemberNameUnused;
+ if (SUCCEEDED(g_pImport->GetNameAndSigOfMemberRef(
+ tkDeclSigTok,
+ &pComSigDecl,
+ &cComSigDecl,
+ &pszMemberNameUnused)))
+ {
+ successfullyGotDeclSig = true;
+ }
+ }
+
+ PCCOR_SIGNATURE pComSigBody;
+ ULONG cComSigBody;
+ if (SUCCEEDED(g_pImport->GetSigOfMethodDef(tkOverrider, &cComSigBody, &pComSigBody)))
+ {
+ successfullyGotBodySig = true;
+ }
+
+ if (successfullyGotDeclSig && successfullyGotBodySig)
+ {
+ if (cComSigBody != cComSigDecl)
+ {
+ needsFullTokenPrint = true;
+ }
+ else if (memcmp(pComSigBody, pComSigDecl, cComSigBody) != 0)
+ {
+ needsFullTokenPrint = true;
+ }
+
+ // Signature are binary identical, full sig printing not needed
+ }
+ else
+ {
+ szptr+=sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"%s",ERRORMSG("INVALID BODY OR DECL SIG"));
+ }
+ }
+
+ if (needsFullTokenPrint)
+ {
+ // In this case, the shortcut syntax cannot be used, and a full token must be printed.
+ // Print the full token and return.
+ szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr), " %s ",KEYWORD("method"));
+ PrettyPrintToken(szString,tkDecl,g_pImport,GUICookie,tkOverrider);
+
+ *pbOverridingTypeSpec = TRUE;
+ return;
+ }
+
+ if (hasTkDeclParent)
+ {
+ // If the tkDeclParent was successfully retrieved during parent discovery print it here.
+ PrettyPrintToken(szString, tkDeclParent, g_pImport,GUICookie,tkOverrider);
+ strcat_s(szString, SZSTRING_SIZE,"::");
+ szptr = &szString[strlen(szString)];
+ }
+
if(TypeFromToken(tkDecl) == mdtMethodSpec)
{
mdToken meth=0;