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