2005-05-31 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / mcs / location.cs
index 6adee744b43b11529fa865f63d483b871c37e4c7..6b31c64c960c784bc22e52d5b48a0a36473ec357 100644 (file)
@@ -10,7 +10,7 @@
 using System;
 using System.IO;
 using System.Collections;
-using System.Diagnostics.SymbolStore;
+using Mono.CompilerServices.SymbolWriter;
 
 namespace Mono.CSharp {
        /// <summary>
@@ -20,11 +20,12 @@ namespace Mono.CSharp {
        ///   This is intentionally a class and not a struct since we need
        ///   to pass this by reference.
        /// </remarks>
-       public sealed class SourceFile {
+       public sealed class SourceFile : ISourceFile {
                public readonly string Name;
                public readonly string Path;
                public readonly int Index;
-               public ISymbolDocumentWriter SymbolDocument;
+               public SourceFileEntry SourceFileEntry;
+               public bool HasLineDirective;
 
                public SourceFile (string name, string path, int index)
                {
@@ -32,6 +33,16 @@ namespace Mono.CSharp {
                        this.Name = name;
                        this.Path = path;
                }
+
+               SourceFileEntry ISourceFile.Entry {
+                       get { return SourceFileEntry; }
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("SourceFile ({0}:{1}:{2}:{3})",
+                                             Name, Path, Index, SourceFileEntry);
+               }
        }
 
        /// <summary>
@@ -46,25 +57,30 @@ namespace Mono.CSharp {
        ///   in 8 bits (and say, map anything after char 255 to be `255+').
        /// </remarks>
        public struct Location {
-               public int token; 
+               int token; 
 
                static ArrayList source_list;
                static Hashtable source_files;
                static int source_bits;
                static int source_mask;
                static int source_count;
-               static int module_base;
                static int current_source;
 
-               public readonly static Location Null;
+               public readonly static Location Null = new Location (-1);
                
                static Location ()
                {
                        source_files = new Hashtable ();
                        source_list = new ArrayList ();
                        current_source = 0;
-                       module_base = 0;
-                       Null.token = 0;
+               }
+
+               public static void Reset ()
+               {
+                       source_files = new Hashtable ();
+                       source_list = new ArrayList ();
+                       current_source = 0;
+                       source_count = 0;
                }
 
                // <summary>
@@ -75,10 +91,13 @@ namespace Mono.CSharp {
                        string path = Path.GetFullPath (name);
 
                        if (source_files.Contains (path)){
-                               Report.Error (
-                                       1516,
-                                       "Source file `" + name + "' specified multiple times");
-                               Environment.Exit (1);
+                               int id = (int) source_files [path];
+                               string other_name = ((SourceFile) source_list [id - 1]).Name;
+                               if (name.Equals (other_name))
+                                       Report.Warning (2002, "Source file '{0}' specified multiple times", name);
+                               else
+                                       Report.Warning (2002, "Source filenames '{0}' and '{1}' both refer to the same file: {2}", name, other_name, path);
+                               return;
                        }
 
                        source_files.Add (path, ++source_count);
@@ -121,10 +140,10 @@ namespace Mono.CSharp {
                // </remarks>
                static public SourceFile LookupFile (string name)
                {
-                       string path = Path.GetFullPath (name);
+                       string path = name == "" ? "" : Path.GetFullPath (name);
 
                        if (!source_files.Contains (path)) {
-                               if (source_count >= source_bits * 8)
+                               if (source_count >= (1 << source_bits))
                                        return new SourceFile (name, path, 0);
 
                                source_files.Add (path, ++source_count);
@@ -140,17 +159,18 @@ namespace Mono.CSharp {
                static public void Push (SourceFile file)
                {
                        current_source = file.Index;
-                       module_base = current_source << source_bits;
                }
 
                // <remarks>
-               //   If we're compiling with debugging support, this is called between parsing and
-               //   code generation to register all the source files with the symbol writer.           //
+               //   If we're compiling with debugging support, this is called between parsing
+               //   and code generation to register all the source files with the
+               //   symbol writer.
                // </remarks>
                static public void DefineSymbolDocuments (SymbolWriter symwriter)
                {
-                       foreach (SourceFile file in source_list)
-                               file.SymbolDocument = symwriter.DefineDocument (file.Path);
+                       foreach (SourceFile file in source_list) {
+                               file.SourceFileEntry = symwriter.DefineDocument (file.Path);
+                       }
                }
                
                public Location (int row)
@@ -194,6 +214,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public int File {
+                       get {
+                               return token & source_mask;
+                       }
+               }
+
                // The ISymbolDocumentWriter interface is used by the symbol writer to
                // describe a single source file - for each source file there's exactly
                // one corresponding ISymbolDocumentWriter instance.
@@ -206,13 +232,12 @@ namespace Mono.CSharp {
                // to the location's source file.
                //
                // If we don't have a symbol writer, this property is always null.
-               public ISymbolDocumentWriter SymbolDocument {
+               public SourceFile SourceFile {
                        get {
                                int index = token & source_mask;
                                if (index == 0)
                                        return null;
-                               SourceFile file = (SourceFile) source_list [index - 1];
-                               return file.SymbolDocument;
+                               return (SourceFile) source_list [index - 1];
                        }
                }
        }