2008-02-19 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / mcs / symbolwriter.cs
1 //
2 // symbolwriter.cs: The symbol writer
3 //
4 // Author:
5 //   Martin Baulig (martin@ximian.com)
6 //
7 // (C) 2003 Ximian, Inc.
8 //
9
10 using System;
11 using System.Collections;
12 using System.Reflection;
13 using System.Reflection.Emit;
14
15 using Mono.CompilerServices.SymbolWriter;
16
17 namespace Mono.CSharp {
18         public static class SymbolWriter
19         {
20                 public static bool HasSymbolWriter {
21                         get { return symwriter != null; }
22                 }
23
24                 private static SymbolWriterImpl symwriter;
25
26                 protected class SymbolWriterImpl : MonoSymbolWriter {
27                         delegate int GetILOffsetFunc (ILGenerator ig);
28                         delegate Guid GetGuidFunc (ModuleBuilder mb);
29
30                         GetILOffsetFunc get_il_offset_func;
31                         GetGuidFunc get_guid_func;
32
33                         ModuleBuilder module_builder;
34
35                         public SymbolWriterImpl (ModuleBuilder module_builder, string filename)
36                                 : base (filename)
37                         {
38                                 this.module_builder = module_builder;
39                         }
40
41                         public int GetILOffset (ILGenerator ig)
42                         {
43                                 return get_il_offset_func (ig);
44                         }
45
46                         public void WriteSymbolFile ()
47                         {
48                                 Guid guid = get_guid_func (module_builder);
49                                 WriteSymbolFile (guid);
50                         }
51
52                         public bool Initialize ()
53                         {
54                                 MethodInfo mi = typeof (ILGenerator).GetMethod (
55                                         "Mono_GetCurrentOffset",
56                                         BindingFlags.Static | BindingFlags.NonPublic);
57                                 if (mi == null)
58                                         return false;
59
60                                 get_il_offset_func = (GetILOffsetFunc) System.Delegate.CreateDelegate (
61                                         typeof (GetILOffsetFunc), mi);
62
63                                 mi = typeof (ModuleBuilder).GetMethod (
64                                         "Mono_GetGuid",
65                                         BindingFlags.Static | BindingFlags.NonPublic);
66                                 if (mi == null)
67                                         return false;
68
69                                 get_guid_func = (GetGuidFunc) System.Delegate.CreateDelegate (
70                                         typeof (GetGuidFunc), mi);
71
72                                 Location.DefineSymbolDocuments (this);
73
74                                 return true;
75                         }
76                 }
77
78                 public static void DefineLocalVariable (string name, LocalBuilder builder)
79                 {
80                         if (symwriter != null) {
81                                 int index = MonoDebuggerSupport.GetLocalIndex (builder);
82                                 symwriter.DefineLocalVariable (index, name);
83                         }
84                 }
85
86                 public static void OpenMethod (ISourceFile file, ISourceMethod method,
87                                                int start_row, int start_column,
88                                                int end_row, int end_column)
89                 {
90                         if (symwriter != null)
91                                 symwriter.OpenMethod (file, method, start_row, start_column,
92                                                       end_row, end_column);
93                 }
94
95                 public static void CloseMethod ()
96                 {
97                         if (symwriter != null)
98                                 symwriter.CloseMethod ();
99                 }
100
101                 public static int OpenScope (ILGenerator ig)
102                 {
103                         if (symwriter != null) {
104                                 int offset = symwriter.GetILOffset (ig);
105                                 return symwriter.OpenScope (offset);
106                         } else {
107                                 return -1;
108                         }
109                 }
110
111                 public static void CloseScope (ILGenerator ig)
112                 {
113                         if (symwriter != null) {
114                                 int offset = symwriter.GetILOffset (ig);
115                                 symwriter.CloseScope (offset);
116                         }
117                 }
118
119                 public static int DefineNamespace (string name, SourceFileEntry source,
120                                                    string[] using_clauses, int parent)
121                 {
122                         if (symwriter != null)
123                                 return symwriter.DefineNamespace (name, source, using_clauses, parent);
124                         else
125                                 return -1;
126                 }
127
128 #region Terrania additions
129                 public static void DefineAnonymousScope (int id)
130                 {
131 #if !DISABLE_TERRANIA_CHANGES
132                         if (symwriter != null)
133                                 symwriter.DefineAnonymousScope (id);
134 #endif
135                 }
136
137                 public static void DefineScopeVariable (int scope, LocalBuilder builder)
138                 {
139 #if !DISABLE_TERRANIA_CHANGES
140                         if (symwriter != null) {
141                                 int index = MonoDebuggerSupport.GetLocalIndex (builder);
142                                 symwriter.DefineScopeVariable (scope, index);
143                         }
144 #endif
145                 }
146
147                 public static void DefineScopeVariable (int scope)
148                 {
149 #if !DISABLE_TERRANIA_CHANGES
150                         if (symwriter != null)
151                                 symwriter.DefineScopeVariable (scope, -1);
152 #endif
153                 }
154
155                 public static void DefineCapturedLocal (int scope_id, string name,
156                                                         string captured_name)
157                 {
158 #if !DISABLE_TERRANIA_CHANGES
159                         if (symwriter != null)
160                                 symwriter.DefineCapturedLocal (scope_id, name, captured_name);
161 #endif
162                 }
163
164                 public static void DefineCapturedParameter (int scope_id, string name,
165                                                             string captured_name)
166                 {
167 #if !DISABLE_TERRANIA_CHANGES
168                         if (symwriter != null)
169                                 symwriter.DefineCapturedParameter (scope_id, name, captured_name);
170 #endif
171                 }
172
173                 public static void DefineCapturedThis (int scope_id, string captured_name)
174                 {
175 #if !DISABLE_TERRANIA_CHANGES
176                         if (symwriter != null)
177                                 symwriter.DefineCapturedThis (scope_id, captured_name);
178 #endif
179                 }
180
181                 public static void DefineCapturedScope (int scope_id, int id, string captured_name)
182                 {
183 #if !DISABLE_TERRANIA_CHANGES
184                         if (symwriter != null)
185                                 symwriter.DefineCapturedScope (scope_id, id, captured_name);
186 #endif
187                 }
188
189                 public static void SetRealMethodName (string name)
190                 {
191 #if !DISABLE_TERRANIA_CHANGES
192                         if (symwriter != null)
193                                 symwriter.SetRealMethodName (name);
194 #endif
195                 }
196
197                 public static void OpenCompilerGeneratedBlock (ILGenerator ig)
198                 {
199 #if !DISABLE_TERRANIA_CHANGES
200                         if (symwriter != null) {
201                                 int offset = symwriter.GetILOffset (ig);
202                                 symwriter.OpenCompilerGeneratedBlock (offset);
203                         }
204 #endif
205                 }
206
207                 public static void CloseCompilerGeneratedBlock (ILGenerator ig)
208                 {
209 #if !DISABLE_TERRANIA_CHANGES
210                         if (symwriter != null) {
211                                 int offset = symwriter.GetILOffset (ig);
212                                 symwriter.CloseCompilerGeneratedBlock (offset);
213                         }
214 #endif
215                 }
216
217                 public static void StartIteratorBody (ILGenerator ig)
218                 {
219 #if !DISABLE_TERRANIA_CHANGES
220                         if (symwriter != null) {
221                                 int offset = symwriter.GetILOffset (ig);
222                                 symwriter.StartIteratorBody (offset);
223                         }
224 #endif
225                 }
226
227                 public static void EndIteratorBody (ILGenerator ig)
228                 {
229 #if !DISABLE_TERRANIA_CHANGES
230                         if (symwriter != null) {
231                                 int offset = symwriter.GetILOffset (ig);
232                                 symwriter.EndIteratorBody (offset);
233                         }
234 #endif
235                 }
236
237                 public static void StartIteratorDispatcher (ILGenerator ig)
238                 {
239 #if !DISABLE_TERRANIA_CHANGES
240                         if (symwriter != null) {
241                                 int offset = symwriter.GetILOffset (ig);
242                                 symwriter.StartIteratorDispatcher (offset);
243                         }
244 #endif
245                 }
246
247                 public static void EndIteratorDispatcher (ILGenerator ig)
248                 {
249 #if !DISABLE_TERRANIA_CHANGES
250                         if (symwriter != null) {
251                                 int offset = symwriter.GetILOffset (ig);
252                                 symwriter.EndIteratorDispatcher (offset);
253                         }
254 #endif
255                 }
256 #endregion
257
258                 public static void MarkSequencePoint (ILGenerator ig, int row, int column)
259                 {
260                         if (symwriter != null) {
261                                 int offset = symwriter.GetILOffset (ig);
262                                 symwriter.MarkSequencePoint (offset, row, column);
263                         }
264                 }
265
266                 public static void WriteSymbolFile ()
267                 {
268                         if (symwriter != null)
269                                 symwriter.WriteSymbolFile ();
270                 }
271
272                 public static bool Initialize (ModuleBuilder module, string filename)
273                 {
274                         symwriter = new SymbolWriterImpl (module, filename);
275                         if (!symwriter.Initialize ()) {
276                                 symwriter = null;
277                                 return false;
278                         }
279
280                         return true;
281                 }
282         }
283 }