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)
32TypeNameBuilder * 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
44void QCALLTYPE TypeNameBuilder::_ReleaseTypeNameBuilder(TypeNameBuilder * pTnb)
45{
46 QCALL_CONTRACT;
47
48 BEGIN_QCALL;
49 delete pTnb;
50 END_QCALL;
51}
52
53void 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
62void QCALLTYPE TypeNameBuilder::_AddName(TypeNameBuilder * pTnb, LPCWSTR wszName)
63{
64 QCALL_CONTRACT;
65
66 BEGIN_QCALL;
67 pTnb->AddName(wszName);
68 END_QCALL;
69}
70
71void QCALLTYPE TypeNameBuilder::_AddAssemblySpec(TypeNameBuilder * pTnb, LPCWSTR wszAssemblySpec)
72{
73 QCALL_CONTRACT;
74
75 BEGIN_QCALL;
76 pTnb->AddAssemblySpec(wszAssemblySpec);
77 END_QCALL;
78}
79
80void QCALLTYPE TypeNameBuilder::_OpenGenericArguments(TypeNameBuilder * pTnb)
81{
82 QCALL_CONTRACT;
83
84 BEGIN_QCALL;
85 pTnb->OpenGenericArguments();
86 END_QCALL;
87}
88
89void QCALLTYPE TypeNameBuilder::_CloseGenericArguments(TypeNameBuilder * pTnb)
90{
91 QCALL_CONTRACT;
92
93 BEGIN_QCALL;
94 pTnb->CloseGenericArguments();
95 END_QCALL;
96}
97
98void QCALLTYPE TypeNameBuilder::_OpenGenericArgument(TypeNameBuilder * pTnb)
99{
100 QCALL_CONTRACT;
101
102 BEGIN_QCALL;
103 pTnb->OpenGenericArgument();
104 END_QCALL;
105}
106
107void QCALLTYPE TypeNameBuilder::_CloseGenericArgument(TypeNameBuilder * pTnb)
108{
109 QCALL_CONTRACT;
110
111 BEGIN_QCALL;
112 pTnb->CloseGenericArgument();
113 END_QCALL;
114}
115
116void QCALLTYPE TypeNameBuilder::_AddPointer(TypeNameBuilder * pTnb)
117{
118 QCALL_CONTRACT;
119
120 BEGIN_QCALL;
121 pTnb->AddPointer();
122 END_QCALL;
123}
124
125void QCALLTYPE TypeNameBuilder::_AddByRef(TypeNameBuilder * pTnb)
126{
127 QCALL_CONTRACT;
128
129 BEGIN_QCALL;
130 pTnb->AddByRef();
131 END_QCALL;
132}
133
134void QCALLTYPE TypeNameBuilder::_AddSzArray(TypeNameBuilder * pTnb)
135{
136 QCALL_CONTRACT;
137
138 BEGIN_QCALL;
139 pTnb->AddSzArray();
140 END_QCALL;
141}
142
143void QCALLTYPE TypeNameBuilder::_AddArray(TypeNameBuilder * pTnb, DWORD dwRank)
144{
145 QCALL_CONTRACT;
146
147 BEGIN_QCALL;
148 pTnb->AddArray(dwRank);
149 END_QCALL;
150}
151
152void 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//
166TypeNameBuilder::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
181void TypeNameBuilder::PushOpenGenericArgument()
182{
183 WRAPPER_NO_CONTRACT;
184
185 m_stack.Push(m_pStr->GetCount());
186}
187
188void 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 */
207void 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
235void TypeNameBuilder::EscapeAssemblyName(LPCWSTR szName)
236{
237 WRAPPER_NO_CONTRACT;
238
239 Append(szName);
240}
241
242void 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
282HRESULT 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
317HRESULT 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
347HRESULT 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
383HRESULT 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
404HRESULT 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
440HRESULT 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
454HRESULT 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
468HRESULT 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
482HRESULT 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
535HRESULT 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
566HRESULT 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
607HRESULT 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
622HRESULT 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
653void 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
674void 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
706void 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
738void 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
760void 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
800void 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
833void 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
848void 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
870void 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
1033void 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
1049void 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
1066void 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
1159void 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
1183void 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
1213void 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
1243void 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
1276void 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
1361void 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*/
1383void 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*/
1397bool 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
1418HRESULT 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
1442ULONG 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
1456ULONG 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
1482HRESULT 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
1499HRESULT 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
1516HRESULT 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
1533HRESULT 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
1550HRESULT 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
1567HRESULT 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
1584HRESULT 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
1601HRESULT 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
1618HRESULT 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
1635HRESULT 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
1652HRESULT 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
1663HRESULT 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}
1679