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