2 // System.Diagnostics.SymbolStore/MonoSymbolWriter.cs
5 // Martin Baulig (martin@gnome.org)
7 // This is the default implementation of the System.Diagnostics.SymbolStore.ISymbolWriter
10 // (C) 2002 Ximian, Inc. http://www.ximian.com
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.Diagnostics.SymbolStore;
17 using System.Collections;
20 namespace Mono.CSharp.Debugger
23 public class MonoSymbolWriter : IMonoSymbolWriter
25 protected string output_filename = null;
26 protected Hashtable methods = null;
27 protected Hashtable sources = null;
29 protected class SourceFile : ISourceFile
31 private ISourceMethod[] _methods;
32 private string _file_name;
34 public SourceFile (string filename)
36 this._file_name = filename;
38 this._methods = new ISourceMethod [0];
41 // interface ISourceFile
43 public string FileName {
49 public ISourceMethod[] Methods {
55 public void AddMethod (ISourceMethod method)
57 int i = _methods.Length;
58 ISourceMethod[] new_m = new ISourceMethod [i + 1];
59 Array.Copy (_methods, new_m, i);
65 protected class SourceLine : ISourceLine
67 public SourceLine (int offset, int line)
69 this._offset = offset;
73 private readonly int _offset;
74 private readonly int _line;
76 // interface ISourceLine
91 protected class LocalVariable : ILocalVariable
93 public LocalVariable (string name, int index)
99 private readonly string _name;
100 private readonly int _index;
102 // interface ILocalVariable
117 protected class SourceMethod : ISourceMethod
119 private ISourceLine[] _lines;
120 private ILocalVariable[] _locals;
122 private readonly MethodInfo _method_info;
123 private readonly SourceFile _source_file;
125 public SourceMethod (MethodInfo method_info, SourceFile source_file) {
126 this._method_info = method_info;
127 this._source_file = source_file;
129 this._lines = new ISourceLine [0];
130 this._locals = new ILocalVariable [0];
133 public void SetSourceRange (int startLine, int startColumn,
134 int endLine, int endColumn)
136 AddLine (new SourceLine (0, startLine));
139 // interface ISourceMethod
141 public ISourceLine[] Lines {
147 public ILocalVariable[] Locals {
153 public void AddLine (ISourceLine line)
155 int i = _lines.Length;
156 ISourceLine[] new_m = new ISourceLine [i + 1];
157 Array.Copy (_lines, new_m, i);
162 public void AddLocal (ILocalVariable local)
164 int i = _locals.Length;
165 ILocalVariable[] new_m = new ILocalVariable [i + 1];
166 Array.Copy (_locals, new_m, i);
171 public MethodInfo MethodInfo {
177 public ISourceFile SourceFile {
184 protected SourceMethod current_method = null;
187 // Interface IMonoSymbolWriter
190 public MonoSymbolWriter ()
192 methods = new Hashtable ();
193 sources = new Hashtable ();
196 public void Close () {
197 CreateDwarfFile (output_filename);
200 public void CloseNamespace () {
203 public void CloseScope (int endOffset) {
206 // Create and return a new IMonoSymbolDocumentWriter.
207 public ISymbolDocumentWriter DefineDocument (string url,
212 return new MonoSymbolDocumentWriter (url);
215 public void DefineField (
218 FieldAttributes attributes,
220 SymAddressKind addrKind,
227 public void DefineGlobalVariable (
229 FieldAttributes attributes,
231 SymAddressKind addrKind,
238 public void DefineLocalVariable (string name,
239 FieldAttributes attributes,
241 SymAddressKind addrKind,
248 LocalVariable local_info = new LocalVariable (name, addr1);
250 if (current_method != null)
251 current_method.AddLocal (local_info);
254 public void DefineParameter (
256 ParameterAttributes attributes,
258 SymAddressKind addrKind,
265 public void DefineSequencePoints (ISymbolDocumentWriter document,
272 SourceLine source_line = new SourceLine (offsets [0], lines [0]);
274 if (current_method != null)
275 current_method.AddLine (source_line);
278 public void Initialize (IntPtr emitter, string filename, bool fFullBuild)
280 throw new NotSupportedException ("Please use the 'Initialize (string filename)' "
281 + "constructor and read the documentation in "
282 + "Mono.CSharp.Debugger/IMonoSymbolWriter.cs");
285 // This is documented in IMonoSymbolWriter.cs
286 public void Initialize (string filename)
288 this.output_filename = filename;
291 public void OpenMethod (SymbolToken method)
296 // This is documented in IMonoSymbolWriter.cs
297 public void OpenMethod (SymbolToken symbol_token, MethodInfo method_info,
300 int token = symbol_token.GetToken ();
301 SourceFile source_info;
303 if (methods.ContainsKey (token))
304 methods.Remove (token);
306 if (sources.ContainsKey (source_file))
307 source_info = (SourceFile) sources [source_file];
309 source_info = new SourceFile (source_file);
310 sources.Add (source_file, source_info);
313 current_method = new SourceMethod (method_info, source_info);
315 source_info.AddMethod (current_method);
317 methods.Add (token, current_method);
319 OpenMethod (symbol_token);
322 public void SetMethodSourceRange (ISymbolDocumentWriter startDoc,
323 int startLine, int startColumn,
324 ISymbolDocumentWriter endDoc,
325 int endLine, int endColumn)
327 if ((startDoc == null) || (endDoc == null))
328 throw new NullReferenceException ();
330 if (!(startDoc is MonoSymbolDocumentWriter) || !(endDoc is MonoSymbolDocumentWriter))
331 throw new NotSupportedException ("both startDoc and endDoc must be of type "
332 + "MonoSymbolDocumentWriter");
334 if (!startDoc.Equals (endDoc))
335 throw new NotSupportedException ("startDoc and endDoc must be the same");
337 if (current_method != null)
338 current_method.SetSourceRange (startLine, startColumn,
341 Console.WriteLine ("SOURCE RANGE");
344 public void CloseMethod () {
345 current_method = null;
348 public void OpenNamespace (string name)
352 public int OpenScope (int startOffset)
354 throw new NotImplementedException ();
357 public void SetScopeRange (int scopeID, int startOffset, int endOffset)
361 public void SetSymAttribute (SymbolToken parent, string name, byte[] data)
365 public void SetUnderlyingWriter (IntPtr underlyingWriter)
369 public void SetUserEntryPoint (SymbolToken entryMethod)
373 public void UsingNamespace (string fullName)
378 // MonoSymbolWriter implementation
380 protected void WriteMethod (DwarfFileWriter.DieCompileUnit parent_die, ISourceMethod method)
382 Console.WriteLine ("WRITING METHOD: " + method.MethodInfo.Name);
384 DwarfFileWriter.DieSubProgram die;
386 die = new DwarfFileWriter.DieSubProgram (parent_die, method);
389 protected void WriteSource (DwarfFileWriter writer, ISourceFile source)
391 Console.WriteLine ("WRITING SOURCE: " + source.FileName);
393 DwarfFileWriter.CompileUnit compile_unit = new DwarfFileWriter.CompileUnit (
394 writer, source.FileName);
396 DwarfFileWriter.DieCompileUnit die = new DwarfFileWriter.DieCompileUnit (compile_unit);
398 foreach (ISourceMethod method in source.Methods)
399 WriteMethod (die, method);
402 protected void CreateDwarfFile (string filename)
404 Console.WriteLine ("WRITING DWARF FILE: " + filename);
406 DwarfFileWriter writer = new DwarfFileWriter (filename);
408 foreach (ISourceFile source in sources.Values)
409 WriteSource (writer, source);
413 Console.WriteLine ("DONE WRITING DWARF FILE");