New tests.
[mono.git] / mcs / mcs / symbolwriter.cs
index 148875711e3eb3ca24de88b305fc4a712be555ab..5159f73d0bfa97257b8ddbb4a305a6a7123db94b 100644 (file)
 // Author:
 //   Martin Baulig (martin@ximian.com)
 //
-// (C) 2003 Ximian, Inc.
+// Copyright 2003 Ximian, Inc.
+// Copyright 2003-2008 Novell, Inc.
 //
 
 using System;
-using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
-using System.Diagnostics.SymbolStore;
+
+using Mono.CompilerServices.SymbolWriter;
 
 namespace Mono.CSharp {
-       public class SymbolWriter {
-               ISymbolWriter symwriter;
-               MethodInfo define_namespace;
-               MethodInfo open_method;
+       public static class SymbolWriter
+       {
+               public static bool HasSymbolWriter {
+                       get { return symwriter != null; }
+               }
+
+               private static SymbolWriterImpl symwriter;
+
+               class SymbolWriterImpl : MonoSymbolWriter {
+#if !NET_4_0
+                       delegate int GetILOffsetFunc (ILGenerator ig);
+                       GetILOffsetFunc get_il_offset_func;
+#endif
+                       delegate Guid GetGuidFunc (ModuleBuilder mb);
+
+                       GetGuidFunc get_guid_func;
+
+                       ModuleBuilder module_builder;
+
+                       public SymbolWriterImpl (ModuleBuilder module_builder, string filename)
+                               : base (filename)
+                       {
+                               this.module_builder = module_builder;
+                       }
+
+                       public int GetILOffset (ILGenerator ig)
+                       {
+#if NET_4_0
+                               return ig.ILOffset;
+#else
+                               return get_il_offset_func (ig);
+#endif
+                       }
+
+                       public void WriteSymbolFile ()
+                       {
+                               Guid guid = get_guid_func (module_builder);
+                               WriteSymbolFile (guid);
+                       }
 
-               protected SymbolWriter (ISymbolWriter symwriter)
+                       public bool Initialize ()
+                       {
+                               MethodInfo mi;
+#if !NET_4_0
+                               mi = typeof (ILGenerator).GetMethod (
+                                       "Mono_GetCurrentOffset",
+                                       BindingFlags.Static | BindingFlags.NonPublic);
+                               if (mi == null)
+                                       return false;
+
+                               get_il_offset_func = (GetILOffsetFunc) System.Delegate.CreateDelegate (
+                                       typeof (GetILOffsetFunc), mi);
+#endif
+
+                               mi = typeof (ModuleBuilder).GetMethod (
+                                       "Mono_GetGuid",
+                                       BindingFlags.Static | BindingFlags.NonPublic);
+                               if (mi == null)
+                                       return false;
+
+                               get_guid_func = (GetGuidFunc) System.Delegate.CreateDelegate (
+                                       typeof (GetGuidFunc), mi);
+
+                               Location.DefineSymbolDocuments (this);
+
+                               return true;
+                       }
+               }
+
+               public static void DefineLocalVariable (string name, LocalBuilder builder)
                {
-                       this.symwriter = symwriter;
+                       if (symwriter != null) {
+                               int index = MonoDebuggerSupport.GetLocalIndex (builder);
+                               symwriter.DefineLocalVariable (index, name);
+                       }
                }
 
-               bool Initialize ()
+               public static SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id,
+                                                             IMethodDef method)
                {
-                       Type type = symwriter.GetType ();
-                       define_namespace = type.GetMethod ("DefineNamespace", new Type[] {
-                               typeof (string), typeof (ISymbolDocumentWriter),
-                               typeof (string []), typeof (int) });
-                       if (define_namespace == null)
-                               return false;
+                       if (symwriter != null)
+                               return symwriter.OpenMethod (file, ns_id, method);
+                       else
+                               return null;
+               }
 
-                       open_method = type.GetMethod ("OpenMethod", new Type[] {
-                               typeof (ISymbolDocumentWriter), typeof (int), typeof (int),
-                               typeof (int), typeof (int), typeof (MethodBase), typeof (int) });
-                       if (open_method == null)
-                               return false;
+               public static void CloseMethod ()
+               {
+                       if (symwriter != null)
+                               symwriter.CloseMethod ();
+               }
 
-                       Location.DefineSymbolDocuments (this);
-                       Namespace.DefineNamespaces (this);
+               public static int OpenScope (ILGenerator ig)
+               {
+                       if (symwriter != null) {
+                               int offset = symwriter.GetILOffset (ig);
+                               return symwriter.OpenScope (offset);
+                       } else {
+                               return -1;
+                       }
+               }
 
-                       return true;
+               public static void CloseScope (ILGenerator ig)
+               {
+                       if (symwriter != null) {
+                               int offset = symwriter.GetILOffset (ig);
+                               symwriter.CloseScope (offset);
+                       }
                }
 
-               public ISymbolDocumentWriter DefineDocument (string path)
+               public static int DefineNamespace (string name, CompileUnitEntry source,
+                                                  string[] using_clauses, int parent)
                {
-                       return symwriter.DefineDocument (
-                               path, SymLanguageType.CSharp, SymLanguageVendor.Microsoft,
-                               SymDocumentType.Text);
+                       if (symwriter != null)
+                               return symwriter.DefineNamespace (name, source, using_clauses, parent);
+                       else
+                               return -1;
                }
 
-               public int DefineNamespace (string name, SourceFile file, string[] using_list, int parent)
+#region Terrania additions
+               public static void DefineAnonymousScope (int id)
                {
-                       if (file.SymbolDocument == null)
-                               return 0;
-                       return (int) define_namespace.Invoke (symwriter, new object[] {
-                               name, file.SymbolDocument, using_list, parent });
+                       if (symwriter != null)
+                               symwriter.DefineAnonymousScope (id);
                }
 
-               public void OpenMethod (TypeContainer parent, MethodBase method, Location start, Location end)
+               public static void DefineScopeVariable (int scope, LocalBuilder builder)
                {
-                       int ns_id = parent.NamespaceEntry.SymbolFileID;
-                       open_method.Invoke (symwriter, new object[] {
-                               start.SymbolDocument, start.Row, 0, end.Row, 0, method, ns_id });
+                       if (symwriter != null) {
+                               int index = MonoDebuggerSupport.GetLocalIndex (builder);
+                               symwriter.DefineScopeVariable (scope, index);
+                       }
                }
 
-               public void CloseMethod ()
+               public static void DefineScopeVariable (int scope)
                {
-                       symwriter.CloseMethod ();
+                       if (symwriter != null)
+                               symwriter.DefineScopeVariable (scope, -1);
                }
 
-               public static SymbolWriter GetSymbolWriter (ModuleBuilder module)
+               public static void DefineCapturedLocal (int scope_id, string name,
+                                                       string captured_name)
                {
-                       ISymbolWriter symwriter = module.GetSymWriter ();
+                       if (symwriter != null)
+                               symwriter.DefineCapturedLocal (scope_id, name, captured_name);
+               }
 
-                       if (symwriter == null)
-                               return null;
+               public static void DefineCapturedParameter (int scope_id, string name,
+                                                           string captured_name)
+               {
+                       if (symwriter != null)
+                               symwriter.DefineCapturedParameter (scope_id, name, captured_name);
+               }
 
-                       SymbolWriter writer = new SymbolWriter (symwriter);
-                       if (!writer.Initialize ())
-                               return null;
+               public static void DefineCapturedThis (int scope_id, string captured_name)
+               {
+                       if (symwriter != null)
+                               symwriter.DefineCapturedThis (scope_id, captured_name);
+               }
 
-                       return writer;
+               public static void DefineCapturedScope (int scope_id, int id, string captured_name)
+               {
+                       if (symwriter != null)
+                               symwriter.DefineCapturedScope (scope_id, id, captured_name);
+               }
+
+               public static void OpenCompilerGeneratedBlock (EmitContext ec)
+               {
+                       if (symwriter != null) {
+                               int offset = symwriter.GetILOffset (ec.ig);
+                               symwriter.OpenCompilerGeneratedBlock (offset);
+                       }
+               }
+
+               public static void CloseCompilerGeneratedBlock (EmitContext ec)
+               {
+                       if (symwriter != null) {
+                               int offset = symwriter.GetILOffset (ec.ig);
+                               symwriter.CloseCompilerGeneratedBlock (offset);
+                       }
+               }
+
+               public static void StartIteratorBody (EmitContext ec)
+               {
+                       if (symwriter != null) {
+                               int offset = symwriter.GetILOffset (ec.ig);
+                               symwriter.StartIteratorBody (offset);
+                       }
+               }
+
+               public static void EndIteratorBody (EmitContext ec)
+               {
+                       if (symwriter != null) {
+                               int offset = symwriter.GetILOffset (ec.ig);
+                               symwriter.EndIteratorBody (offset);
+                       }
+               }
+
+               public static void StartIteratorDispatcher (EmitContext ec)
+               {
+                       if (symwriter != null) {
+                               int offset = symwriter.GetILOffset (ec.ig);
+                               symwriter.StartIteratorDispatcher (offset);
+                       }
+               }
+
+               public static void EndIteratorDispatcher (EmitContext ec)
+               {
+                       if (symwriter != null) {
+                               int offset = symwriter.GetILOffset (ec.ig);
+                               symwriter.EndIteratorDispatcher (offset);
+                       }
+               }
+#endregion
+
+               public static void MarkSequencePoint (ILGenerator ig, Location loc)
+               {
+                       if (symwriter != null) {
+                               SourceFileEntry file = loc.SourceFile.SourceFileEntry;
+                               int offset = symwriter.GetILOffset (ig);
+                               symwriter.MarkSequencePoint (
+                                       offset, file, loc.Row, loc.Column, loc.Hidden);
+                       }
+               }
+
+               public static void WriteSymbolFile ()
+               {
+                       if (symwriter != null)
+                               symwriter.WriteSymbolFile ();
+               }
+
+               public static bool Initialize (ModuleBuilder module, string filename)
+               {
+                       symwriter = new SymbolWriterImpl (module, filename);
+                       if (!symwriter.Initialize ()) {
+                               symwriter = null;
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               public static void Reset ()
+               {
+                       symwriter = null;
                }
        }
 }