33#include < string>
44#include < algorithm>
55#include < codecvt>
6+ #include < cstdint>
67#include < locale>
78#include < vector>
89#if defined(_WIN32)
@@ -63,40 +64,81 @@ inline void CopyWTrunc(WCHAR *dst, ULONG dstLen, const std::basic_string<WCHAR>
6364 dst[n] = static_cast <WCHAR >(0 );
6465}
6566
66- inline void GetTypeName2 (ICorProfilerInfo15 *pInfo, IMetaDataImport2 *pMetaDataImport, mdToken mdType, ULONG numGenericTypeArgs, ClassID *genericTypeArgs, WCHAR *pszName, ULONG bufferLen);
67+ inline void GetTypeName2 (ICorProfilerInfo15 *pInfo, IMetaDataImport2 *pMetaDataImport, mdToken mdType, ULONG numGenericTypeArgs, ClassID *genericTypeArgs, WCHAR *pszName, ULONG bufferLen, ULONG recursionDepth = 0 );
6768
6869inline void GetTypeName (ICorProfilerInfo15 *pInfo, IMetaDataImport2 *pMetaDataImport, ClassID classId, ModuleID moduleId, WCHAR *pszName, ULONG bufferLen)
6970{
70- mdTypeDef mdType;
71- ClassID parentClassId;
71+ if (pszName == nullptr || bufferLen == 0 )
72+ return ;
73+
74+ pszName[0 ] = static_cast <WCHAR >(0 );
75+
76+ if (pInfo == nullptr || classId == 0 )
77+ return ;
78+
79+ mdTypeDef mdType = mdTypeDefNil;
80+ ClassID parentClassId = 0 ;
7281 ULONG32 numGenericTypeArgs = 0 ;
7382
74- pInfo->GetClassIDInfo2 (classId, NULL , &mdType, &parentClassId, 0 , &numGenericTypeArgs, NULL );
83+ if (FAILED (pInfo->GetClassIDInfo2 (classId, NULL , &mdType, &parentClassId, 0 , &numGenericTypeArgs, NULL )) || mdType == mdTypeDefNil)
84+ return ;
7585
7686 std::vector<ClassID> genericTypeArgs;
7787 if (numGenericTypeArgs)
88+ {
7889 genericTypeArgs.resize (numGenericTypeArgs);
79- if (numGenericTypeArgs)
80- pInfo->GetClassIDInfo2 (classId, NULL , &mdType, &parentClassId, numGenericTypeArgs, &numGenericTypeArgs, genericTypeArgs.data ());
90+ ULONG32 fetched = numGenericTypeArgs;
91+ if (FAILED (pInfo->GetClassIDInfo2 (classId, NULL , &mdType, &parentClassId, numGenericTypeArgs, &fetched, genericTypeArgs.data ())))
92+ {
93+ genericTypeArgs.clear ();
94+ numGenericTypeArgs = 0 ;
95+ }
96+ else
97+ {
98+ numGenericTypeArgs = fetched;
99+ genericTypeArgs.resize (numGenericTypeArgs);
100+ }
101+ }
81102
82103 IMetaDataImport2 *metadataImport = pMetaDataImport;
83104 bool releaseMeta = false ;
84105 if (metadataImport == NULL )
106+ {
85107 releaseMeta = SUCCEEDED (pInfo->GetModuleMetaData (moduleId, ofRead, IID_IMetaDataImport2, reinterpret_cast <IUnknown **>(&metadataImport))) && metadataImport != nullptr ;
108+ if (!releaseMeta)
109+ return ;
110+ }
86111
87112 GetTypeName2 (pInfo, metadataImport, mdType, numGenericTypeArgs, genericTypeArgs.empty () ? nullptr : genericTypeArgs.data (), pszName, bufferLen);
88113 if (releaseMeta)
89114 metadataImport->Release ();
90115}
91116
92- inline void GetTypeName2 (ICorProfilerInfo15 *pInfo, IMetaDataImport2 *pMetaDataImport, mdToken mdType, ULONG numGenericTypeArgs, ClassID *genericTypeArgs, WCHAR *pszName, ULONG bufferLen)
117+ inline void GetTypeName2 (ICorProfilerInfo15 *pInfo, IMetaDataImport2 *pMetaDataImport, mdToken mdType, ULONG numGenericTypeArgs, ClassID *genericTypeArgs, WCHAR *pszName, ULONG bufferLen, ULONG recursionDepth )
93118{
94- ULONG length = bufferLen;
95- DWORD flags ;
96- mdTypeDef mdBaseType;
119+ if (pszName == nullptr || bufferLen == 0 )
120+ return ;
121+
97122 pszName[0 ] = static_cast <WCHAR >(0 );
98123
124+ if (pMetaDataImport == nullptr || mdType == mdTokenNil)
125+ return ;
126+
127+ if (recursionDepth > 32 )
128+ {
129+ pszName[0 ] = static_cast <WCHAR >(u' ?' );
130+ if (bufferLen > 1 )
131+ pszName[1 ] = static_cast <WCHAR >(0 );
132+ return ;
133+ }
134+
135+ ULONG length = bufferLen;
136+ DWORD flags = 0 ;
137+ mdTypeDef mdBaseType = mdTypeDefNil;
138+
99139 auto hr = pMetaDataImport->GetTypeDefProps (mdType, pszName, length, &length, &flags, &mdBaseType);
140+ if (FAILED (hr))
141+ return ;
100142
101143 if (!IsTdNested (flags) && numGenericTypeArgs == 0 )
102144 {
@@ -106,14 +148,18 @@ inline void GetTypeName2(ICorProfilerInfo15 *pInfo, IMetaDataImport2 *pMetaDataI
106148 std::basic_string<WCHAR > out;
107149 if (IsTdNested (flags))
108150 {
109- mdToken mdEnclosingClass;
110- pMetaDataImport->GetNestedClassProps (mdType, &mdEnclosingClass);
111-
112- std::vector<WCHAR > enclosing (bufferLen);
113- enclosing[0 ] = static_cast <WCHAR >(0 );
114- GetTypeName2 (pInfo, pMetaDataImport, mdEnclosingClass, numGenericTypeArgs, genericTypeArgs, enclosing.data (), bufferLen);
115- out += enclosing.data ();
116- out += static_cast <WCHAR >(u' +' );
151+ mdToken mdEnclosingClass = mdTokenNil;
152+ if (SUCCEEDED (pMetaDataImport->GetNestedClassProps (mdType, &mdEnclosingClass)) && mdEnclosingClass != mdTokenNil && mdEnclosingClass != mdType)
153+ {
154+ std::vector<WCHAR > enclosing (bufferLen);
155+ enclosing[0 ] = static_cast <WCHAR >(0 );
156+ GetTypeName2 (pInfo, pMetaDataImport, mdEnclosingClass, numGenericTypeArgs, genericTypeArgs, enclosing.data (), bufferLen, recursionDepth + 1 );
157+ if (enclosing[0 ] != static_cast <WCHAR >(0 ))
158+ {
159+ out += enclosing.data ();
160+ out += static_cast <WCHAR >(u' +' );
161+ }
162+ }
117163 }
118164 if (numGenericTypeArgs > 0 )
119165 {
@@ -124,12 +170,24 @@ inline void GetTypeName2(ICorProfilerInfo15 *pInfo, IMetaDataImport2 *pMetaDataI
124170
125171 for (size_t currentGenericArg = 0 ; currentGenericArg < numGenericTypeArgs; currentGenericArg++)
126172 {
127- ClassID argClassId = genericTypeArgs[currentGenericArg];
128- ModuleID argModuleId;
129- pInfo->GetClassIDInfo2 (argClassId, &argModuleId, NULL , 0 , NULL , NULL , NULL );
173+ ClassID argClassId = (genericTypeArgs != nullptr ) ? genericTypeArgs[currentGenericArg] : 0 ;
130174 WCHAR argTypeName[260 ];
131- GetTypeName (pInfo, pMetaDataImport, argClassId, argModuleId, argTypeName, 260 );
132- out += argTypeName;
175+ argTypeName[0 ] = static_cast <WCHAR >(0 );
176+
177+ if (pInfo != nullptr && argClassId != 0 )
178+ {
179+ ModuleID argModuleId = 0 ;
180+ if (SUCCEEDED (pInfo->GetClassIDInfo2 (argClassId, &argModuleId, NULL , 0 , NULL , NULL , NULL )) && argModuleId != 0 )
181+ {
182+ // Always resolve generic arg names with metadata from its own module.
183+ GetTypeName (pInfo, nullptr , argClassId, argModuleId, argTypeName, ARRAY_LEN (argTypeName));
184+ }
185+ }
186+
187+ if (argTypeName[0 ] != static_cast <WCHAR >(0 ))
188+ out += argTypeName;
189+ else
190+ out += static_cast <WCHAR >(u' ?' );
133191
134192 if (currentGenericArg < numGenericTypeArgs - 1 )
135193 {
0 commit comments