Delay initialization of missing methods needed by symbol writer
[mono.git] / mcs / mcs / symbolwriter.cs
1 //
2 // symbolwriter.cs: The debug symbol writer
3 //
4 // Authors: Martin Baulig (martin@ximian.com)
5 //          Marek Safar (marek.safar@gmail.com)
6 //
7 // Dual licensed under the terms of the MIT X11 or GNU GPL
8 //
9 // Copyright 2003 Ximian, Inc (http://www.ximian.com)
10 // Copyright 2004-2010 Novell, Inc
11 //
12
13 using System;
14 using System.Reflection;
15 using System.Reflection.Emit;
16
17 using Mono.CompilerServices.SymbolWriter;
18
19 namespace Mono.CSharp
20 {
21         static class SymbolWriter
22         {
23 #if !NET_4_0
24                 delegate int GetILOffsetFunc (ILGenerator ig);
25                 static GetILOffsetFunc get_il_offset_func;
26
27                 delegate Guid GetGuidFunc (ModuleBuilder mb);
28                 static GetGuidFunc get_guid_func;
29
30                 static void Initialize ()
31                 {
32                         var mi = typeof (ILGenerator).GetMethod (
33                                 "Mono_GetCurrentOffset",
34                                 BindingFlags.Static | BindingFlags.NonPublic);
35                         if (mi == null)
36                                 throw new MissingMethodException ("Mono_GetCurrentOffset");
37
38                         get_il_offset_func = (GetILOffsetFunc) System.Delegate.CreateDelegate (
39                                 typeof (GetILOffsetFunc), mi);
40
41                         mi = typeof (ModuleBuilder).GetMethod (
42                                 "Mono_GetGuid",
43                                 BindingFlags.Static | BindingFlags.NonPublic);
44                         if (mi == null)
45                                 throw new MissingMethodException ("Mono_GetGuid");
46
47                         get_guid_func = (GetGuidFunc) System.Delegate.CreateDelegate (
48                                 typeof (GetGuidFunc), mi);
49                 }
50 #endif
51
52                 static int GetILOffset (ILGenerator ig)
53                 {
54 #if NET_4_0
55                         return ig.ILOffset;
56 #else
57                         if (get_il_offset_func == null)
58                                 Initialize ();
59
60                         return get_il_offset_func (ig);
61 #endif
62                 }
63
64                 public static Guid GetGuid (ModuleBuilder module)
65                 {
66 #if NET_4_0
67                         return module.ModuleVersionId;
68 #else
69                         if (get_guid_func == null)
70                                 Initialize ();
71
72                         return get_guid_func (module);
73 #endif
74                 }
75
76                 public static bool HasSymbolWriter {
77                         get { return symwriter != null; }
78                 }
79
80                 public static MonoSymbolWriter symwriter;
81
82                 public static void DefineLocalVariable (string name, LocalBuilder builder)
83                 {
84                         if (symwriter != null) {
85                                 symwriter.DefineLocalVariable (builder.LocalIndex, name);
86                         }
87                 }
88
89                 public static SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id,
90                                                               IMethodDef method)
91                 {
92                         if (symwriter != null)
93                                 return symwriter.OpenMethod (file, ns_id, method);
94                         else
95                                 return null;
96                 }
97
98                 public static void CloseMethod ()
99                 {
100                         if (symwriter != null)
101                                 symwriter.CloseMethod ();
102                 }
103
104                 public static int OpenScope (ILGenerator ig)
105                 {
106                         if (symwriter != null) {
107                                 int offset = GetILOffset (ig);
108                                 return symwriter.OpenScope (offset);
109                         } else {
110                                 return -1;
111                         }
112                 }
113
114                 public static void CloseScope (ILGenerator ig)
115                 {
116                         if (symwriter != null) {
117                                 int offset = GetILOffset (ig);
118                                 symwriter.CloseScope (offset);
119                         }
120                 }
121
122                 public static int DefineNamespace (string name, CompileUnitEntry source,
123                                                    string[] using_clauses, int parent)
124                 {
125                         if (symwriter != null)
126                                 return symwriter.DefineNamespace (name, source, using_clauses, parent);
127                         else
128                                 return -1;
129                 }
130
131                 public static void DefineAnonymousScope (int id)
132                 {
133                         if (symwriter != null)
134                                 symwriter.DefineAnonymousScope (id);
135                 }
136
137                 public static void DefineScopeVariable (int scope, LocalBuilder builder)
138                 {
139                         if (symwriter != null) {
140                                 symwriter.DefineScopeVariable (scope, builder.LocalIndex);
141                         }
142                 }
143
144                 public static void DefineScopeVariable (int scope)
145                 {
146                         if (symwriter != null)
147                                 symwriter.DefineScopeVariable (scope, -1);
148                 }
149
150                 public static void DefineCapturedLocal (int scope_id, string name,
151                                                         string captured_name)
152                 {
153                         if (symwriter != null)
154                                 symwriter.DefineCapturedLocal (scope_id, name, captured_name);
155                 }
156
157                 public static void DefineCapturedParameter (int scope_id, string name,
158                                                             string captured_name)
159                 {
160                         if (symwriter != null)
161                                 symwriter.DefineCapturedParameter (scope_id, name, captured_name);
162                 }
163
164                 public static void DefineCapturedThis (int scope_id, string captured_name)
165                 {
166                         if (symwriter != null)
167                                 symwriter.DefineCapturedThis (scope_id, captured_name);
168                 }
169
170                 public static void DefineCapturedScope (int scope_id, int id, string captured_name)
171                 {
172                         if (symwriter != null)
173                                 symwriter.DefineCapturedScope (scope_id, id, captured_name);
174                 }
175
176                 public static void OpenCompilerGeneratedBlock (EmitContext ec)
177                 {
178                         if (symwriter != null) {
179                                 int offset = GetILOffset (ec.ig);
180                                 symwriter.OpenCompilerGeneratedBlock (offset);
181                         }
182                 }
183
184                 public static void CloseCompilerGeneratedBlock (EmitContext ec)
185                 {
186                         if (symwriter != null) {
187                                 int offset = GetILOffset (ec.ig);
188                                 symwriter.CloseCompilerGeneratedBlock (offset);
189                         }
190                 }
191
192                 public static void StartIteratorBody (EmitContext ec)
193                 {
194                         if (symwriter != null) {
195                                 int offset = GetILOffset (ec.ig);
196                                 symwriter.StartIteratorBody (offset);
197                         }
198                 }
199
200                 public static void EndIteratorBody (EmitContext ec)
201                 {
202                         if (symwriter != null) {
203                                 int offset = GetILOffset (ec.ig);
204                                 symwriter.EndIteratorBody (offset);
205                         }
206                 }
207
208                 public static void StartIteratorDispatcher (EmitContext ec)
209                 {
210                         if (symwriter != null) {
211                                 int offset = GetILOffset (ec.ig);
212                                 symwriter.StartIteratorDispatcher (offset);
213                         }
214                 }
215
216                 public static void EndIteratorDispatcher (EmitContext ec)
217                 {
218                         if (symwriter != null) {
219                                 int offset = GetILOffset (ec.ig);
220                                 symwriter.EndIteratorDispatcher (offset);
221                         }
222                 }
223
224                 public static void MarkSequencePoint (ILGenerator ig, Location loc)
225                 {
226                         if (symwriter != null) {
227                                 SourceFileEntry file = loc.SourceFile.SourceFileEntry;
228                                 int offset = GetILOffset (ig);
229                                 symwriter.MarkSequencePoint (
230                                         offset, file, loc.Row, loc.Column, loc.Hidden);
231                         }
232                 }
233
234                 public static void Reset ()
235                 {
236                         symwriter = null;
237                 }
238         }
239 }