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
17typedef 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
35class CCeeGen;
36
37#define CEEGEN_TRACKED_TOKEN(x) tkix ## x,
38
39class CeeGenTokenMapper : public IMapToken
40{
41friend class CCeeGen;
42friend class PESectionMan;
43public:
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
130protected:
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