2010-03-12 Jb Evain <jbevain@novell.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 // Copyright 2003 Ximian, Inc.
8 // Copyright 2003-2008 Novell, Inc.
9 //
10
11 using System;
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                 class SymbolWriterImpl : MonoSymbolWriter {
27 #if !NET_4_0
28                         delegate int GetILOffsetFunc (ILGenerator ig);
29                         GetILOffsetFunc get_il_offset_func;
30 #endif
31                         delegate Guid GetGuidFunc (ModuleBuilder mb);
32
33                         GetGuidFunc get_guid_func;
34
35                         ModuleBuilder module_builder;
36
37                         public SymbolWriterImpl (ModuleBuilder module_builder, string filename)
38                                 : base (filename)
39                         {
40                                 this.module_builder = module_builder;
41                         }
42
43                         public int GetILOffset (ILGenerator ig)
44                         {
45 #if NET_4_0
46                                 return ig.ILOffset;
47 #else
48                                 return get_il_offset_func (ig);
49 #endif
50                         }
51
52                         public void WriteSymbolFile ()
53                         {
54                                 Guid guid = get_guid_func (module_builder);
55                                 WriteSymbolFile (guid);
56                         }
57
58                         public bool Initialize ()
59                         {
60                                 MethodInfo mi;
61 #if !NET_4_0
62                                 mi = typeof (ILGenerator).GetMethod (
63                                         "Mono_GetCurrentOffset",
64                                         BindingFlags.Static | BindingFlags.NonPublic);
65                                 if (mi == null)
66                                         return false;
67
68                                 get_il_offset_func = (GetILOffsetFunc) System.Delegate.CreateDelegate (
69                                         typeof (GetILOffsetFunc), mi);
70 #endif
71
72                                 mi = typeof (ModuleBuilder).GetMethod (
73                                         "Mono_GetGuid",
74                                         BindingFlags.Static | BindingFlags.NonPublic);
75                                 if (mi == null)
76                                         return false;
77
78                                 get_guid_func = (GetGuidFunc) System.Delegate.CreateDelegate (
79                                         typeof (GetGuidFunc), mi);
80
81                                 Location.DefineSymbolDocuments (this);
82
83                                 return true;
84                         }
85                 }
86
87                 public static void DefineLocalVariable (string name, LocalBuilder builder)
88                 {
89                         if (symwriter != null) {
90                                 int index = MonoDebuggerSupport.GetLocalIndex (builder);
91                                 symwriter.DefineLocalVariable (index, name);
92                         }
93                 }
94
95                 public static SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id,
96                                                               IMethodDef method)
97                 {
98                         if (symwriter != null)
99                                 return symwriter.OpenMethod (file, ns_id, method);
100                         else
101                                 return null;
102                 }
103
104                 public static void CloseMethod ()
105                 {
106                         if (symwriter != null)
107                                 symwriter.CloseMethod ();
108                 }
109
110                 public static int OpenScope (ILGenerator ig)
111                 {
112                         if (symwriter != null) {
113                                 int offset = symwriter.GetILOffset (ig);
114                                 return symwriter.OpenScope (offset);
115                         } else {
116                                 return -1;
117                         }
118                 }
119
120                 public static void CloseScope (ILGenerator ig)
121                 {
122                         if (symwriter != null) {
123                                 int offset = symwriter.GetILOffset (ig);
124                                 symwriter.CloseScope (offset);
125                         }
126                 }
127
128                 public static int DefineNamespace (string name, CompileUnitEntry source,
129                                                    string[] using_clauses, int parent)
130                 {
131                         if (symwriter != null)
132                                 return symwriter.DefineNamespace (name, source, using_clauses, parent);
133                         else
134                                 return -1;
135                 }
136
137 #region Terrania additions
138                 public static void DefineAnonymousScope (int id)
139                 {
140                         if (symwriter != null)
141                                 symwriter.DefineAnonymousScope (id);
142                 }
143
144                 public static void DefineScopeVariable (int scope, LocalBuilder builder)
145                 {
146                         if (symwriter != null) {
147                                 int index = MonoDebuggerSupport.GetLocalIndex (builder);
148                                 symwriter.DefineScopeVariable (scope, index);
149                         }
150                 }
151
152                 public static void DefineScopeVariable (int scope)
153                 {
154                         if (symwriter != null)
155                                 symwriter.DefineScopeVariable (scope, -1);
156                 }
157
158                 public static void DefineCapturedLocal (int scope_id, string name,
159                                                         string captured_name)
160                 {
161                         if (symwriter != null)
162                                 symwriter.DefineCapturedLocal (scope_id, name, captured_name);
163                 }
164
165                 public static void DefineCapturedParameter (int scope_id, string name,
166                                                             string captured_name)
167                 {
168                         if (symwriter != null)
169                                 symwriter.DefineCapturedParameter (scope_id, name, captured_name);
170                 }
171
172                 public static void DefineCapturedThis (int scope_id, string captured_name)
173                 {
174                         if (symwriter != null)
175                                 symwriter.DefineCapturedThis (scope_id, captured_name);
176                 }
177
178                 public static void DefineCapturedScope (int scope_id, int id, string captured_name)
179                 {
180                         if (symwriter != null)
181                                 symwriter.DefineCapturedScope (scope_id, id, captured_name);
182                 }
183
184                 public static void OpenCompilerGeneratedBlock (ILGenerator ig)
185                 {
186                         if (symwriter != null) {
187                                 int offset = symwriter.GetILOffset (ig);
188                                 symwriter.OpenCompilerGeneratedBlock (offset);
189                         }
190                 }
191
192                 public static void CloseCompilerGeneratedBlock (ILGenerator ig)
193                 {
194                         if (symwriter != null) {
195                                 int offset = symwriter.GetILOffset (ig);
196                                 symwriter.CloseCompilerGeneratedBlock (offset);
197                         }
198                 }
199
200                 public static void StartIteratorBody (ILGenerator ig)
201                 {
202                         if (symwriter != null) {
203                                 int offset = symwriter.GetILOffset (ig);
204                                 symwriter.StartIteratorBody (offset);
205                         }
206                 }
207
208                 public static void EndIteratorBody (ILGenerator ig)
209                 {
210                         if (symwriter != null) {
211                                 int offset = symwriter.GetILOffset (ig);
212                                 symwriter.EndIteratorBody (offset);
213                         }
214                 }
215
216                 public static void StartIteratorDispatcher (ILGenerator ig)
217                 {
218                         if (symwriter != null) {
219                                 int offset = symwriter.GetILOffset (ig);
220                                 symwriter.StartIteratorDispatcher (offset);
221                         }
222                 }
223
224                 public static void EndIteratorDispatcher (ILGenerator ig)
225                 {
226                         if (symwriter != null) {
227                                 int offset = symwriter.GetILOffset (ig);
228                                 symwriter.EndIteratorDispatcher (offset);
229                         }
230                 }
231 #endregion
232
233                 public static void MarkSequencePoint (ILGenerator ig, Location loc)
234                 {
235                         if (symwriter != null) {
236                                 SourceFileEntry file = loc.SourceFile.SourceFileEntry;
237                                 int offset = symwriter.GetILOffset (ig);
238                                 symwriter.MarkSequencePoint (
239                                         offset, file, loc.Row, loc.Column, loc.Hidden);
240                         }
241                 }
242
243                 public static void WriteSymbolFile ()
244                 {
245                         if (symwriter != null)
246                                 symwriter.WriteSymbolFile ();
247                 }
248
249                 public static bool Initialize (ModuleBuilder module, string filename)
250                 {
251                         symwriter = new SymbolWriterImpl (module, filename);
252                         if (!symwriter.Initialize ()) {
253                                 symwriter = null;
254                                 return false;
255                         }
256
257                         return true;
258                 }
259
260                 public static void Reset ()
261                 {
262                         symwriter = null;
263                 }
264         }
265 }