using System;
using System.IO;
using System.Collections;
-using System.Diagnostics.SymbolStore;
+using Mono.CompilerServices.SymbolWriter;
namespace Mono.CSharp {
/// <summary>
/// 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)
{
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>
/// 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>
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);
// </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);
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)
}
}
+ 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.
// 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];
}
}
}