summaryrefslogtreecommitdiff
path: root/src/inc/ceegentokenmapper.h
blob: a2312a036c04b730b79c95e356f3f760efc9e7c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//*****************************************************************************
// CeeGenTokenMapper.h
//
// This helper class tracks mapped tokens from their old value to the new value
// which can happen when the data is optimized on save.
//
//*****************************************************************************

#ifndef __CeeGenTokenMapper_h__
#define __CeeGenTokenMapper_h__

#include "utilcode.h"

typedef CDynArray<mdToken> TOKENMAP;

#define INDEX_OF_TYPE(type) ((type) >> 24)
//r#define INDEX_FROM_TYPE(type) case INDEX_OF_TYPE(mdt ## type): return (tkix ## type)

// Define the list of CeeGen tracked tokens
#define CEEGEN_TRACKED_TOKENS()             \
    CEEGEN_TRACKED_TOKEN(TypeDef)           \
    CEEGEN_TRACKED_TOKEN(InterfaceImpl)     \
    CEEGEN_TRACKED_TOKEN(MethodDef)         \
    CEEGEN_TRACKED_TOKEN(TypeRef)           \
    CEEGEN_TRACKED_TOKEN(MemberRef)         \
    CEEGEN_TRACKED_TOKEN(CustomAttribute)   \
    CEEGEN_TRACKED_TOKEN(FieldDef)          \
    CEEGEN_TRACKED_TOKEN(ParamDef)          \
    CEEGEN_TRACKED_TOKEN(File)              \
    CEEGEN_TRACKED_TOKEN(GenericParam)      \

class CCeeGen;

#define CEEGEN_TRACKED_TOKEN(x) tkix ## x,

class CeeGenTokenMapper : public IMapToken
{
friend class CCeeGen;
friend class PESectionMan;
public:
    enum
    {
        CEEGEN_TRACKED_TOKENS()
        MAX_TOKENMAP
    };

    static int IndexForType(mdToken tk);
    
    CeeGenTokenMapper() : m_pIImport(0), m_cRefs(1), m_pIMapToken(NULL)  { LIMITED_METHOD_CONTRACT; }
    virtual ~CeeGenTokenMapper() {}

//*****************************************************************************
// IUnknown implementation.  
//*****************************************************************************
    virtual ULONG __stdcall AddRef()
    {LIMITED_METHOD_CONTRACT;  return ++m_cRefs; }

    virtual ULONG __stdcall Release()
    {   
        STATIC_CONTRACT_NOTHROW;
        STATIC_CONTRACT_FORBID_FAULT;
        SUPPORTS_DAC_HOST_ONLY;

        ULONG cRefs = --m_cRefs;
        if (cRefs == 0)
        {
            if (m_pIMapToken)
            {
                m_pIMapToken->Release();
                m_pIMapToken = NULL;
            }
            
            delete this;
        }
        return cRefs;
    }

    virtual HRESULT __stdcall QueryInterface(REFIID iid, PVOID *ppIUnk);

//*****************************************************************************
// Called by the meta data engine when a token is remapped to a new location.
// This value is recorded in the m_rgMap array based on type and rid of the
// from token value.
//*****************************************************************************
    virtual HRESULT __stdcall Map(mdToken tkImp, mdToken tkEmit);

//*****************************************************************************
// Check the given token to see if it has moved to a new location.  If so,
// return true and give back the new token.
//*****************************************************************************
    virtual int HasTokenMoved(mdToken tkFrom, mdToken &tkTo);

    int GetMaxMapSize() const
    { LIMITED_METHOD_CONTRACT; return (MAX_TOKENMAP); }

    IUnknown *GetMapTokenIface() const
    { LIMITED_METHOD_CONTRACT; return ((IUnknown *) this); }

    
//*****************************************************************************
// Hand out a copy of the meta data information.
//*****************************************************************************
    virtual HRESULT GetMetaData(IMetaDataImport **ppIImport);

//*****************************************************************************
// Add another token mapper.
//*****************************************************************************
    virtual HRESULT AddTokenMapper(IMapToken *pIMapToken)
    {
        STATIC_CONTRACT_NOTHROW;
        STATIC_CONTRACT_FORBID_FAULT;

        // Add the token mapper, if there isn't already one.
        if (m_pIMapToken == NULL)
        {
            m_pIMapToken = pIMapToken;
            m_pIMapToken->AddRef();
            return S_OK;
        }
        else
        {
            _ASSERTE(!"Token mapper already set!");
            return E_FAIL;
        }
    }

protected:
// m_rgMap is an array indexed by token type.  For each type, an array of
// tokens is kept, indexed by from rid.  To see if a token has been moved,
// do a lookup by type to get the right array, then use the from rid to
// find the to rid.
    TOKENMAP    m_rgMap[MAX_TOKENMAP];
    IMetaDataImport *m_pIImport;
    ULONG       m_cRefs;                // Ref count.
    IMapToken  *m_pIMapToken;
    
};

#endif // __CeeGenTokenMapper_h__