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// File: generics.inl
6//
7
8//
9// Helper functions for generics implementation
10//
11
12//
13// ============================================================================
14
15#ifndef GENERICS_INL
16#define GENERICS_INL
17
18#ifdef FEATURE_COMINTEROP
19#include "winrttypenameconverter.h"
20#endif
21
22// Generics helper functions
23namespace Generics
24{
25#ifndef DACCESS_COMPILE
26 inline void DetermineCCWTemplateAndGUIDPresenceOnNonCanonicalMethodTable(
27 // Input
28 MethodTable *pOldMT, BOOL fNewMTContainsGenericVariables,
29 // Output
30 BOOL *pfHasGuidInfo, BOOL *pfHasCCWTemplate)
31 {
32 STANDARD_VM_CONTRACT;
33
34#ifdef FEATURE_COMINTEROP
35 WORD wNumInterfaces = static_cast<WORD>(pOldMT->GetNumInterfaces());
36
37 InterfaceInfo_t * pOldIMap = (InterfaceInfo_t *)pOldMT->GetInterfaceMap();
38
39 BOOL fHasGuidInfo = FALSE;
40
41 // Generic WinRT delegates expose a class interface and need the CCW template
42 BOOL fHasCCWTemplate = FALSE;
43
44 if (!fNewMTContainsGenericVariables)
45 {
46 if (pOldMT->IsInterface())
47 {
48 fHasGuidInfo = (pOldMT->IsProjectedFromWinRT() || WinRTTypeNameConverter::IsRedirectedType(pOldMT, WinMDAdapter::WinMDTypeKind_PInterface));
49 }
50 else if (pOldMT->IsDelegate())
51 {
52 fHasGuidInfo = (pOldMT->IsProjectedFromWinRT() || WinRTTypeNameConverter::IsRedirectedType(pOldMT, WinMDAdapter::WinMDTypeKind_PDelegate));
53
54 // Generic WinRT delegates expose a class interface and need a CCW template
55 fHasCCWTemplate = fHasGuidInfo;
56 }
57
58 if (!fHasCCWTemplate)
59 {
60 if (pOldMT->IsInterface())
61 {
62 // Interfaces need the CCW template if they are redirected and need variance
63 if (pOldMT->HasVariance() &&
64 (pOldMT->IsProjectedFromWinRT() || WinRTTypeNameConverter::IsRedirectedType(pOldMT, WinMDAdapter::WinMDTypeKind_PInterface)))
65 {
66 fHasCCWTemplate = TRUE;
67 }
68 }
69 else
70 {
71 // Other types may need the CCW template if they implement generic interfaces
72 for (WORD iItf = 0; iItf < wNumInterfaces; iItf++)
73 {
74 // If the class implements a generic WinRT interface, it needs its own (per-instantiation)
75 // CCW template as the one on EEClass would be shared and hence useless.
76 OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOAD_APPROXPARENTS);
77 MethodTable *pItfMT = pOldIMap[iItf].GetApproxMethodTable(pOldMT->GetLoaderModule());
78 if (pItfMT->HasInstantiation() &&
79 (pItfMT->IsProjectedFromWinRT() || WinRTTypeNameConverter::IsRedirectedType(pItfMT, WinMDAdapter::WinMDTypeKind_PInterface)))
80 {
81 fHasCCWTemplate = TRUE;
82 break;
83 }
84 }
85 }
86 }
87 }
88#else // FEATURE_COMINTEROP
89 BOOL fHasGuidInfo = FALSE;
90 BOOL fHasCCWTemplate = FALSE;
91#endif // FEATURE_COMINTEROP
92 *pfHasGuidInfo = fHasGuidInfo;
93 *pfHasCCWTemplate = fHasCCWTemplate;
94 }
95#endif // DACCESS_COMPILE
96}
97
98#endif // GENERICS_INL
99