[jit] Fix the saving of the 'cfg->ret_var_set' flag when inlining, it was set to...
[mono.git] / mcs / class / Mono.CompilerServices.SymbolWriter / MonoSymbolWriter.cs
1 //
2 // Mono.CSharp.Debugger/MonoSymbolWriter.cs
3 //
4 // Author:
5 //   Martin Baulig (martin@ximian.com)
6 //
7 // This is the default implementation of the System.Diagnostics.SymbolStore.ISymbolWriter
8 // interface.
9 //
10 // (C) 2002 Ximian, Inc.  http://www.ximian.com
11 //
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System;
35 using System.Runtime.CompilerServices;
36 using System.Collections.Generic;
37 using System.IO;
38         
39 namespace Mono.CompilerServices.SymbolWriter
40 {
41         public class MonoSymbolWriter
42         {
43                 List<SourceMethodBuilder> methods;
44                 List<SourceFileEntry> sources;
45                 List<CompileUnitEntry> comp_units;
46                 protected readonly MonoSymbolFile file;
47                 string filename;
48                 
49                 private SourceMethodBuilder current_method;
50                 Stack<SourceMethodBuilder> current_method_stack = new Stack<SourceMethodBuilder> ();
51
52                 public MonoSymbolWriter (string filename)
53                 {
54                         this.methods = new List<SourceMethodBuilder> ();
55                         this.sources = new List<SourceFileEntry> ();
56                         this.comp_units = new List<CompileUnitEntry> ();
57                         this.file = new MonoSymbolFile ();
58
59                         this.filename = filename + ".mdb";
60                 }
61
62                 public MonoSymbolFile SymbolFile {
63                         get { return file; }
64                 }
65
66                 public void CloseNamespace ()
67                 { }
68
69                 public void DefineLocalVariable (int index, string name)
70                 {
71                         if (current_method == null)
72                                 return;
73
74                         current_method.AddLocal (index, name);
75                 }
76
77                 public void DefineCapturedLocal (int scope_id, string name, string captured_name)
78                 {
79                         file.DefineCapturedVariable (scope_id, name, captured_name,
80                                                      CapturedVariable.CapturedKind.Local);
81                 }
82
83                 public void DefineCapturedParameter (int scope_id, string name, string captured_name)
84                 {
85                         file.DefineCapturedVariable (scope_id, name, captured_name,
86                                                      CapturedVariable.CapturedKind.Parameter);
87                 }
88
89                 public void DefineCapturedThis (int scope_id, string captured_name)
90                 {
91                         file.DefineCapturedVariable (scope_id, "this", captured_name,
92                                                      CapturedVariable.CapturedKind.This);
93                 }
94
95                 public void DefineCapturedScope (int scope_id, int id, string captured_name)
96                 {
97                         file.DefineCapturedScope (scope_id, id, captured_name);
98                 }
99
100                 public void DefineScopeVariable (int scope, int index)
101                 {
102                         if (current_method == null)
103                                 return;
104
105                         current_method.AddScopeVariable (scope, index);
106                 }
107
108                 public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column,
109                                                bool is_hidden)
110                 {
111                         if (current_method == null)
112                                 return;
113
114                         current_method.MarkSequencePoint (offset, file, line, column, is_hidden);
115                 }
116
117                 public SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id, IMethodDef method)
118                 {
119                         SourceMethodBuilder builder = new SourceMethodBuilder (file, ns_id, method);
120                         current_method_stack.Push (current_method);
121                         current_method = builder;
122                         methods.Add (current_method);
123                         return builder;
124                 }
125
126                 public void CloseMethod ()
127                 {
128                         current_method = (SourceMethodBuilder) current_method_stack.Pop ();
129                 }
130
131                 public SourceFileEntry DefineDocument (string url)
132                 {
133                         SourceFileEntry entry = new SourceFileEntry (file, url);
134                         sources.Add (entry);
135                         return entry;
136                 }
137
138                 public SourceFileEntry DefineDocument (string url, byte[] guid, byte[] checksum)
139                 {
140                         SourceFileEntry entry = new SourceFileEntry (file, url, guid, checksum);
141                         sources.Add (entry);
142                         return entry;
143                 }
144
145                 public CompileUnitEntry DefineCompilationUnit (SourceFileEntry source)
146                 {
147                         CompileUnitEntry entry = new CompileUnitEntry (file, source);
148                         comp_units.Add (entry);
149                         return entry;
150                 }
151
152                 public int DefineNamespace (string name, CompileUnitEntry unit,
153                                             string[] using_clauses, int parent)
154                 {
155                         if ((unit == null) || (using_clauses == null))
156                                 throw new NullReferenceException ();
157
158                         return unit.DefineNamespace (name, using_clauses, parent);
159                 }
160
161                 public int OpenScope (int start_offset)
162                 {
163                         if (current_method == null)
164                                 return 0;
165
166                         current_method.StartBlock (CodeBlockEntry.Type.Lexical, start_offset);
167                         return 0;
168                 }
169
170                 public void CloseScope (int end_offset)
171                 {
172                         if (current_method == null)
173                                 return;
174
175                         current_method.EndBlock (end_offset);
176                 }
177
178                 public void OpenCompilerGeneratedBlock (int start_offset)
179                 {
180                         if (current_method == null)
181                                 return;
182
183                         current_method.StartBlock (CodeBlockEntry.Type.CompilerGenerated,
184                                                    start_offset);
185                 }
186
187                 public void CloseCompilerGeneratedBlock (int end_offset)
188                 {
189                         if (current_method == null)
190                                 return;
191
192                         current_method.EndBlock (end_offset);
193                 }
194
195                 public void StartIteratorBody (int start_offset)
196                 {
197                         current_method.StartBlock (CodeBlockEntry.Type.IteratorBody,
198                                                    start_offset);
199                 }
200
201                 public void EndIteratorBody (int end_offset)
202                 {
203                         current_method.EndBlock (end_offset);
204                 }
205
206                 public void StartIteratorDispatcher (int start_offset)
207                 {
208                         current_method.StartBlock (CodeBlockEntry.Type.IteratorDispatcher,
209                                                    start_offset);
210                 }
211
212                 public void EndIteratorDispatcher (int end_offset)
213                 {
214                         current_method.EndBlock (end_offset);
215                 }
216
217                 public void DefineAnonymousScope (int id)
218                 {
219                         file.DefineAnonymousScope (id);
220                 }
221
222                 public void WriteSymbolFile (Guid guid)
223                 {
224                         foreach (SourceMethodBuilder method in methods)
225                                 method.DefineMethod (file);
226
227                         try {
228                                 // We mmap the file, so unlink the previous version since it may be in use
229                                 File.Delete (filename);
230                         } catch {
231                                 // We can safely ignore
232                         }
233                         using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write)) {
234                                 file.CreateSymbolFile (guid, fs);
235                         }
236                 }
237         }
238 }