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 | // CeeGenTokenMapper.h |
6 | // |
7 | // This helper class tracks mapped tokens from their old value to the new value |
8 | // which can happen when the data is optimized on save. |
9 | // |
10 | //***************************************************************************** |
11 | |
12 | #ifndef __CeeGenTokenMapper_h__ |
13 | #define __CeeGenTokenMapper_h__ |
14 | |
15 | #include "utilcode.h" |
16 | |
17 | typedef CDynArray<mdToken> TOKENMAP; |
18 | |
19 | #define INDEX_OF_TYPE(type) ((type) >> 24) |
20 | //r#define INDEX_FROM_TYPE(type) case INDEX_OF_TYPE(mdt ## type): return (tkix ## type) |
21 | |
22 | // Define the list of CeeGen tracked tokens |
23 | #define CEEGEN_TRACKED_TOKENS() \ |
24 | CEEGEN_TRACKED_TOKEN(TypeDef) \ |
25 | CEEGEN_TRACKED_TOKEN(InterfaceImpl) \ |
26 | CEEGEN_TRACKED_TOKEN(MethodDef) \ |
27 | CEEGEN_TRACKED_TOKEN(TypeRef) \ |
28 | CEEGEN_TRACKED_TOKEN(MemberRef) \ |
29 | CEEGEN_TRACKED_TOKEN(CustomAttribute) \ |
30 | CEEGEN_TRACKED_TOKEN(FieldDef) \ |
31 | CEEGEN_TRACKED_TOKEN(ParamDef) \ |
32 | CEEGEN_TRACKED_TOKEN(File) \ |
33 | CEEGEN_TRACKED_TOKEN(GenericParam) \ |
34 | |
35 | class CCeeGen; |
36 | |
37 | #define CEEGEN_TRACKED_TOKEN(x) tkix ## x, |
38 | |
39 | class CeeGenTokenMapper : public IMapToken |
40 | { |
41 | friend class CCeeGen; |
42 | friend class PESectionMan; |
43 | public: |
44 | enum |
45 | { |
46 | CEEGEN_TRACKED_TOKENS() |
47 | MAX_TOKENMAP |
48 | }; |
49 | |
50 | static int IndexForType(mdToken tk); |
51 | |
52 | CeeGenTokenMapper() : m_pIImport(0), m_cRefs(1), m_pIMapToken(NULL) { LIMITED_METHOD_CONTRACT; } |
53 | virtual ~CeeGenTokenMapper() {} |
54 | |
55 | //***************************************************************************** |
56 | // IUnknown implementation. |
57 | //***************************************************************************** |
58 | virtual ULONG STDMETHODCALLTYPE AddRef() |
59 | {LIMITED_METHOD_CONTRACT; return ++m_cRefs; } |
60 | |
61 | virtual ULONG STDMETHODCALLTYPE Release() |
62 | { |
63 | STATIC_CONTRACT_NOTHROW; |
64 | STATIC_CONTRACT_FORBID_FAULT; |
65 | SUPPORTS_DAC_HOST_ONLY; |
66 | |
67 | ULONG cRefs = --m_cRefs; |
68 | if (cRefs == 0) |
69 | { |
70 | if (m_pIMapToken) |
71 | { |
72 | m_pIMapToken->Release(); |
73 | m_pIMapToken = NULL; |
74 | } |
75 | |
76 | delete this; |
77 | } |
78 | return cRefs; |
79 | } |
80 | |
81 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, PVOID *ppIUnk); |
82 | |
83 | //***************************************************************************** |
84 | // Called by the meta data engine when a token is remapped to a new location. |
85 | // This value is recorded in the m_rgMap array based on type and rid of the |
86 | // from token value. |
87 | //***************************************************************************** |
88 | virtual HRESULT STDMETHODCALLTYPE Map(mdToken tkImp, mdToken tkEmit); |
89 | |
90 | //***************************************************************************** |
91 | // Check the given token to see if it has moved to a new location. If so, |
92 | // return true and give back the new token. |
93 | //***************************************************************************** |
94 | virtual int HasTokenMoved(mdToken tkFrom, mdToken &tkTo); |
95 | |
96 | int GetMaxMapSize() const |
97 | { LIMITED_METHOD_CONTRACT; return (MAX_TOKENMAP); } |
98 | |
99 | IUnknown *GetMapTokenIface() const |
100 | { LIMITED_METHOD_CONTRACT; return ((IUnknown *) this); } |
101 | |
102 | |
103 | //***************************************************************************** |
104 | // Hand out a copy of the meta data information. |
105 | //***************************************************************************** |
106 | virtual HRESULT GetMetaData(IMetaDataImport **ppIImport); |
107 | |
108 | //***************************************************************************** |
109 | // Add another token mapper. |
110 | //***************************************************************************** |
111 | virtual HRESULT AddTokenMapper(IMapToken *pIMapToken) |
112 | { |
113 | STATIC_CONTRACT_NOTHROW; |
114 | STATIC_CONTRACT_FORBID_FAULT; |
115 | |
116 | // Add the token mapper, if there isn't already one. |
117 | if (m_pIMapToken == NULL) |
118 | { |
119 | m_pIMapToken = pIMapToken; |
120 | m_pIMapToken->AddRef(); |
121 | return S_OK; |
122 | } |
123 | else |
124 | { |
125 | _ASSERTE(!"Token mapper already set!" ); |
126 | return E_FAIL; |
127 | } |
128 | } |
129 | |
130 | protected: |
131 | // m_rgMap is an array indexed by token type. For each type, an array of |
132 | // tokens is kept, indexed by from rid. To see if a token has been moved, |
133 | // do a lookup by type to get the right array, then use the from rid to |
134 | // find the to rid. |
135 | TOKENMAP m_rgMap[MAX_TOKENMAP]; |
136 | IMetaDataImport *m_pIImport; |
137 | ULONG m_cRefs; // Ref count. |
138 | IMapToken *m_pIMapToken; |
139 | |
140 | }; |
141 | |
142 | #endif // __CeeGenTokenMapper_h__ |
143 | |