[x86/Linux] Use CDECL (instead of STDCALL) as STDMETHODCALLTYPE
[platform/upstream/coreclr.git] / src / vm / typestring.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 // ---------------------------------------------------------------------------
5 // typestring.cpp
6 // ---------------------------------------------------------------------------
7 //
8
9 //
10 // This module contains a helper function used to produce string
11 // representations of types, with options to control the appearance of
12 // namespace and assembly information.  Its primary use is in
13 // reflection (Type.Name, Type.FullName, Type.ToString, etc) but over
14 // time it could replace the use of TypeHandle.GetName etc for
15 // diagnostic messages.
16 //
17 // See the header file for more details
18 // ---------------------------------------------------------------------------
19
20
21 #include "common.h"
22 #include "class.h"
23 #include "typehandle.h"
24 #include "sstring.h"
25 #include "sigformat.h"
26 #include "typeparse.h"
27 #include "typestring.h"
28 #include "ex.h"
29 #include "typedesc.h"
30
31 #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
32 TypeNameBuilder * QCALLTYPE TypeNameBuilder::_CreateTypeNameBuilder()
33
34     QCALL_CONTRACT;
35
36     TypeNameBuilder * retVal = NULL;
37     BEGIN_QCALL;
38     retVal = new TypeNameBuilder();
39     END_QCALL;
40
41     return retVal;
42
43
44 void QCALLTYPE TypeNameBuilder::_ReleaseTypeNameBuilder(TypeNameBuilder * pTnb) 
45 {
46     QCALL_CONTRACT;
47
48     BEGIN_QCALL;
49     delete pTnb;
50     END_QCALL;
51
52
53 void QCALLTYPE TypeNameBuilder::_ToString(TypeNameBuilder * pTnb, QCall::StringHandleOnStack retString)
54 {
55     QCALL_CONTRACT;
56
57     BEGIN_QCALL;
58     retString.Set(*pTnb->GetString());
59     END_QCALL;
60
61
62 void QCALLTYPE TypeNameBuilder::_AddName(TypeNameBuilder * pTnb, LPCWSTR wszName) 
63 {
64     QCALL_CONTRACT;
65
66     BEGIN_QCALL;
67     pTnb->AddName(wszName); 
68     END_QCALL;
69
70
71 void QCALLTYPE TypeNameBuilder::_AddAssemblySpec(TypeNameBuilder * pTnb, LPCWSTR wszAssemblySpec) 
72 {
73     QCALL_CONTRACT;
74
75     BEGIN_QCALL;
76     pTnb->AddAssemblySpec(wszAssemblySpec); 
77     END_QCALL;
78
79
80 void QCALLTYPE TypeNameBuilder::_OpenGenericArguments(TypeNameBuilder * pTnb) 
81 {
82     QCALL_CONTRACT;
83
84     BEGIN_QCALL;
85     pTnb->OpenGenericArguments(); 
86     END_QCALL;
87
88
89 void QCALLTYPE TypeNameBuilder::_CloseGenericArguments(TypeNameBuilder * pTnb) 
90 {
91     QCALL_CONTRACT;
92
93     BEGIN_QCALL;
94     pTnb->CloseGenericArguments(); 
95     END_QCALL;
96
97
98 void QCALLTYPE TypeNameBuilder::_OpenGenericArgument(TypeNameBuilder * pTnb) 
99 {
100     QCALL_CONTRACT;
101
102     BEGIN_QCALL;
103     pTnb->OpenGenericArgument(); 
104     END_QCALL;
105
106
107 void QCALLTYPE TypeNameBuilder::_CloseGenericArgument(TypeNameBuilder * pTnb) 
108 {
109     QCALL_CONTRACT;
110
111     BEGIN_QCALL;
112     pTnb->CloseGenericArgument(); 
113     END_QCALL;
114
115
116 void QCALLTYPE TypeNameBuilder::_AddPointer(TypeNameBuilder * pTnb) 
117 {
118     QCALL_CONTRACT;
119
120     BEGIN_QCALL;
121     pTnb->AddPointer(); 
122     END_QCALL;
123
124
125 void QCALLTYPE TypeNameBuilder::_AddByRef(TypeNameBuilder * pTnb) 
126 {
127     QCALL_CONTRACT;
128
129     BEGIN_QCALL;
130     pTnb->AddByRef(); 
131     END_QCALL;
132
133
134 void QCALLTYPE TypeNameBuilder::_AddSzArray(TypeNameBuilder * pTnb) 
135 {
136     QCALL_CONTRACT;
137
138     BEGIN_QCALL;
139     pTnb->AddSzArray(); 
140     END_QCALL;
141
142
143 void QCALLTYPE TypeNameBuilder::_AddArray(TypeNameBuilder * pTnb, DWORD dwRank) 
144 {
145     QCALL_CONTRACT;
146
147     BEGIN_QCALL;
148     pTnb->AddArray(dwRank); 
149     END_QCALL;
150 }
151     
152 void QCALLTYPE TypeNameBuilder::_Clear(TypeNameBuilder * pTnb) 
153 {
154     QCALL_CONTRACT;
155
156     BEGIN_QCALL;
157     pTnb->Clear(); 
158     END_QCALL;
159
160
161 #endif
162
163 //
164 // TypeNameBuilder
165 //
166 TypeNameBuilder::TypeNameBuilder(SString* pStr, ParseState parseState /*= ParseStateSTART*/) : 
167     m_pStr(NULL)
168
169     CONTRACTL
170     {
171         THROWS;
172         GC_NOTRIGGER;
173         MODE_ANY;
174     }
175     CONTRACTL_END;
176     Clear(); 
177     m_pStr = pStr;
178     m_parseState = parseState; 
179 }
180
181 void TypeNameBuilder::PushOpenGenericArgument()
182 {
183     WRAPPER_NO_CONTRACT;
184
185     m_stack.Push(m_pStr->GetCount());
186 }
187
188 void TypeNameBuilder::PopOpenGenericArgument()
189 {
190     CONTRACTL
191     {
192         THROWS;
193         GC_NOTRIGGER;
194         MODE_ANY;
195     }
196     CONTRACTL_END;
197
198     COUNT_T index = m_stack.Pop();
199         
200     if (!m_bHasAssemblySpec)
201         m_pStr->Delete(m_pStr->Begin() + index - 1, 1);
202     
203     m_bHasAssemblySpec = FALSE;
204 }
205
206 /* This method escapes szName and appends it to this TypeNameBuilder */
207 void TypeNameBuilder::EscapeName(LPCWSTR szName)
208 {
209     CONTRACTL
210     {
211         THROWS;
212         GC_NOTRIGGER;
213         MODE_ANY;
214     }
215     CONTRACTL_END;
216
217     if (TypeString::ContainsReservedChar(szName))
218     {
219         while (* szName)
220         {
221             WCHAR c = * szName ++;
222
223             if (IsTypeNameReservedChar(c))
224                 Append(W('\\'));
225         
226             Append(c);
227         }
228     }
229     else
230     {
231         Append(szName);
232     }
233 }
234
235 void TypeNameBuilder::EscapeAssemblyName(LPCWSTR szName)
236 {
237     WRAPPER_NO_CONTRACT; 
238
239     Append(szName);
240 }
241
242 void TypeNameBuilder::EscapeEmbeddedAssemblyName(LPCWSTR szName)
243 {
244     CONTRACTL
245     {
246         THROWS;
247         GC_NOTRIGGER;
248         MODE_ANY;
249     }
250     CONTRACTL_END;
251
252     LPCWSTR itr = szName;
253     bool bContainsReservedChar = false;
254     
255     while (*itr)
256     {
257         if (W(']') == *itr++)
258         {
259             bContainsReservedChar = true;
260             break;
261         }
262     }
263     
264     if (bContainsReservedChar)
265     {
266         itr = szName;
267         while (*itr)
268         {
269             WCHAR c = *itr++;
270             if (c == ']')
271                 Append(W('\\'));
272
273             Append(c);
274         }
275     }
276     else
277     {
278         Append(szName);
279     }
280 }
281
282 HRESULT TypeNameBuilder::OpenGenericArgument() 
283
284     CONTRACTL
285     {
286         THROWS;
287         GC_NOTRIGGER;
288         MODE_ANY;
289     }
290     CONTRACTL_END;
291
292     if (!CheckParseState(ParseStateSTART))
293         return Fail();
294
295     if (m_instNesting == 0)
296         return Fail();
297
298     HRESULT hr = S_OK;
299
300     m_parseState = ParseStateSTART;
301     m_bNestedName = FALSE;
302
303     if (!m_bFirstInstArg)
304         Append(W(','));
305
306     m_bFirstInstArg = FALSE;
307
308     if (m_bUseAngleBracketsForGenerics)
309         Append(W('<'));
310     else
311         Append(W('['));
312     PushOpenGenericArgument();
313     
314     return hr;
315 }
316
317 HRESULT TypeNameBuilder::AddName(LPCWSTR szName) 
318
319     CONTRACTL
320     {
321         THROWS;
322         GC_NOTRIGGER;
323         MODE_ANY;
324     }
325     CONTRACTL_END;
326
327     if (!szName)
328         return Fail();
329     
330     if (!CheckParseState(ParseStateSTART | ParseStateNAME))
331         return Fail();
332
333     HRESULT hr = S_OK;
334
335     m_parseState = ParseStateNAME;
336
337     if (m_bNestedName)
338         Append(W('+')); 
339
340     m_bNestedName = TRUE;
341
342     EscapeName(szName); 
343
344     return hr;
345 }
346
347 HRESULT TypeNameBuilder::AddName(LPCWSTR szName, LPCWSTR szNamespace) 
348
349     CONTRACTL
350     {
351         THROWS;
352         GC_NOTRIGGER;
353         MODE_ANY;
354     }
355     CONTRACTL_END;
356
357     if (!szName)
358         return Fail();
359     
360     if (!CheckParseState(ParseStateSTART | ParseStateNAME))
361         return Fail();
362
363     HRESULT hr = S_OK;
364
365     m_parseState = ParseStateNAME;
366
367     if (m_bNestedName)
368         Append(W('+')); 
369
370     m_bNestedName = TRUE;
371
372     if (szNamespace && *szNamespace)
373     {
374         EscapeName(szNamespace); 
375         Append(W('.'));
376     }
377
378     EscapeName(szName); 
379
380     return hr;
381 }
382
383 HRESULT TypeNameBuilder::OpenGenericArguments() 
384
385     WRAPPER_NO_CONTRACT; 
386     
387     if (!CheckParseState(ParseStateNAME))
388         return Fail();
389
390     HRESULT hr = S_OK;
391
392     m_parseState = ParseStateSTART;
393     m_instNesting ++;
394     m_bFirstInstArg = TRUE;
395
396     if (m_bUseAngleBracketsForGenerics)
397         Append(W('<'));
398     else
399         Append(W('['));
400
401     return hr;
402 }
403
404 HRESULT TypeNameBuilder::CloseGenericArguments() 
405
406     CONTRACTL
407     {
408         THROWS;
409         GC_NOTRIGGER;
410         MODE_ANY;
411     }
412     CONTRACTL_END;
413
414     if (!m_instNesting)
415         return Fail();
416     if (!CheckParseState(ParseStateSTART))
417         return Fail();
418
419     HRESULT hr = S_OK;
420
421     m_parseState = ParseStateGENARGS;
422
423     m_instNesting --;
424
425     if (m_bFirstInstArg)
426     {
427         m_pStr->Truncate(m_pStr->End() - 1);
428     }    
429     else
430     {
431         if (m_bUseAngleBracketsForGenerics)
432             Append(W('>')); 
433         else
434             Append(W(']')); 
435     }
436
437     return hr;
438 }
439
440 HRESULT TypeNameBuilder::AddPointer() 
441
442     WRAPPER_NO_CONTRACT; 
443     
444     if (!CheckParseState(ParseStateNAME | ParseStateGENARGS | ParseStatePTRARR))
445         return Fail();
446
447     m_parseState = ParseStatePTRARR;
448     
449     Append(W('*')); 
450
451     return S_OK;
452 }
453
454 HRESULT TypeNameBuilder::AddByRef() 
455
456     WRAPPER_NO_CONTRACT;
457
458     if (!CheckParseState(ParseStateNAME | ParseStateGENARGS | ParseStatePTRARR))
459         return Fail();
460
461     m_parseState = ParseStateBYREF;
462     
463     Append(W('&'));
464
465     return S_OK;
466 }
467
468 HRESULT TypeNameBuilder::AddSzArray() 
469
470     WRAPPER_NO_CONTRACT; 
471     
472     if (!CheckParseState(ParseStateNAME | ParseStateGENARGS | ParseStatePTRARR))
473         return Fail();
474
475     m_parseState = ParseStatePTRARR;
476     
477     Append(W("[]")); 
478
479     return S_OK;
480
481
482 HRESULT TypeNameBuilder::AddArray(DWORD rank)
483 {
484     CONTRACTL
485     {
486         THROWS;
487         GC_NOTRIGGER;
488         MODE_ANY;
489     }
490     CONTRACTL_END;
491     
492     if (!CheckParseState(ParseStateNAME | ParseStateGENARGS | ParseStatePTRARR))
493         return Fail();
494
495     m_parseState = ParseStatePTRARR;
496         
497     if (rank <= 0)
498         return E_INVALIDARG;
499
500     if (rank == 1)
501         Append(W("[*]"));
502     else if (rank > 64)
503     {
504         // Only taken in an error path, runtime will not load arrays of more than 32 dimentions
505         WCHAR wzDim[128];
506         _snwprintf_s(wzDim, 128, _TRUNCATE, W("[%d]"), rank);
507         Append(wzDim);
508     }
509     else
510     {
511         WCHAR* wzDim = new (nothrow) WCHAR[rank+3];
512             
513         if(wzDim == NULL) // allocation failed, do it the long way (each Append -> memory realloc)
514         {
515             Append(W('['));
516             for(COUNT_T i = 1; i < rank; i ++)
517                 Append(W(','));
518             Append(W(']'));
519         }
520         else             // allocation OK, do it the fast way
521         {
522             WCHAR* pwz = wzDim+1;
523             *wzDim = '[';
524             for(COUNT_T i = 1; i < rank; i++, pwz++) *pwz=',';
525             *pwz = ']';
526             *(++pwz) = 0;
527             Append(wzDim);
528             delete [] wzDim;
529         }
530     }
531
532     return S_OK;
533 }
534
535 HRESULT TypeNameBuilder::CloseGenericArgument()
536 {
537     CONTRACTL
538     {
539         THROWS;
540         GC_NOTRIGGER;
541         MODE_ANY;
542     }
543     CONTRACTL_END;
544     
545     if (!CheckParseState(ParseStateNAME | ParseStateGENARGS | ParseStatePTRARR | ParseStateBYREF | ParseStateASSEMSPEC))
546         return Fail();
547
548     if (m_instNesting == 0)
549         return Fail();
550     
551     m_parseState = ParseStateSTART;
552     
553     if (m_bHasAssemblySpec)
554     {
555         if (m_bUseAngleBracketsForGenerics)
556             Append(W('>')); 
557         else
558             Append(W(']')); 
559     }
560
561     PopOpenGenericArgument();
562
563     return S_OK;
564 }
565
566 HRESULT TypeNameBuilder::AddAssemblySpec(LPCWSTR szAssemblySpec)
567 {
568     CONTRACTL
569     {
570         THROWS;
571         GC_NOTRIGGER;
572         MODE_ANY;
573     }
574     CONTRACTL_END;
575
576     if (!CheckParseState(ParseStateNAME | ParseStateGENARGS | ParseStatePTRARR | ParseStateBYREF))
577         return Fail();
578
579     HRESULT hr = S_OK;
580     
581     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
582     
583     m_parseState = ParseStateASSEMSPEC;
584
585     if (szAssemblySpec && *szAssemblySpec)
586     {
587         Append(W(", "));
588         
589         if (m_instNesting > 0)
590         {
591             EscapeEmbeddedAssemblyName(szAssemblySpec);
592         }
593         else
594         {
595             EscapeAssemblyName(szAssemblySpec);
596         }
597
598         m_bHasAssemblySpec = TRUE;
599         hr = S_OK;
600     }
601
602     END_SO_INTOLERANT_CODE;
603     
604     return hr;
605 }
606
607 HRESULT TypeNameBuilder::ToString(BSTR* pszStringRepresentation)
608 {
609     WRAPPER_NO_CONTRACT;
610
611     if (!CheckParseState(ParseStateNAME | ParseStateGENARGS | ParseStatePTRARR | ParseStateBYREF | ParseStateASSEMSPEC))
612         return Fail();
613
614     if (m_instNesting)
615         return Fail();
616
617     *pszStringRepresentation = SysAllocString(m_pStr->GetUnicode());
618
619     return S_OK;
620 }
621
622 HRESULT TypeNameBuilder::Clear()
623 {
624     CONTRACTL
625     {
626         THROWS; // TypeNameBuilder::Stack::Clear might throw.
627         GC_NOTRIGGER;
628         MODE_ANY;
629     }
630     CONTRACTL_END;
631
632     CONTRACT_VIOLATION(SOToleranceViolation);
633
634     if (m_pStr)
635     {   
636         m_pStr->Clear();
637     }
638     m_bNestedName = FALSE;
639     m_instNesting = 0;
640     m_bFirstInstArg = FALSE;
641     m_parseState = ParseStateSTART;
642     m_bHasAssemblySpec = FALSE;
643     m_bUseAngleBracketsForGenerics = FALSE;
644     m_stack.Clear();
645     
646     return S_OK;
647 }
648
649
650
651 // Append the name of the type td to the string
652 // The following flags in the FormatFlags argument are significant: FormatNamespace 
653 void TypeString::AppendTypeDef(SString& ss, IMDInternalImport *pImport, mdTypeDef td, DWORD format)
654 {
655     CONTRACT_VOID
656     {
657         MODE_ANY;
658         GC_NOTRIGGER;
659         THROWS;
660     }
661     CONTRACT_END
662
663     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(COMPlusThrowSO());
664     {
665         TypeNameBuilder tnb(&ss, TypeNameBuilder::ParseStateNAME);
666         AppendTypeDef(tnb, pImport, td, format);    
667     }
668     END_SO_INTOLERANT_CODE;
669
670     RETURN;
671 }
672
673
674 void TypeString::AppendTypeDef(TypeNameBuilder& tnb, IMDInternalImport *pImport, mdTypeDef td, DWORD format) 
675 {
676     CONTRACT_VOID
677     {
678         MODE_ANY;
679         GC_NOTRIGGER;
680         THROWS;
681         PRECONDITION(CheckPointer(pImport));
682         PRECONDITION(TypeFromToken(td) == mdtTypeDef);
683     }
684     CONTRACT_END
685
686     LPCUTF8 szName;
687     LPCUTF8 szNameSpace;
688     IfFailThrow(pImport->GetNameOfTypeDef(td, &szName, &szNameSpace));
689     
690     const WCHAR *wszNameSpace = NULL;
691
692     InlineSString<128> ssName(SString::Utf8, szName);
693     InlineSString<128> ssNameSpace;
694
695     if (format & FormatNamespace)
696     {
697         ssNameSpace.SetUTF8(szNameSpace);
698         wszNameSpace = ssNameSpace.GetUnicode();
699     }
700
701     tnb.AddName(ssName.GetUnicode(), wszNameSpace);
702
703     RETURN;
704 }
705
706 void TypeString::AppendNestedTypeDef(TypeNameBuilder& tnb, IMDInternalImport *pImport, mdTypeDef td, DWORD format)
707 {
708     CONTRACT_VOID
709     {
710         MODE_ANY;
711         GC_NOTRIGGER;
712         THROWS;
713         PRECONDITION(CheckPointer(pImport));
714         PRECONDITION(TypeFromToken(td) == mdtTypeDef);
715     }
716     CONTRACT_END
717     
718     DWORD dwAttr;
719     IfFailThrow(pImport->GetTypeDefProps(td, &dwAttr, NULL));
720     
721     StackSArray<mdTypeDef> arNames;
722     arNames.Append(td);
723     if (format & FormatNamespace && IsTdNested(dwAttr)) 
724     {   
725         while (SUCCEEDED(pImport->GetNestedClassProps(td, &td))) 
726             arNames.Append(td);
727     }   
728     
729     for(SCOUNT_T i = arNames.GetCount() - 1; i >= 0; i --)
730         AppendTypeDef(tnb, pImport, arNames[i], format);
731     
732     RETURN;
733 }
734
735 // Append a square-bracket-enclosed, comma-separated list of n type parameters in inst to the string s
736 // and enclose each parameter in square brackets to disambiguate the commas
737 // The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly FormatNoVersion
738 void TypeString::AppendInst(SString& ss, Instantiation inst, DWORD format) 
739 {
740     CONTRACT_VOID
741     {
742         MODE_ANY;
743         if (format & (FormatAssembly|FormatFullInst)) GC_TRIGGERS; else GC_NOTRIGGER;
744         THROWS;
745     }
746     CONTRACT_END
747
748     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(COMPlusThrowSO());
749     {
750         TypeNameBuilder tnb(&ss, TypeNameBuilder::ParseStateNAME);
751         if ((format & FormatAngleBrackets) != 0)
752             tnb.SetUseAngleBracketsForGenerics(TRUE);
753         AppendInst(tnb, inst, format);
754     }
755     END_SO_INTOLERANT_CODE;
756
757     RETURN;
758 }
759
760 void TypeString::AppendInst(TypeNameBuilder& tnb, Instantiation inst, DWORD format) 
761 {
762     CONTRACT_VOID
763     {
764         MODE_ANY;
765         THROWS;
766         if (format & (FormatAssembly|FormatFullInst)) GC_TRIGGERS; else GC_NOTRIGGER;
767         PRECONDITION(!inst.IsEmpty());
768     }
769     CONTRACT_END
770
771     tnb.OpenGenericArguments();
772
773     for (DWORD i = 0; i < inst.GetNumArgs(); i++) 
774     {
775         tnb.OpenGenericArgument();
776
777         TypeHandle thArg = inst[i];
778
779         if ((format & FormatFullInst) != 0 && !thArg.IsGenericVariable()) 
780         {
781             AppendType(tnb, thArg, Instantiation(), format | FormatNamespace | FormatAssembly);
782         }
783         else
784         {
785             AppendType(tnb, thArg, Instantiation(), format & (FormatNamespace | FormatAngleBrackets
786 #ifdef _DEBUG
787                                                | FormatDebug
788 #endif
789                                                ));
790         }
791
792         tnb.CloseGenericArgument();
793     }
794
795     tnb.CloseGenericArguments();
796
797     RETURN;
798 }
799
800 void TypeString::AppendParamTypeQualifier(TypeNameBuilder& tnb, CorElementType kind, DWORD rank)
801 {
802     CONTRACTL
803     {
804         MODE_ANY;
805         THROWS;
806         GC_NOTRIGGER;
807         PRECONDITION(CorTypeInfo::IsModifier(kind));
808     }
809     CONTRACTL_END
810
811     switch (kind)
812     {
813     case ELEMENT_TYPE_BYREF :
814         tnb.AddByRef();
815         break;
816     case ELEMENT_TYPE_PTR :
817         tnb.AddPointer();
818         break;
819     case ELEMENT_TYPE_SZARRAY :
820         tnb.AddSzArray();
821         break;
822     case ELEMENT_TYPE_ARRAY :        
823         tnb.AddArray(rank);
824         break;
825     default :
826         break;
827     }
828 }
829
830 // Append a representation of the type t to the string s
831 // The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly FormatNoVersion
832
833 void TypeString::AppendType(SString& ss, TypeHandle ty, DWORD format) 
834 {
835     CONTRACT_VOID
836     {
837         MODE_ANY;
838         if (format & (FormatAssembly|FormatFullInst)) GC_TRIGGERS; else GC_NOTRIGGER;
839         THROWS;        
840     }
841     CONTRACT_END
842     
843     AppendType(ss, ty, Instantiation(), format);
844
845     RETURN;
846 }
847
848 void TypeString::AppendType(SString& ss, TypeHandle ty, Instantiation typeInstantiation, DWORD format) 
849 {
850     CONTRACT_VOID
851     {
852         MODE_ANY;
853         if (format & (FormatAssembly|FormatFullInst)) GC_TRIGGERS; else GC_NOTRIGGER;
854         THROWS;        
855     }
856     CONTRACT_END
857     
858     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(COMPlusThrowSO());
859     {
860         TypeNameBuilder tnb(&ss);
861         if ((format & FormatAngleBrackets) != 0)
862             tnb.SetUseAngleBracketsForGenerics(TRUE);
863         AppendType(tnb, ty, typeInstantiation, format);
864     }
865     END_SO_INTOLERANT_CODE;
866
867     RETURN;
868 }
869
870 void TypeString::AppendType(TypeNameBuilder& tnb, TypeHandle ty, Instantiation typeInstantiation, DWORD format) 
871 {
872     CONTRACT_VOID
873     {
874         MODE_ANY;
875         
876         /* This method calls Assembly::GetDisplayName. Since that function
877         uses Fusion which takes some Crsts in some places, it is GC_TRIGGERS. 
878         It could be made GC_NOTRIGGER by factoring out Assembly::GetDisplayName.
879         However, its better to leave stuff as GC_TRIGGERS unless really needed, 
880         as GC_NOTRIGGER ties your hands up. */
881         if (format & (FormatAssembly|FormatFullInst)) GC_TRIGGERS; else GC_NOTRIGGER;
882         THROWS;        
883     }
884     CONTRACT_END
885
886     INTERIOR_STACK_PROBE_FOR_CHECK_THREAD(10);
887
888     BOOL bToString = (format & (FormatNamespace|FormatFullInst|FormatAssembly)) == FormatNamespace;
889
890     // It's null!
891     if (ty.IsNull())
892     {
893         tnb.AddName(W("(null)"));
894     }
895     else
896     // It's not restored yet!
897     if (ty.IsEncodedFixup())
898     {
899         tnb.AddName(W("(fixup)"));
900     }
901     else
902
903     // It's an array, with format 
904     //   element_ty[] (1-d, SZARRAY) 
905     //   element_ty[*] (1-d, ARRAY)
906     //   element_ty[,] (2-d, ARRAY) etc
907     // or a pointer (*) or byref (&)
908     if (ty.HasTypeParam() || (!ty.IsTypeDesc() && ty.AsMethodTable()->IsArray())) 
909     {
910         if (ty.GetSignatureCorElementType() != ELEMENT_TYPE_VALUETYPE)
911         {
912             DWORD rank;
913             TypeHandle elemType;
914             if (ty.HasTypeParam())
915             {
916                 rank = ty.IsArray() ? ty.AsArray()->GetRank() : 0; 
917                 elemType = ty.GetTypeParam();
918             }
919             else
920             {
921                 MethodTable *pMT = ty.GetMethodTable();
922                 PREFIX_ASSUME(pMT != NULL);
923                 rank = pMT->GetRank();
924                 elemType = pMT->GetApproxArrayElementTypeHandle();
925             }
926
927             _ASSERTE(!elemType.IsNull());
928             AppendType(tnb, elemType, Instantiation(), format & ~FormatAssembly);
929             AppendParamTypeQualifier(tnb, ty.GetSignatureCorElementType(), rank);
930         }
931         else
932         {
933             tnb.Append(W("VALUETYPE"));
934             TypeHandle elemType = ty.GetTypeParam();
935             AppendType(tnb, elemType, Instantiation(), format & ~FormatAssembly);
936         }
937     }
938
939     // ...or type parameter
940     else if (ty.IsGenericVariable()) 
941     {
942         PTR_TypeVarTypeDesc tyvar = dac_cast<PTR_TypeVarTypeDesc>(ty.AsTypeDesc());
943
944         mdGenericParam token = tyvar->GetToken();
945         
946         LPCSTR szName = NULL;
947         mdToken mdOwner;
948         
949         IfFailThrow(ty.GetModule()->GetMDImport()->GetGenericParamProps(token, NULL, NULL, &mdOwner, NULL, &szName));
950
951         _ASSERTE(TypeFromToken(mdOwner) == mdtTypeDef || TypeFromToken(mdOwner) == mdtMethodDef);
952             
953         LPCSTR szPrefix;
954         if (!(format & FormatGenericParam))
955             szPrefix = "";
956         else if (TypeFromToken(mdOwner) == mdtTypeDef)
957             szPrefix = "!";
958         else
959             szPrefix = "!!";
960
961         SmallStackSString pName(SString::Utf8, szPrefix);
962         pName.AppendUTF8(szName);
963         tnb.AddName(pName.GetUnicode());
964             
965         format &= ~FormatAssembly;
966     }
967     
968     // ...or function pointer
969     else if (ty.IsFnPtrType())
970     {
971         // Don't attempt to format this currently, it may trigger GC due to fixups.
972         tnb.AddName(W("(fnptr)"));
973     }
974
975     // ...otherwise it's just a plain type def or an instantiated type
976     else 
977     {
978         // Get the TypeDef token and attributes
979         IMDInternalImport *pImport = ty.GetMethodTable()->GetMDImport();
980         mdTypeDef td = ty.GetCl();
981         if (IsNilToken(td)) {
982             // This type does not exist in metadata. Simply append "dynamicClass".
983             tnb.AddName(W("(dynamicClass)"));
984         }
985         else
986         {
987 #ifdef _DEBUG
988             if (format & FormatDebug)
989             {
990                 WCHAR wzAddress[128];
991                 _snwprintf_s(wzAddress, 128, _TRUNCATE, W("(%p)"), dac_cast<TADDR>(ty.AsPtr()));
992                 tnb.AddName(wzAddress);
993             }
994 #endif
995             AppendNestedTypeDef(tnb, pImport, td, format);
996         }
997
998         // Append the instantiation
999         if ((format & (FormatNamespace|FormatAssembly)) && ty.HasInstantiation() && (!ty.IsGenericTypeDefinition() || bToString))
1000         {
1001             if (typeInstantiation.IsEmpty())
1002                 AppendInst(tnb, ty.GetInstantiation(), format);
1003             else
1004                 AppendInst(tnb, typeInstantiation, format);
1005         }
1006     }
1007
1008     // Now append the assembly
1009     if (format & FormatAssembly) 
1010     {
1011         Assembly* pAssembly = ty.GetAssembly();
1012         _ASSERTE(pAssembly != NULL);
1013
1014         StackSString pAssemblyName;
1015 #ifdef DACCESS_COMPILE
1016         pAssemblyName.SetUTF8(pAssembly->GetSimpleName());
1017 #else
1018         pAssembly->GetDisplayName(pAssemblyName,
1019                                   ASM_DISPLAYF_PUBLIC_KEY_TOKEN | ASM_DISPLAYF_CONTENT_TYPE |
1020                                   (format & FormatNoVersion ? 0 : ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE));
1021 #endif
1022
1023         tnb.AddAssemblySpec(pAssemblyName.GetUnicode());
1024
1025     }  
1026     
1027     END_INTERIOR_STACK_PROBE;
1028
1029
1030   RETURN;
1031 }
1032
1033 void TypeString::AppendMethod(SString& s, MethodDesc *pMD, Instantiation typeInstantiation, const DWORD format)
1034 {
1035     CONTRACTL
1036     {
1037         MODE_ANY;
1038         GC_TRIGGERS;
1039         THROWS;
1040         PRECONDITION(CheckPointer(pMD));
1041         PRECONDITION(pMD->IsRestored_NoLogging());
1042         PRECONDITION(s.Check());
1043     }
1044     CONTRACTL_END
1045
1046     AppendMethodImpl(s, pMD, typeInstantiation, format);
1047 }
1048
1049 void TypeString::AppendMethodInternal(SString& s, MethodDesc *pMD, const DWORD format)
1050 {
1051     CONTRACTL
1052     {
1053         MODE_ANY;
1054         GC_TRIGGERS;
1055         SUPPORTS_DAC;
1056         THROWS;
1057         PRECONDITION(CheckPointer(pMD));
1058         PRECONDITION(pMD->IsRestored_NoLogging());
1059         PRECONDITION(s.Check());
1060     }
1061     CONTRACTL_END
1062
1063     AppendMethodImpl(s, pMD, Instantiation(), format);
1064 }
1065
1066 void TypeString::AppendMethodImpl(SString& ss, MethodDesc *pMD, Instantiation typeInstantiation, const DWORD format)
1067 {
1068     CONTRACTL
1069     {
1070         MODE_ANY;
1071         GC_TRIGGERS;
1072         SUPPORTS_DAC;
1073         THROWS;
1074         PRECONDITION(CheckPointer(pMD));
1075         PRECONDITION(pMD->IsRestored_NoLogging());
1076         PRECONDITION(ss.Check());
1077     }
1078     CONTRACTL_END
1079
1080     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(COMPlusThrowSO());
1081     {
1082         TypeHandle th;
1083         
1084         if (pMD->IsDynamicMethod())
1085         {
1086             if (pMD->IsLCGMethod())
1087             {
1088                 SString sss(SString::Literal, "DynamicClass");
1089                 ss += sss;
1090             }
1091             else if (pMD->IsILStub())
1092             {
1093                 SString sss(SString::Literal, ILStubResolver::GetStubClassName(pMD));
1094                 ss += sss;
1095             }
1096         }
1097         else 
1098         {
1099             th = TypeHandle(pMD->GetMethodTable());
1100             AppendType(ss, th, typeInstantiation, format);
1101         }
1102         
1103         SString sss1(SString::Literal, NAMESPACE_SEPARATOR_STR);
1104         ss += sss1;
1105         SString sss2(SString::Utf8, pMD->GetName());
1106         ss += sss2;
1107
1108         if (pMD->HasMethodInstantiation() && !pMD->IsGenericMethodDefinition())
1109         {
1110             AppendInst(ss, pMD->GetMethodInstantiation(), format);
1111         }
1112         
1113         if (format & FormatSignature)
1114         {
1115             // @TODO: The argument list should be formatted nicely using AppendType()
1116             
1117             SigFormat sigFormatter(pMD, th);
1118             const char* sigStr = sigFormatter.GetCStringParmsOnly();
1119             SString sss(SString::Utf8, sigStr);
1120             ss += sss;
1121         }
1122         
1123         if (format & FormatStubInfo) {
1124             if (pMD->IsInstantiatingStub())
1125             {
1126                 SString sss(SString::Literal, "{inst-stub}");
1127                 ss += sss;
1128             }
1129             if (pMD->IsUnboxingStub())
1130             {
1131                 SString sss(SString::Literal, "{unbox-stub}");
1132                 ss += sss;
1133             }
1134             if (pMD->IsSharedByGenericMethodInstantiations())
1135             {
1136                 SString sss(SString::Literal, "{method-shared}");
1137                 ss += sss;
1138             }
1139             else if (pMD->IsSharedByGenericInstantiations())
1140             {
1141                 SString sss(SString::Literal, "{shared}");
1142                 ss += sss;
1143             }
1144             if (pMD->RequiresInstMethodTableArg())
1145             {
1146                 SString sss(SString::Literal, "{requires-mt-arg}");
1147                 ss += sss;
1148             }
1149             if (pMD->RequiresInstMethodDescArg())
1150             {
1151                 SString sss(SString::Literal, "{requires-mdesc-arg}");
1152                 ss += sss;
1153             }
1154         }
1155     }
1156     END_SO_INTOLERANT_CODE;
1157 }
1158
1159 void TypeString::AppendField(SString& s, FieldDesc *pFD, Instantiation typeInstantiation, const DWORD format /* = FormatNamespace */)
1160 {
1161     CONTRACTL
1162     {
1163         MODE_ANY;
1164         GC_TRIGGERS;
1165         THROWS;
1166         PRECONDITION(CheckPointer(pFD));
1167         PRECONDITION(s.Check());
1168     }
1169     CONTRACTL_END;
1170
1171     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(COMPlusThrowSO());
1172     {
1173         TypeHandle th(pFD->GetApproxEnclosingMethodTable());
1174         AppendType(s, th, typeInstantiation, format);
1175
1176         s.AppendUTF8(NAMESPACE_SEPARATOR_STR);
1177         s.AppendUTF8(pFD->GetName());
1178     }
1179     END_SO_INTOLERANT_CODE;
1180 }
1181
1182 #ifdef _DEBUG
1183 void TypeString::AppendMethodDebug(SString& ss, MethodDesc *pMD)
1184 {
1185     CONTRACTL
1186     {
1187         MODE_ANY;
1188         GC_TRIGGERS;
1189         NOTHROW;
1190         PRECONDITION(CheckPointer(pMD));
1191         PRECONDITION(pMD->IsRestored_NoLogging());
1192         PRECONDITION(ss.Check());
1193     }
1194     CONTRACTL_END
1195
1196 #ifndef DACCESS_COMPILE
1197     EX_TRY
1198     {
1199         AppendMethodInternal(ss, pMD, FormatSignature | FormatNamespace);
1200     }
1201     EX_CATCH
1202     {
1203         // This function is only used as diagnostic aid in debug builds.
1204         // If we run out of memory or hit some other problem,
1205         // tough luck for the debugger.
1206
1207         // Should we set ss to Empty
1208     }
1209     EX_END_CATCH(SwallowAllExceptions);
1210 #endif
1211 }
1212
1213 void TypeString::AppendTypeDebug(SString& ss, TypeHandle t)
1214 {
1215     CONTRACTL
1216     {
1217         MODE_ANY;
1218         GC_NOTRIGGER;
1219         NOTHROW;
1220         PRECONDITION(CheckPointer(t));
1221         PRECONDITION(ss.Check());
1222         SO_NOT_MAINLINE;
1223     }
1224     CONTRACTL_END
1225
1226 #ifndef DACCESS_COMPILE
1227     {
1228         EX_TRY
1229         {
1230             AppendType(ss, t, FormatNamespace | FormatDebug);
1231         }
1232         EX_CATCH
1233         {
1234             // This function is only used as diagnostic aid in debug builds. 
1235             // If we run out of memory or hit some other problem,
1236             // tough luck for the debugger.
1237         }
1238         EX_END_CATCH(SwallowAllExceptions);
1239     }
1240 #endif
1241 }
1242
1243 void TypeString::AppendTypeKeyDebug(SString& ss, TypeKey *pTypeKey)
1244 {
1245     CONTRACTL
1246     {
1247         MODE_ANY;
1248         GC_NOTRIGGER;
1249         NOTHROW;
1250         PRECONDITION(CheckPointer(pTypeKey));
1251         PRECONDITION(ss.Check());
1252         SO_NOT_MAINLINE;
1253     }
1254     CONTRACTL_END
1255
1256 #ifndef DACCESS_COMPILE
1257     {
1258         EX_TRY
1259         {
1260             AppendTypeKey(ss, pTypeKey, FormatNamespace | FormatDebug);
1261         }
1262         EX_CATCH
1263         {
1264             // This function is only used as diagnostic aid in debug builds. 
1265             // If we run out of memory or hit some other problem,
1266             // tough luck for the debugger.
1267         }
1268         EX_END_CATCH(SwallowAllExceptions);
1269     }
1270 #endif 
1271 }
1272
1273 #endif // _DEBUG
1274
1275
1276 void TypeString::AppendTypeKey(TypeNameBuilder& tnb, TypeKey *pTypeKey, DWORD format)
1277 {
1278     CONTRACT_VOID
1279     {
1280         MODE_ANY;
1281         THROWS;
1282         if (format & (FormatAssembly|FormatFullInst)) GC_TRIGGERS; else GC_NOTRIGGER;
1283         PRECONDITION(CheckPointer(pTypeKey));
1284         SO_INTOLERANT;
1285     }
1286     CONTRACT_END
1287
1288     Module *pModule = NULL;
1289
1290     // It's an array, with format 
1291     //   element_ty[] (1-d, SZARRAY) 
1292     //   element_ty[*] (1-d, ARRAY)
1293     //   element_ty[,] (2-d, ARRAY) etc
1294     // or a pointer (*) or byref (&)
1295     CorElementType kind = pTypeKey->GetKind();
1296     if (CorTypeInfo::IsModifier(kind))
1297     {
1298         DWORD rank = 0;
1299         TypeHandle elemType = pTypeKey->GetElementType();
1300         if (CorTypeInfo::IsArray(kind))
1301         {
1302             rank = pTypeKey->GetRank();
1303         }
1304
1305         AppendType(tnb, elemType, Instantiation(), format);
1306         AppendParamTypeQualifier(tnb, kind, rank);
1307         pModule = elemType.GetModule();
1308     }
1309     else if (kind == ELEMENT_TYPE_VALUETYPE)
1310     {
1311         tnb.Append(W("VALUETYPE"));
1312         TypeHandle elemType = pTypeKey->GetElementType();
1313         AppendType(tnb, elemType, Instantiation(), format);
1314         pModule = elemType.GetModule();
1315     }
1316     else if (kind == ELEMENT_TYPE_FNPTR)
1317     {
1318         RETURN;
1319     }
1320
1321     // ...otherwise it's just a plain type def or an instantiated type
1322     else 
1323     {
1324         // Get the TypeDef token and attributes
1325         pModule = pTypeKey->GetModule();
1326         if (pModule != NULL)
1327         {
1328             IMDInternalImport *pImport = pModule->GetMDImport();
1329             mdTypeDef td = pTypeKey->GetTypeToken();
1330             _ASSERTE(!IsNilToken(td));
1331
1332             AppendNestedTypeDef(tnb, pImport, td, format);
1333
1334             // Append the instantiation
1335             if ((format & (FormatNamespace|FormatAssembly)) && pTypeKey->HasInstantiation())
1336                 AppendInst(tnb, pTypeKey->GetInstantiation(), format);
1337         }
1338
1339     }
1340
1341     // Now append the assembly
1342     if (pModule != NULL && (format & FormatAssembly))
1343     {
1344         Assembly* pAssembly = pModule->GetAssembly();
1345         _ASSERTE(pAssembly != NULL);
1346
1347         StackSString pAssemblyName;
1348 #ifdef DACCESS_COMPILE
1349         pAssemblyName.SetUTF8(pAssembly->GetSimpleName());
1350 #else
1351         pAssembly->GetDisplayName(pAssemblyName,
1352                                   ASM_DISPLAYF_PUBLIC_KEY_TOKEN | ASM_DISPLAYF_CONTENT_TYPE |
1353                                   (format & FormatNoVersion ? 0 : ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE));
1354 #endif
1355         tnb.AddAssemblySpec(pAssemblyName.GetUnicode());
1356     }            
1357
1358     RETURN;
1359 }
1360
1361 void TypeString::AppendTypeKey(SString& ss, TypeKey *pTypeKey, DWORD format)
1362 {
1363     CONTRACT_VOID
1364     {
1365         MODE_ANY;
1366         if (format & (FormatAssembly|FormatFullInst)) GC_TRIGGERS; else GC_NOTRIGGER;
1367         THROWS;
1368         PRECONDITION(CheckPointer(pTypeKey));
1369     }
1370     CONTRACT_END
1371     
1372     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(COMPlusThrowSO());
1373     {
1374         TypeNameBuilder tnb(&ss);
1375         AppendTypeKey(tnb, pTypeKey, format);
1376     }
1377     END_SO_INTOLERANT_CODE;
1378
1379     RETURN;
1380 }
1381
1382 /*static*/
1383 void TypeString::EscapeSimpleTypeName(SString* ssTypeName, SString* ssEscapedTypeName)
1384 {
1385     SString::Iterator itr = ssTypeName->Begin();
1386     WCHAR c;
1387     while ((c = *itr++) != W('\0'))
1388     {
1389         if (IsTypeNameReservedChar(c))
1390             ssEscapedTypeName->Append(W("\\"));
1391     
1392         ssEscapedTypeName->Append(c);
1393     }
1394 }
1395
1396 /*static*/
1397 bool TypeString::ContainsReservedChar(LPCWSTR pTypeName)
1398 {
1399     CONTRACTL
1400     {
1401         GC_NOTRIGGER;
1402         MODE_ANY;
1403     }
1404     CONTRACTL_END;
1405
1406     WCHAR c;
1407     while ((c = * pTypeName++) != W('\0'))
1408     {
1409         if (IsTypeNameReservedChar(c))
1410         {
1411             return true;
1412         }
1413     }
1414
1415     return false;
1416 }
1417
1418 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::QueryInterface(REFIID riid, void **ppUnk)
1419 {
1420     CONTRACTL
1421     {
1422         NOTHROW;
1423         GC_NOTRIGGER;
1424         MODE_ANY;
1425         SO_TOLERANT;
1426     }
1427     CONTRACTL_END;
1428
1429     *ppUnk = 0;
1430
1431     if (riid == IID_IUnknown)
1432         *ppUnk = (IUnknown *)this;
1433     else if (riid == IID_ITypeNameBuilder)
1434         *ppUnk = (ITypeNameBuilder*)this;
1435     else
1436         return (E_NOINTERFACE);
1437
1438     AddRef();
1439     return S_OK;
1440 }
1441
1442 ULONG STDMETHODCALLTYPE TypeNameBuilderWrapper::AddRef()
1443 {
1444     CONTRACTL
1445     {
1446         NOTHROW;
1447         GC_NOTRIGGER;
1448         MODE_ANY;
1449         SO_TOLERANT;
1450     }
1451     CONTRACTL_END;
1452
1453     return InterlockedIncrement(&m_ref);
1454 }
1455
1456 ULONG STDMETHODCALLTYPE TypeNameBuilderWrapper::Release()
1457 {
1458     CONTRACTL
1459     {
1460         NOTHROW;
1461         GC_NOTRIGGER;
1462         MODE_ANY;
1463         SO_TOLERANT;
1464         SUPPORTS_DAC_HOST_ONLY;
1465     }
1466     CONTRACTL_END;
1467
1468     LONG ref = 0;
1469
1470     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1471     
1472     ref = InterlockedDecrement(&m_ref);
1473     if (ref == 0)
1474         delete this;
1475
1476     END_SO_INTOLERANT_CODE;
1477
1478     return ref;
1479 }
1480
1481
1482 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::OpenGenericArguments()
1483 {
1484     CONTRACTL
1485     {
1486         THROWS;
1487         GC_NOTRIGGER;
1488         MODE_ANY;
1489     }
1490     CONTRACTL_END;
1491
1492     HRESULT hr;
1493     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1494     hr = m_tnb.OpenGenericArguments();
1495     END_SO_INTOLERANT_CODE;
1496     return hr;
1497 }
1498
1499 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::CloseGenericArguments()
1500 {
1501     CONTRACTL
1502     {
1503         THROWS;
1504         GC_NOTRIGGER;
1505         MODE_ANY;
1506     }
1507     CONTRACTL_END;
1508
1509     HRESULT hr;
1510     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1511     hr = m_tnb.CloseGenericArguments();
1512     END_SO_INTOLERANT_CODE;
1513     return hr;
1514 }
1515
1516 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::OpenGenericArgument()
1517 {
1518     CONTRACTL
1519     {
1520         THROWS;
1521         GC_NOTRIGGER;
1522         MODE_ANY;
1523     }
1524     CONTRACTL_END;
1525
1526     HRESULT hr;
1527     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1528     hr = m_tnb.OpenGenericArgument();
1529     END_SO_INTOLERANT_CODE;
1530     return hr;
1531 }
1532
1533 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::CloseGenericArgument()
1534 {
1535     CONTRACTL
1536     {
1537         THROWS;
1538         GC_NOTRIGGER;
1539         MODE_ANY;
1540     }
1541     CONTRACTL_END;
1542
1543     HRESULT hr;
1544     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1545     hr = m_tnb.CloseGenericArgument();
1546     END_SO_INTOLERANT_CODE;
1547     return hr;
1548 }
1549
1550 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddName(LPCWSTR szName)
1551 {
1552     CONTRACTL
1553     {
1554         THROWS;
1555         GC_NOTRIGGER;
1556         MODE_ANY;
1557     }
1558     CONTRACTL_END;
1559
1560     HRESULT hr;
1561     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1562     hr = m_tnb.AddName(szName);
1563     END_SO_INTOLERANT_CODE;
1564     return hr;
1565 }
1566
1567 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddPointer()
1568 {
1569     CONTRACTL
1570     {
1571         THROWS;
1572         GC_NOTRIGGER;
1573         MODE_ANY;
1574     }
1575     CONTRACTL_END;
1576
1577     HRESULT hr;
1578     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1579     hr = m_tnb.AddPointer();
1580     END_SO_INTOLERANT_CODE;
1581     return hr;
1582 }
1583
1584 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddByRef()
1585 {
1586     CONTRACTL
1587     {
1588         THROWS;
1589         GC_NOTRIGGER;
1590         MODE_ANY;
1591     }
1592     CONTRACTL_END;
1593
1594     HRESULT hr;
1595     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1596     hr = m_tnb.AddByRef();
1597     END_SO_INTOLERANT_CODE;
1598     return hr;
1599 }
1600
1601 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddSzArray()
1602 {
1603     CONTRACTL
1604     {
1605         THROWS;
1606         GC_NOTRIGGER;
1607         MODE_ANY;
1608     }
1609     CONTRACTL_END;
1610
1611     HRESULT hr;
1612     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1613     hr = m_tnb.AddSzArray();
1614     END_SO_INTOLERANT_CODE;
1615     return hr;
1616 }
1617
1618 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddArray(DWORD rank)
1619 {
1620     CONTRACTL
1621     {
1622         THROWS;
1623         GC_NOTRIGGER;
1624         MODE_ANY;
1625     }
1626     CONTRACTL_END;
1627
1628     HRESULT hr;
1629     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1630     hr = m_tnb.AddArray(rank);
1631     END_SO_INTOLERANT_CODE;
1632     return hr;
1633 }
1634
1635 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddAssemblySpec(LPCWSTR szAssemblySpec)
1636 {
1637     CONTRACTL
1638     {
1639         THROWS;
1640         GC_NOTRIGGER;
1641         MODE_ANY;
1642     }
1643     CONTRACTL_END;
1644
1645     HRESULT hr;
1646     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1647     hr = m_tnb.AddAssemblySpec(szAssemblySpec);
1648     END_SO_INTOLERANT_CODE;
1649     return hr;
1650 }
1651
1652 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::ToString(BSTR* pszStringRepresentation)
1653 {
1654     WRAPPER_NO_CONTRACT;
1655
1656     HRESULT hr;
1657     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1658     hr = m_tnb.ToString(pszStringRepresentation);
1659     END_SO_INTOLERANT_CODE;
1660     return hr;
1661 }
1662
1663 HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::Clear()
1664 {
1665     CONTRACTL
1666     {
1667         THROWS;
1668         GC_NOTRIGGER;
1669         MODE_ANY;
1670     }
1671     CONTRACTL_END;
1672
1673     HRESULT hr;
1674     BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
1675     hr = m_tnb.Clear();
1676     END_SO_INTOLERANT_CODE;
1677     return hr;
1678 }