From 335fe9493d7c310ef86137f9542adbeb34970aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Kr=C3=BCger?= Date: Tue, 7 Feb 2012 10:26:00 +0100 Subject: [PATCH] Updated mcs. --- .../Parser/CSharpParser.cs | 7 +- .../Parser/mcs/MonoSymbolFile.cs | 22 +- .../Parser/mcs/MonoSymbolTable.cs | 9 +- .../Parser/mcs/MonoSymbolWriter.cs | 5 +- .../Parser/mcs/anonymous.cs | 37 +-- .../Parser/mcs/assembly.cs | 12 +- .../Parser/mcs/assign.cs | 13 +- .../Parser/mcs/class.cs | 34 ++- .../Parser/mcs/codegen.cs | 28 +- .../Parser/mcs/context.cs | 13 +- .../Parser/mcs/cs-parser.cs | 35 ++- .../Parser/mcs/cs-parser.jay | 20 +- .../Parser/mcs/cs-tokenizer.cs | 276 ++++++++++++------ .../Parser/mcs/decl.cs | 17 +- .../Parser/mcs/delegate.cs | 4 +- .../Parser/mcs/doc.cs | 15 +- .../Parser/mcs/driver.cs | 46 +-- .../Parser/mcs/ecore.cs | 2 +- .../Parser/mcs/eval.cs | 22 +- .../Parser/mcs/expression.cs | 3 +- .../Parser/mcs/generic.cs | 9 +- .../Parser/mcs/location.cs | 232 +++++---------- .../Parser/mcs/method.cs | 110 +++---- .../Parser/mcs/module.cs | 2 +- .../Parser/mcs/namespace.cs | 177 +++++++---- .../Parser/mcs/report.cs | 133 ++------- .../Parser/mcs/settings.cs | 165 +++++++++-- .../Parser/mcs/statement.cs | 122 ++++---- .../Parser/mcs/symbolwriter.cs | 17 +- 29 files changed, 855 insertions(+), 732 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs b/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs index accd3c38bb..ace51a3c5e 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs @@ -3574,10 +3574,11 @@ namespace ICSharpCode.NRefactory.CSharp { lock (parseLock) { errorReportPrinter = new ErrorReportPrinter (""); - var ctx = new CompilerContext (CompilerSettings, new Report (errorReportPrinter)); + var ctx = new CompilerContext (CompilerSettings, errorReportPrinter); + ctx.Settings.TabSize = 1; var reader = new SeekableStreamReader (stream, Encoding.UTF8); - var file = new CompilationSourceFile (fileName, fileName, 0); - Location.Initialize (new List (new [] { file })); + var file = new SourceFile (fileName, fileName, 0); + Location.Initialize (new List (new [] { file })); var module = new ModuleContainer (ctx); var driver = new Driver (ctx); var parser = driver.Parse (reader, file, module); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs index 465f4c7cbe..583289595f 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs @@ -156,7 +156,6 @@ namespace Mono.CompilerServices.SymbolWriter List methods = new List (); List sources = new List (); List comp_units = new List (); - Dictionary type_hash = new Dictionary (); Dictionary anonymous_scopes; OffsetTable ot; @@ -187,17 +186,6 @@ namespace Mono.CompilerServices.SymbolWriter return comp_units.Count; } - internal int DefineType (Type type) - { - int index; - if (type_hash.TryGetValue (type, out index)) - return index; - - index = ++last_type_index; - type_hash.Add (type, index); - return index; - } - internal void AddMethod (MethodEntry entry) { methods.Add (entry); @@ -285,7 +273,7 @@ namespace Mono.CompilerServices.SymbolWriter // methods.Sort (); for (int i = 0; i < methods.Count; i++) - ((MethodEntry) methods [i]).Index = i + 1; + methods [i].Index = i + 1; // // Write data sections. @@ -304,7 +292,7 @@ namespace Mono.CompilerServices.SymbolWriter // ot.MethodTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < methods.Count; i++) { - MethodEntry entry = (MethodEntry) methods [i]; + MethodEntry entry = methods [i]; entry.Write (bw); } ot.MethodTableSize = (int) bw.BaseStream.Position - ot.MethodTableOffset; @@ -314,7 +302,7 @@ namespace Mono.CompilerServices.SymbolWriter // ot.SourceTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < sources.Count; i++) { - SourceFileEntry source = (SourceFileEntry) sources [i]; + SourceFileEntry source = sources [i]; source.Write (bw); } ot.SourceTableSize = (int) bw.BaseStream.Position - ot.SourceTableOffset; @@ -324,7 +312,7 @@ namespace Mono.CompilerServices.SymbolWriter // ot.CompileUnitTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < comp_units.Count; i++) { - CompileUnitEntry unit = (CompileUnitEntry) comp_units [i]; + CompileUnitEntry unit = comp_units [i]; unit.Write (bw); } ot.CompileUnitTableSize = (int) bw.BaseStream.Position - ot.CompileUnitTableOffset; @@ -633,7 +621,7 @@ namespace Mono.CompilerServices.SymbolWriter lock (this) { read_methods (); - return (MethodEntry) method_list [index - 1]; + return method_list [index - 1]; } } diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs index 5f30818ff6..a4e75bd969 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs @@ -185,7 +185,7 @@ namespace Mono.CompilerServices.SymbolWriter public readonly int Row; public readonly int File; public readonly int Offset; - public readonly bool IsHidden; + public readonly bool IsHidden; // Obsolete is never used #endregion public LineNumberEntry (int file, int row, int offset) @@ -568,6 +568,7 @@ namespace Mono.CompilerServices.SymbolWriter } } + [Obsolete] public int DefineNamespace (string name, string[] using_clauses, int parent) { if (!creating) @@ -700,6 +701,12 @@ namespace Mono.CompilerServices.SymbolWriter this.hash = checksum; } + public byte[] Checksum { + get { + return hash; + } + } + internal void WriteData (MyBinaryWriter bw) { DataOffset = (int) bw.BaseStream.Position; diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs index 4d6d1f3d2d..8cc380d4c2 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolWriter.cs @@ -153,6 +153,7 @@ namespace Mono.CompilerServices.SymbolWriter return entry; } + [Obsolete] public int DefineNamespace (string name, CompileUnitEntry unit, string[] using_clauses, int parent) { @@ -370,10 +371,12 @@ namespace Mono.CompilerServices.SymbolWriter new ScopeVariable (scope, index)); } + [Obsolete] public string RealMethodName { get { return _real_name; } } + [Obsolete ("It has no meaning")] public void SetRealMethodName (string name) { _real_name = name; @@ -394,7 +397,7 @@ namespace Mono.CompilerServices.SymbolWriter MethodEntry entry = new MethodEntry ( file, _comp_unit.Entry, _method.Token, ScopeVariables, - Locals, lines, Blocks, RealMethodName, 0, //_method_flags, + Locals, lines, Blocks, _real_name, 0, //_method_flags, _ns_id); file.AddMethod (entry); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs index 5afead6a68..6d59cc6cc4 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs @@ -1039,16 +1039,10 @@ namespace Mono.CSharp { return false; for (int i = 0; i < Parameters.Count; ++i) { - TypeSpec itype = d_params.Types [i]; - if (!TypeManager.IsGenericParameter (itype)) { - if (!TypeManager.HasElementType (itype)) - continue; - - if (!TypeManager.IsGenericParameter (TypeManager.GetElementType (itype))) - continue; - } - type_inference.ExactInference (Parameters.Types [i], itype); + if (type_inference.ExactInference (Parameters.Types[i], d_params.Types[i]) == 0) + return false; } + return true; } @@ -1318,18 +1312,16 @@ namespace Mono.CSharp { { public readonly AnonymousExpression AnonymousMethod; public readonly AnonymousMethodStorey Storey; - readonly string RealName; public AnonymousMethodMethod (TypeDefinition parent, AnonymousExpression am, AnonymousMethodStorey storey, TypeExpr return_type, - Modifiers mod, string real_name, MemberName name, + Modifiers mod, MemberName name, ParametersCompiled parameters) : base (parent, return_type, mod | Modifiers.COMPILER_GENERATED, name, parameters, null) { this.AnonymousMethod = am; this.Storey = storey; - this.RealName = real_name; Parent.PartialContainer.Members.Add (this); Block = new ToplevelBlock (am.block, parameters); @@ -1373,11 +1365,6 @@ namespace Mono.CSharp { base.Emit (); } - - public override void EmitExtraSymbolInfo (SourceMethod source) - { - source.SetRealMethodName (RealName); - } } protected ParametersBlock block; @@ -1577,7 +1564,6 @@ namespace Mono.CSharp { var parent = storey != null ? storey : ec.CurrentTypeDefinition.Parent.PartialContainer; - MemberCore mc = ec.MemberContext as MemberCore; string name = CompilerGeneratedClass.MakeName (parent != storey ? block_name : null, "m", null, ec.Module.CounterAnonymousMethods++); @@ -1595,13 +1581,9 @@ namespace Mono.CSharp { member_name = new MemberName (name, Location); } - string real_name = String.Format ( - "{0}~{1}{2}", mc.GetSignatureForError (), GetSignatureForError (), - parameters.GetSignatureForError ()); - return new AnonymousMethodMethod (parent, this, storey, new TypeExpression (ReturnType, Location), modifiers, - real_name, member_name, parameters); + member_name, parameters); } protected override Expression DoResolve (ResolveContext ec) @@ -1756,8 +1738,8 @@ namespace Mono.CSharp { readonly IList parameters; - private AnonymousTypeClass (TypeContainer parent, MemberName name, IList parameters, Location loc) - : base (parent, name, (parent.Module.Evaluator != null ? Modifiers.PUBLIC : 0) | Modifiers.SEALED) + private AnonymousTypeClass (ModuleContainer parent, MemberName name, IList parameters, Location loc) + : base (parent, name, (parent.Evaluator != null ? Modifiers.PUBLIC : 0) | Modifiers.SEALED) { this.parameters = parameters; } @@ -2043,6 +2025,11 @@ namespace Mono.CSharp { return SignatureForError; } + public override CompilationSourceFile GetCompilationSourceFile () + { + return null; + } + public IList Parameters { get { return parameters; diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs index 3574c49ee3..0dad8ff0f3 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs @@ -448,11 +448,6 @@ namespace Mono.CSharp if (Compiler.Settings.GenerateDebugInfo) { symbol_writer = new MonoSymbolWriter (file_name); - // Register all source files with symbol writer - foreach (var source in Compiler.SourceFiles) { - source.DefineSymbolInfo (symbol_writer); - } - // TODO: global variables SymbolWriter.symwriter = symbol_writer; } @@ -484,12 +479,7 @@ namespace Mono.CSharp Builder.__AddDeclarativeSecurity (entry); } #else - var args = new PermissionSet[3]; -#pragma warning disable 618 - declarative_security.TryGetValue (SecurityAction.RequestMinimum, out args[0]); - declarative_security.TryGetValue (SecurityAction.RequestOptional, out args[1]); - declarative_security.TryGetValue (SecurityAction.RequestRefuse, out args[2]); - builder_extra.AddPermissionRequests (args); + throw new NotSupportedException ("Assembly-level security"); #endif } diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs index 4fc2e6e9a4..774b312069 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs @@ -565,7 +565,18 @@ namespace Mono.CSharp { { if (resolved == null) return; - + + // + // Emit sequence symbol info even if we are in compiler generated + // block to allow debugging filed initializers when constructor is + // compiler generated + // + if (ec.HasSet (BuilderContext.Options.OmitDebugInfo)) { + using (ec.With (BuilderContext.Options.OmitDebugInfo, false)) { + ec.Mark (loc); + } + } + if (resolved != this) resolved.EmitStatement (ec); else diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs index babad42806..bc3902682d 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs @@ -242,11 +242,11 @@ namespace Mono.CSharp return true; } - public virtual void DefineConstants () + public virtual void PrepareEmit () { if (containers != null) { foreach (var t in containers) { - t.DefineConstants (); + t.PrepareEmit (); } } } @@ -1006,6 +1006,18 @@ namespace Mono.CSharp return a.GetAttributeUsageAttribute (); } + public virtual CompilationSourceFile GetCompilationSourceFile () + { + TypeContainer ns = Parent; + while (true) { + var sf = ns as CompilationSourceFile; + if (sf != null) + return sf; + + ns = ns.Parent; + } + } + public virtual void AddBasesForPart (List bases) { type_bases = bases; @@ -1462,7 +1474,7 @@ namespace Mono.CSharp return true; } - public override void DefineConstants () + public override void PrepareEmit () { foreach (var member in members) { var pm = member as IParametersMember; @@ -1480,7 +1492,7 @@ namespace Mono.CSharp c.DefineValue (); } - base.DefineConstants (); + base.PrepareEmit (); } // @@ -1817,7 +1829,7 @@ namespace Mono.CSharp // // Check for internal or private fields that were never assigned // - if (!IsCompilerGenerated && Report.WarningLevel >= 3) { + if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) { bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly (); foreach (var member in members) { if (member is Event) { @@ -1858,7 +1870,7 @@ namespace Mono.CSharp // // Only report 649 on level 4 // - if (Report.WarningLevel < 4) + if (Compiler.Settings.WarningLevel < 4) continue; // @@ -2366,12 +2378,14 @@ namespace Mono.CSharp mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC; } - Constructor c = new Constructor (this, MemberName.Name, mods, - null, ParametersCompiled.EmptyReadOnlyParameters, Location); + var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location); c.Initializer = new GeneratedBaseInitializer (Location); AddConstructor (c, true); - c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location); + c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) { + IsCompilerGenerated = true + }; + return c; } @@ -2467,7 +2481,7 @@ namespace Mono.CSharp return; } - if (a.Type.IsConditionallyExcluded (Compiler, Location)) + if (a.Type.IsConditionallyExcluded (this, Location)) return; base.ApplyAttributeBuilder (a, ctor, cdata, pa); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs index 8a5c4c4836..bb79678ba6 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs @@ -89,6 +89,13 @@ namespace Mono.CSharp if (rc.Module.Compiler.Settings.Checked) flags |= Options.CheckedScope; + if (SymbolWriter.HasSymbolWriter) { + if (!rc.Module.Compiler.Settings.Optimize) + flags |= Options.AccurateDebugInfo; + } else { + flags |= Options.OmitDebugInfo; + } + #if STATIC ig.__CleverExceptionBlockAssistance (); #endif @@ -120,6 +127,12 @@ namespace Mono.CSharp get { return member_context.CurrentMemberDefinition; } } + public bool EmitAccurateDebugInfo { + get { + return (flags & Options.AccurateDebugInfo) != 0; + } + } + public bool HasReturnLabel { get { return return_label.HasValue; @@ -188,12 +201,19 @@ namespace Mono.CSharp /// This is called immediately before emitting an IL opcode to tell the symbol /// writer to which source line this opcode belongs. /// - public void Mark (Location loc) + public bool Mark (Location loc) { - if (!SymbolWriter.HasSymbolWriter || HasSet (Options.OmitDebugInfo) || loc.IsNull) - return; + if ((flags & Options.OmitDebugInfo) != 0) + return false; + + if (loc.IsNull) + return false; + + if (loc.SourceFile.IsHiddenLocation (loc)) + return false; SymbolWriter.MarkSequencePoint (ig, loc); + return true; } public void DefineLocalVariable (string name, LocalBuilder builder) @@ -865,7 +885,7 @@ namespace Mono.CSharp public void Emit (EmitContext ec, MethodSpec method, Arguments Arguments, Location loc) { // Speed up the check by not doing it on not allowed targets - if (method.ReturnType.Kind == MemberKind.Void && method.IsConditionallyExcluded (ec.Module.Compiler, loc)) + if (method.ReturnType.Kind == MemberKind.Void && method.IsConditionallyExcluded (ec.MemberContext, loc)) return; EmitPredefined (ec, method, Arguments); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs index 24fedc69d5..4a2318c2b5 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs @@ -586,10 +586,10 @@ namespace Mono.CSharp Dictionary all_source_files; - public CompilerContext (CompilerSettings settings, Report report) + public CompilerContext (CompilerSettings settings, ReportPrinter reportPrinter) { this.settings = settings; - this.report = report; + this.report = new Report (this, reportPrinter); this.builtin_types = new BuiltinTypes (); this.TimeReporter = DisabledTimeReporter; } @@ -620,7 +620,7 @@ namespace Mono.CSharp } } - public List SourceFiles { + public List SourceFiles { get { return settings.SourceFiles; } @@ -646,7 +646,7 @@ namespace Mono.CSharp string path; if (!Path.IsPathRooted (name)) { - string root = Path.GetDirectoryName (comp_unit.FullPathName); + string root = Path.GetDirectoryName (comp_unit.SourceFile.FullPathName); path = Path.Combine (root, name); } else path = name; @@ -655,7 +655,8 @@ namespace Mono.CSharp if (all_source_files.TryGetValue (path, out retval)) return retval; - retval = Location.AddFile (name, path); + retval = new SourceFile (name, path, all_source_files.Count + 1); + Location.AddFile (retval); all_source_files.Add (path, retval); return retval; } @@ -681,6 +682,8 @@ namespace Mono.CSharp /// CheckedScope = 1 << 0, + AccurateDebugInfo = 1 << 1, + OmitDebugInfo = 1 << 2, ConstructorScope = 1 << 3, diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs index 20cc531a0f..0ac4334583 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs @@ -1597,10 +1597,7 @@ case 94: } break; case 95: -#line 931 "cs-parser.jay" - { - push_current_container (new Struct (current_container, (MemberName) yyVals[0+yyTop], (Modifiers) yyVals[-4+yyTop], (Attributes) yyVals[-5+yyTop]), yyVals[-3+yyTop]); - } + case_95(); break; case 96: case_96(); @@ -4126,7 +4123,7 @@ void case_21() var name = (MemberName) yyVals[0+yyTop]; if (attrs != null) { bool valid_global_attrs = true; - if ((current_namespace.DeclarationFound || current_namespace != file.NamespaceContainer)) { + if ((current_namespace.DeclarationFound || current_namespace != file)) { valid_global_attrs = false; } else { foreach (var a in attrs.Attrs) { @@ -4144,7 +4141,7 @@ void case_21() module.AddAttributes (attrs, current_namespace); - var ns = new NamespaceContainer (name, module, current_namespace, file); + var ns = new NamespaceContainer (name, current_namespace); current_namespace.AddTypeContainer (ns); current_container = current_namespace = ns; } @@ -4205,7 +4202,7 @@ void case_39() /* we parse succeeding declaration hence we parse them as normal and re-attach them*/ /* when we know whether they are global (assembly:, module:) or local (type:).*/ if (ds.OptAttributes != null) { - ds.OptAttributes.ConvertGlobalAttributes (ds, current_namespace, !current_namespace.DeclarationFound && current_namespace == file.NamespaceContainer); + ds.OptAttributes.ConvertGlobalAttributes (ds, current_namespace, !current_namespace.DeclarationFound && current_namespace == file); } } current_namespace.DeclarationFound = true; @@ -4426,8 +4423,15 @@ void case_93() lexer.parsing_generic_declaration = false; } +void case_95() +#line 929 "cs-parser.jay" +{ + push_current_container (new Struct (current_container, (MemberName) yyVals[0+yyTop], (Modifiers) yyVals[-4+yyTop], (Attributes) yyVals[-5+yyTop]), yyVals[-3+yyTop]); + lbag.AddMember (current_container, GetModifierLocations (), GetLocation (yyVals[-2+yyTop])); + } + void case_96() -#line 934 "cs-parser.jay" +#line 935 "cs-parser.jay" { lexer.ConstraintsParsing = false; @@ -4437,7 +4441,6 @@ void case_96() if (doc_support) current_container.PartialContainer.DocComment = Lexer.consume_doc_comment (); - lbag.AddMember (current_container, GetModifierLocations (), GetLocation (yyVals[-5+yyTop])); lexer.parsing_modifiers = true; } @@ -7182,16 +7185,16 @@ void case_629() } push_current_container (c, yyVals[-3+yyTop]); + lbag.AddMember (current_container, GetModifierLocations (), GetLocation (yyVals[-2+yyTop])); } void case_630() -#line 4318 "cs-parser.jay" +#line 4319 "cs-parser.jay" { lexer.ConstraintsParsing = false; if (yyVals[0+yyTop] != null) current_container.SetConstraints ((List) yyVals[0+yyTop]); - lbag.AddMember (current_container, GetModifierLocations (), GetLocation (yyVals[-5+yyTop])); if (doc_support) { current_container.PartialContainer.DocComment = Lexer.consume_doc_comment (); @@ -12469,17 +12472,17 @@ static CSharpParser () } public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file) - : this (reader, file, file.NamespaceContainer.Module.Compiler.Report) + : this (reader, file, file.Compiler.Report) { } public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report) { this.file = file; - current_container = current_namespace = file.NamespaceContainer; + current_container = current_namespace = file; - this.module = current_namespace.Module; - this.compiler = module.Compiler; + this.module = file.Module; + this.compiler = file.Compiler; this.settings = compiler.Settings; this.report = report; @@ -12487,7 +12490,7 @@ public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Re yacc_verbose_flag = settings.VerboseParserFlag; doc_support = settings.DocumentationFile != null; oob_stack.Clear (); - lexer = new Tokenizer (reader, file, compiler); + lexer = new Tokenizer (reader, file); #if FULL_AST lbag = new LocationsBag (); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay index ff3a4b6f80..9d40d25fe0 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay @@ -502,7 +502,7 @@ namespace_declaration var name = (MemberName) $3; if (attrs != null) { bool valid_global_attrs = true; - if ((current_namespace.DeclarationFound || current_namespace != file.NamespaceContainer)) { + if ((current_namespace.DeclarationFound || current_namespace != file)) { valid_global_attrs = false; } else { foreach (var a in attrs.Attrs) { @@ -520,7 +520,7 @@ namespace_declaration module.AddAttributes (attrs, current_namespace); - var ns = new NamespaceContainer (name, module, current_namespace, file); + var ns = new NamespaceContainer (name, current_namespace); current_namespace.AddTypeContainer (ns); current_container = current_namespace = ns; } @@ -605,7 +605,7 @@ namespace_or_type_declaration // we parse succeeding declaration hence we parse them as normal and re-attach them // when we know whether they are global (assembly:, module:) or local (type:). if (ds.OptAttributes != null) { - ds.OptAttributes.ConvertGlobalAttributes (ds, current_namespace, !current_namespace.DeclarationFound && current_namespace == file.NamespaceContainer); + ds.OptAttributes.ConvertGlobalAttributes (ds, current_namespace, !current_namespace.DeclarationFound && current_namespace == file); } } current_namespace.DeclarationFound = true; @@ -928,6 +928,7 @@ struct_declaration type_declaration_name { push_current_container (new Struct (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3); + lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4)); } opt_class_base opt_type_parameter_constraints_clauses @@ -940,7 +941,6 @@ struct_declaration if (doc_support) current_container.PartialContainer.DocComment = Lexer.consume_doc_comment (); - lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4)); lexer.parsing_modifiers = true; } @@ -4312,6 +4312,7 @@ class_declaration } push_current_container (c, $3); + lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4)); } opt_class_base opt_type_parameter_constraints_clauses @@ -4320,7 +4321,6 @@ class_declaration if ($9 != null) current_container.SetConstraints ((List) $9); - lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4)); if (doc_support) { current_container.PartialContainer.DocComment = Lexer.consume_doc_comment (); @@ -6609,17 +6609,17 @@ static CSharpParser () } public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file) - : this (reader, file, file.NamespaceContainer.Module.Compiler.Report) + : this (reader, file, file.Compiler.Report) { } public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report) { this.file = file; - current_container = current_namespace = file.NamespaceContainer; + current_container = current_namespace = file; - this.module = current_namespace.Module; - this.compiler = module.Compiler; + this.module = file.Module; + this.compiler = file.Compiler; this.settings = compiler.Settings; this.report = report; @@ -6627,7 +6627,7 @@ public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Re yacc_verbose_flag = settings.VerboseParserFlag; doc_support = settings.DocumentationFile != null; oob_stack.Clear (); - lexer = new Tokenizer (reader, file, compiler); + lexer = new Tokenizer (reader, file); #if FULL_AST lbag = new LocationsBag (); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs index 92188c8d15..8fc3d9c0a8 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs @@ -132,7 +132,7 @@ namespace Mono.CSharp { #if !FULL_AST if (buffer.Length == 0) - buffer = new LocatedToken [10000]; + buffer = new LocatedToken [15000]; #endif pos = 0; } @@ -161,23 +161,24 @@ namespace Mono.CSharp Error = 9, Warning = 10, Pragma = 11 | CustomArgumentsParsing, - Line = 12, + Line = 12 | CustomArgumentsParsing, CustomArgumentsParsing = 1 << 10, RequiresArgument = 1 << 11 } - SeekableStreamReader reader; - SourceFile ref_name; - CompilationSourceFile file_name; - CompilerContext context; - bool hidden = false; + readonly SeekableStreamReader reader; + readonly CompilationSourceFile source_file; + readonly CompilerContext context; + + SourceFile current_source; + Location hidden_block_start; int ref_line = 1; int line = 1; int col = 0; int previous_col; int current_token; - int tab_size; + readonly int tab_size; bool handle_get_set = false; bool handle_remove_add = false; bool handle_where = false; @@ -275,6 +276,9 @@ namespace Mono.CSharp static readonly char[] pragma_warning_disable = "disable".ToCharArray (); static readonly char[] pragma_warning_restore = "restore".ToCharArray (); static readonly char[] pragma_checksum = "checksum".ToCharArray (); + static readonly char[] line_hidden = "hidden".ToCharArray (); + static readonly char[] line_default = "default".ToCharArray (); + static readonly char[] simple_whitespaces = new char[] { ' ', '\t' }; bool startsLine = true; internal SpecialsBag sbag; @@ -298,12 +302,7 @@ namespace Mono.CSharp get { return handle_typeof; } set { handle_typeof = value; } } - - public int TabSize { - get { return tab_size; } - set { tab_size = value; } - } - + public XmlCommentState doc_state { get { return xml_doc_state; } set { @@ -393,7 +392,7 @@ namespace Mono.CSharp public int line; public int ref_line; public int col; - public bool hidden; + public Location hidden; public int putback_char; public int previous_col; public Stack ifstack; @@ -407,7 +406,7 @@ namespace Mono.CSharp line = t.line; ref_line = t.ref_line; col = t.col; - hidden = t.hidden; + hidden = t.hidden_block_start; putback_char = t.putback_char; previous_col = t.previous_col; if (t.ifstack != null && t.ifstack.Count != 0) { @@ -423,24 +422,22 @@ namespace Mono.CSharp } } - public Tokenizer (SeekableStreamReader input, CompilationSourceFile file, CompilerContext ctx) + public Tokenizer (SeekableStreamReader input, CompilationSourceFile file) { - this.ref_name = file; - this.file_name = file; - this.context = ctx; + this.source_file = file; + this.context = file.Compiler; + this.current_source = file.SourceFile; + reader = input; putback_char = -1; xml_comment_buffer = new StringBuilder (); - doc_processing = ctx.Settings.DocumentationFile != null; + doc_processing = context.Settings.DocumentationFile != null; - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - tab_size = 4; - else - tab_size = 8; + tab_size = context.Settings.TabSize; - Mono.CSharp.Location.Push (file, file); + Mono.CSharp.Location.Push (current_source); } public void PushPosition () @@ -456,7 +453,7 @@ namespace Mono.CSharp ref_line = p.ref_line; line = p.line; col = p.col; - hidden = p.hidden; + hidden_block_start = p.hidden; putback_char = p.putback_char; previous_col = p.previous_col; ifstack = p.ifstack; @@ -886,7 +883,7 @@ namespace Mono.CSharp public Location Location { get { - return new Location (ref_line, hidden ? -1 : col); + return new Location (ref_line, col); } } @@ -1799,7 +1796,7 @@ namespace Mono.CSharp if (putback_char != -1){ Console.WriteLine ("Col: " + col); Console.WriteLine ("Row: " + line); - Console.WriteLine ("Name: " + ref_name.Name); + Console.WriteLine ("Name: " + current_source.Name); Console.WriteLine ("Current [{0}] putting back [{1}] ", putback_char, c); throw new Exception ("This should not happen putback on putback"); } @@ -1960,44 +1957,120 @@ namespace Mono.CSharp // // Handles the #line directive // - bool PreProcessLine (string arg) + bool PreProcessLine () { - if (arg.Length == 0) - return false; + Location loc = Location; + + int c; + + int length = TokenizePreprocessorIdentifier (out c); + if (length == line_default.Length) { + if (!IsTokenIdentifierEqual (line_default)) + return false; + + current_source = source_file.SourceFile; + if (!hidden_block_start.IsNull) { + current_source.RegisterHiddenScope (hidden_block_start, loc); + hidden_block_start = Location.Null; + } - if (arg == "default"){ ref_line = line; - ref_name = file_name; - hidden = false; - Location.Push (file_name, ref_name); + Location.Push (current_source); return true; - } else if (arg == "hidden"){ - hidden = true; + } + + if (length == line_hidden.Length) { + if (!IsTokenIdentifierEqual (line_hidden)) + return false; + + if (hidden_block_start.IsNull) + hidden_block_start = loc; + return true; } - - try { - int pos; - if ((pos = arg.IndexOf (' ')) != -1 && pos != 0){ - ref_line = System.Int32.Parse (arg.Substring (0, pos)); - pos++; - - char [] quotes = { '\"' }; - - string name = arg.Substring (pos).Trim (quotes); - ref_name = context.LookupFile (file_name, name); - file_name.AddIncludeFile (ref_name); - hidden = false; - Location.Push (file_name, ref_name); - } else { - ref_line = System.Int32.Parse (arg); - hidden = false; + if (length != 0 || c < '0' || c > '9') { + // + // Eat any remaining characters to continue parsing on next line + // + while (c != -1 && c != '\n') { + c = get_char (); } - } catch { + return false; } - + + int new_line = TokenizeNumber (c); + if (new_line < 1) { + // + // Eat any remaining characters to continue parsing on next line + // + while (c != -1 && c != '\n') { + c = get_char (); + } + + return new_line != 0; + } + + c = get_char (); + if (c == ' ') { + // skip over white space + do { + c = get_char (); + } while (c == ' ' || c == '\t'); + } else if (c == '"') { + c = 0; + } + + if (c != '\n' && c != '/' && c != '"') { + // + // Eat any remaining characters to continue parsing on next line + // + while (c != -1 && c != '\n') { + c = get_char (); + } + + Report.Error (1578, loc, "Filename, single-line comment or end-of-line expected"); + return true; + } + + string new_file_name = null; + if (c == '"') { + new_file_name = TokenizeFileName (ref c); + + // skip over white space + while (c == ' ' || c == '\t') { + c = get_char (); + } + } + + if (c == '\n') { + } else if (c == '/') { + ReadSingleLineComment (); + } else { + // + // Eat any remaining characters to continue parsing on next line + // + while (c != -1 && c != '\n') { + c = get_char (); + } + + Error_EndLineExpected (); + return true; + } + + if (new_file_name != null) { + current_source = context.LookupFile (source_file, new_file_name); + source_file.AddIncludeFile (current_source); + Location.Push (current_source); + } + + if (!hidden_block_start.IsNull) { + current_source.RegisterHiddenScope (hidden_block_start, loc); + hidden_block_start = Location.Null; + } + + ref_line = new_line; return true; } @@ -2036,12 +2109,12 @@ namespace Mono.CSharp if (context.Settings.IsConditionalSymbolDefined (ident)) return; - file_name.AddDefine (ident); + source_file.AddDefine (ident); } else { // // #undef ident // - file_name.AddUndefine (ident); + source_file.AddUndefine (ident); } } @@ -2092,26 +2165,13 @@ namespace Mono.CSharp if (c != '"') return false; - var string_builder = new StringBuilder (); - while (c != -1 && c != '\n') { - c = get_char (); - if (c == '"') { - c = get_char (); - break; - } - - string_builder.Append ((char) c); - } - - if (string_builder.Length == 0) { - Report.Warning (1709, 1, Location, "Filename specified for preprocessor directive is empty"); - } + string file_name = TokenizeFileName (ref c); // TODO: Any white-spaces count if (c != ' ') return false; - SourceFile file = context.LookupFile (file_name, string_builder.ToString ()); + SourceFile file = context.LookupFile (source_file, file_name); if (get_char () != '"' || get_char () != '{') return false; @@ -2178,7 +2238,7 @@ namespace Mono.CSharp } file.SetChecksum (guid_bytes, checksum_bytes.ToArray ()); - ref_name.AutoGenerated = true; + current_source.AutoGenerated = true; return true; } @@ -2192,27 +2252,53 @@ namespace Mono.CSharp return true; } - int TokenizePragmaNumber (ref int c) + int TokenizeNumber (int value) { number_pos = 0; - int number; + decimal_digits (value); + uint ui = (uint) (number_builder[0] - '0'); - if (c >= '0' && c <= '9') { - decimal_digits (c); - uint ui = (uint) (number_builder[0] - '0'); + try { + for (int i = 1; i < number_pos; i++) { + ui = checked ((ui * 10) + ((uint) (number_builder[i] - '0'))); + } - try { - for (int i = 1; i < number_pos; i++) { - ui = checked ((ui * 10) + ((uint) (number_builder[i] - '0'))); - } + return (int) ui; + } catch (OverflowException) { + Error_NumericConstantTooLong (); + return -1; + } + } - number = (int) ui; - } catch (OverflowException) { - Error_NumericConstantTooLong (); - number = -1; + string TokenizeFileName (ref int c) + { + var string_builder = new StringBuilder (); + while (c != -1 && c != '\n') { + c = get_char (); + if (c == '"') { + c = get_char (); + break; } + string_builder.Append ((char) c); + } + + if (string_builder.Length == 0) { + Report.Warning (1709, 1, Location, "Filename specified for preprocessor directive is empty"); + } + + return string_builder.ToString (); + } + + int TokenizePragmaNumber (ref int c) + { + number_pos = 0; + + int number; + + if (c >= '0' && c <= '9') { + number = TokenizeNumber (c); c = get_char (); @@ -2307,9 +2393,9 @@ namespace Mono.CSharp code = TokenizePragmaNumber (ref c); if (code > 0) { if (disable) { - Report.RegisterWarningRegion (loc).WarningDisable (loc, code, Report); + Report.RegisterWarningRegion (loc).WarningDisable (loc, code, context.Report); } else { - Report.RegisterWarningRegion (loc).WarningEnable (loc, code, Report); + Report.RegisterWarningRegion (loc).WarningEnable (loc, code, context); } } } while (code >= 0 && c != '\n' && c != -1); @@ -2345,7 +2431,7 @@ namespace Mono.CSharp if (s == "false") return false; - return file_name.IsConditionalDefined (context, s); + return source_file.IsConditionalDefined (s); } bool pp_primary (ref string s) @@ -2735,10 +2821,10 @@ namespace Mono.CSharp return true; case PreprocessorDirective.Line: - if (!PreProcessLine (arg)) - Report.Error ( - 1576, Location, - "The line number specified for #line directive is missing or invalid"); + Location loc = Location; + if (!PreProcessLine ()) + Report.Error (1576, loc, "The line number specified for #line directive is missing or invalid"); + return caller_is_taking; } diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs index 8948891abd..83be8c1ffa 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs @@ -1199,7 +1199,7 @@ namespace Mono.CSharp { return (state & StateFlags.CLSCompliant) != 0; } - public bool IsConditionallyExcluded (CompilerContext ctx, Location loc) + public bool IsConditionallyExcluded (IMemberContext ctx, Location loc) { if ((Kind & (MemberKind.Class | MemberKind.Method)) == 0) return false; @@ -1208,9 +1208,18 @@ namespace Mono.CSharp { if (conditions == null) return false; - foreach (var condition in conditions) { - if (loc.CompilationUnit.IsConditionalDefined (ctx, condition)) - return false; + var m = ctx.CurrentMemberDefinition; + CompilationSourceFile unit = null; + while (m != null && unit == null) { + unit = m as CompilationSourceFile; + m = m.Parent; + } + + if (unit != null) { + foreach (var condition in conditions) { + if (unit.IsConditionalDefined (condition)) + return false; + } } return true; diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs index cd3811ab27..96dcf77415 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs @@ -292,7 +292,7 @@ namespace Mono.CSharp { EndInvokeBuilder.Define (); } - public override void DefineConstants () + public override void PrepareEmit () { if (!Parameters.IsEmpty) { parameters.ResolveDefaultValues (this); @@ -525,7 +525,7 @@ namespace Mono.CSharp { Error_ConversionFailed (ec, delegate_method, ret_expr); } - if (delegate_method.IsConditionallyExcluded (ec.Module.Compiler, loc)) { + if (delegate_method.IsConditionallyExcluded (ec, loc)) { ec.Report.SymbolRelatedToPreviousError (delegate_method); MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator; if (m != null && m.IsPartialDefinition) { diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs index 40edc1c929..19340bf6c1 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs @@ -32,6 +32,7 @@ namespace Mono.CSharp readonly XmlDocument XmlDocumentation; readonly ModuleContainer module; + readonly ModuleContainer doc_module; // // The output for XML documentation. @@ -48,6 +49,9 @@ namespace Mono.CSharp public DocumentationBuilder (ModuleContainer module) { + doc_module = new ModuleContainer (module.Compiler); + doc_module.DocumentationBuilder = this; + this.module = module; XmlDocumentation = new XmlDocument (); XmlDocumentation.PreserveWhitespace = false; @@ -322,13 +326,10 @@ namespace Mono.CSharp var s = new MemoryStream (encoding.GetBytes (cref)); SeekableStreamReader seekable = new SeekableStreamReader (s, encoding); - var source_file = new CompilationSourceFile ("{documentation}", "", 1); - var doc_module = new ModuleContainer (module.Compiler); - doc_module.DocumentationBuilder = this; - source_file.NamespaceContainer = new NamespaceContainer (null, doc_module, null, source_file); + var source_file = new CompilationSourceFile (doc_module); + var report = new Report (doc_module.Compiler, new NullReportPrinter ()); - Report parse_report = new Report (new NullReportPrinter ()); - var parser = new CSharpParser (seekable, source_file, parse_report); + var parser = new CSharpParser (seekable, source_file, report); ParsedParameters = null; ParsedName = null; ParsedBuiltinType = null; @@ -336,7 +337,7 @@ namespace Mono.CSharp parser.Lexer.putback_char = Tokenizer.DocumentationXref; parser.Lexer.parsing_generic_declaration_doc = true; parser.parse (); - if (parse_report.Errors > 0) { + if (report.Errors > 0) { Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'", mc.GetSignatureForError (), cref); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs index 178d6b621c..109fbb2fe5 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs @@ -41,20 +41,22 @@ namespace Mono.CSharp } } - void tokenize_file (CompilationSourceFile file) + void tokenize_file (SourceFile sourceFile, ModuleContainer module) { Stream input; try { - input = File.OpenRead (file.Name); + input = File.OpenRead (sourceFile.Name); } catch { - Report.Error (2001, "Source file `" + file.Name + "' could not be found"); + Report.Error (2001, "Source file `" + sourceFile.Name + "' could not be found"); return; } using (input){ SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding); - Tokenizer lexer = new Tokenizer (reader, file, ctx); + var file = new CompilationSourceFile (module, sourceFile); + + Tokenizer lexer = new Tokenizer (reader, file); int token, tokens = 0, errors = 0; while ((token = lexer.token ()) != Token.EOF){ @@ -70,20 +72,21 @@ namespace Mono.CSharp void Parse (ModuleContainer module) { - Location.Initialize (module.Compiler.SourceFiles); - bool tokenize_only = module.Compiler.Settings.TokenizeOnly; var sources = module.Compiler.SourceFiles; + + Location.Initialize (sources); + for (int i = 0; i < sources.Count; ++i) { if (tokenize_only) { - tokenize_file (sources[i]); + tokenize_file (sources[i], module); } else { Parse (sources[i], module); } } } - public void Parse (CompilationSourceFile file, ModuleContainer module) + public void Parse (SourceFile file, ModuleContainer module) { Stream input; @@ -108,15 +111,14 @@ namespace Mono.CSharp Parse (reader, file, module); reader.Dispose (); input.Close (); - } - - public CSharpParser Parse (SeekableStreamReader reader, CompilationSourceFile file, ModuleContainer module) + } + + public CSharpParser Parse (SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module) { - var root = new NamespaceContainer (null, module, null, file); - file.NamespaceContainer = root; - module.AddTypeContainer (root); + var file = new CompilationSourceFile (module, sourceFile); + module.AddTypeContainer (file); + CSharpParser parser = new CSharpParser (reader, file); - parser.Lexer.TabSize = 1; parser.Lexer.sbag = new SpecialsBag (); parser.parse (); return parser; @@ -126,16 +128,15 @@ namespace Mono.CSharp { Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t"; - var r = new Report (new ConsoleReportPrinter ()); - CommandLineParser cmd = new CommandLineParser (r); + CommandLineParser cmd = new CommandLineParser (Console.Out); var settings = cmd.ParseArguments (args); - if (settings == null || r.Errors > 0) + if (settings == null) return 1; if (cmd.HasBeenStopped) return 0; - Driver d = new Driver (new CompilerContext (settings, r)); + Driver d = new Driver (new CompilerContext (settings, new ConsoleReportPrinter ())); if (d.Compile () && d.Report.Errors == 0) { if (d.Report.Warnings > 0) { @@ -367,13 +368,12 @@ namespace Mono.CSharp public static bool InvokeCompiler (string [] args, TextWriter error) { try { - var r = new Report (new StreamReportPrinter (error)); - CommandLineParser cmd = new CommandLineParser (r, error); + CommandLineParser cmd = new CommandLineParser (error); var setting = cmd.ParseArguments (args); - if (setting == null || r.Errors > 0) + if (setting == null) return false; - var d = new Driver (new CompilerContext (setting, r)); + var d = new Driver (new CompilerContext (setting, new StreamReportPrinter (error))); return d.Compile (); } finally { Reset (); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs index 73247f9d00..d9abd9d373 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs @@ -3287,7 +3287,7 @@ namespace Mono.CSharp { return null; } - if (best_candidate.IsConditionallyExcluded (ec.Module.Compiler, loc)) + if (best_candidate.IsConditionallyExcluded (ec, loc)) ec.Report.Error (765, loc, "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree"); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs index a93f5e14e3..c9b8645441 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs @@ -72,19 +72,17 @@ namespace Mono.CSharp readonly ReflectionImporter importer; readonly CompilationSourceFile source_file; - public Evaluator (CompilerSettings settings, Report report) + public Evaluator (CompilerContext ctx) { - ctx = new CompilerContext (settings, report); + this.ctx = ctx; module = new ModuleContainer (ctx); module.Evaluator = this; - source_file = new CompilationSourceFile ("{interactive}", "", 1); - source_file.NamespaceContainer = new NamespaceContainer (null, module, null, source_file); - module.AddTypeContainer (source_file.NamespaceContainer); + source_file = new CompilationSourceFile (module); + module.AddTypeContainer (source_file); startup_files = ctx.SourceFiles.Count; - ctx.SourceFiles.Add (source_file); // FIXME: Importer needs this assembly for internalsvisibleto module.SetDeclaringAssembly (new AssemblyDefinitionDynamic (module, "evaluator")); @@ -118,7 +116,7 @@ namespace Mono.CSharp Location.Initialize (ctx.SourceFiles); for (int i = 0; i < startup_files; ++i) { - var sf = ctx.Settings.SourceFiles [i]; + var sf = ctx.SourceFiles [i]; d.Parse (sf, module); } } @@ -444,7 +442,7 @@ namespace Mono.CSharp // InputKind ToplevelOrStatement (SeekableStreamReader seekable) { - Tokenizer tokenizer = new Tokenizer (seekable, source_file, ctx); + Tokenizer tokenizer = new Tokenizer (seekable, source_file); int t = tokenizer.token (); switch (t){ @@ -572,7 +570,7 @@ namespace Mono.CSharp } seekable.Position = 0; - source_file.NamespaceContainer.DeclarationFound = false; + source_file.DeclarationFound = false; CSharpParser parser = new CSharpParser (seekable, source_file); if (kind == InputKind.StatementOrExpression){ @@ -654,7 +652,7 @@ namespace Mono.CSharp } module.CreateContainer (); - ((NamespaceContainer) module.Containers[0]).EnableUsingClausesRedefinition (); + source_file.EnableUsingClausesRedefinition (); module.Define (); if (Report.Errors != 0){ @@ -758,7 +756,7 @@ namespace Mono.CSharp //foreach (object x in ns.using_alias_list) // sb.AppendFormat ("using {0};\n", x); - foreach (var ue in source_file.NamespaceContainer.Usings) { + foreach (var ue in source_file.Usings) { sb.AppendFormat ("using {0};", ue.ToString ()); sb.Append (Environment.NewLine); } @@ -770,7 +768,7 @@ namespace Mono.CSharp { var res = new List (); - foreach (var ue in source_file.NamespaceContainer.Usings) { + foreach (var ue in source_file.Usings) { if (ue.Alias != null || ue.ResolvedExpression == null) continue; diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs index 850fee1a85..40267354de 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs @@ -5401,7 +5401,8 @@ namespace Mono.CSharp // Any value type has to be pass as by-ref to get back the same // instance on which the member was called // - var mod = TypeSpec.IsValueType (ma.LeftExpression.Type) ? Argument.AType.Ref : Argument.AType.None; + var mod = ma.LeftExpression is IMemoryLocation && TypeSpec.IsValueType (ma.LeftExpression.Type) ? + Argument.AType.Ref : Argument.AType.None; args.Insert (0, new Argument (ma.LeftExpression.Resolve (ec), mod)); } } else { // is SimpleName diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs index 25a3161b7a..f8d349f789 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs @@ -2858,16 +2858,17 @@ namespace Mono.CSharp { if (!u.IsArray) return 0; - // TODO MemberCache: GetMetaInfo () - if (u.GetMetaInfo ().GetArrayRank () != v.GetMetaInfo ().GetArrayRank ()) + var ac_u = (ArrayContainer) u; + var ac_v = (ArrayContainer) v; + if (ac_u.Rank != ac_v.Rank) return 0; - return ExactInference (TypeManager.GetElementType (u), TypeManager.GetElementType (v)); + return ExactInference (ac_u.Element, ac_v.Element); } // If V is constructed type and U is constructed type if (TypeManager.IsGenericType (v)) { - if (!TypeManager.IsGenericType (u)) + if (!TypeManager.IsGenericType (u) || v.MemberDefinition != u.MemberDefinition) return 0; TypeSpec [] ga_u = TypeManager.GetTypeArguments (u); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs index 53bb2c7b76..71b272d407 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs @@ -17,16 +17,42 @@ using Mono.CompilerServices.SymbolWriter; using System.Diagnostics; using System.Linq; -namespace Mono.CSharp { - /// - /// This is one single source file. - /// - /// - /// This is intentionally a class and not a struct since we need - /// to pass this by reference. - /// - public class SourceFile : ISourceFile, IEquatable +namespace Mono.CSharp +{ + // + // This is one single source file. + // + public class SourceFile : IEquatable { + // + // Used by #line directive to track hidden sequence point + // regions + // + struct LocationRegion : IComparable + { + public readonly Location Start; + public readonly Location End; + + public LocationRegion (Location start, Location end) + { + this.Start = start; + this.End = end; + } + + public int CompareTo (LocationRegion other) + { + if (Start.Row == other.Start.Row) + return Start.Column.CompareTo (other.Start.Column); + + return Start.Row.CompareTo (other.Start.Row); + } + + public override string ToString () + { + return Start.ToString () + " - " + End.ToString (); + } + } + public readonly string Name; public readonly string FullPathName; public readonly int Index; @@ -34,6 +60,7 @@ namespace Mono.CSharp { SourceFileEntry file; byte[] guid, checksum; + List hidden_lines; public SourceFile (string name, string path, int index) { @@ -43,11 +70,9 @@ namespace Mono.CSharp { } public SourceFileEntry SourceFileEntry { - get { return file; } - } - - SourceFileEntry ISourceFile.Entry { - get { return file; } + get { + return file; + } } public void SetChecksum (byte[] guid, byte[] checksum) @@ -56,8 +81,11 @@ namespace Mono.CSharp { this.checksum = checksum; } - public virtual void DefineSymbolInfo (MonoSymbolWriter symwriter) + public SourceFileEntry CreateSymbolInfo (MonoSymbolWriter symwriter) { + if (hidden_lines != null) + hidden_lines.Sort (); + if (guid != null) file = symwriter.DefineDocument (FullPathName, guid, checksum); else { @@ -65,6 +93,8 @@ namespace Mono.CSharp { if (AutoGenerated) file.SetAutoGenerated (); } + + return file; } public bool Equals (SourceFile other) @@ -72,97 +102,33 @@ namespace Mono.CSharp { return FullPathName == other.FullPathName; } - public override string ToString () - { - return String.Format ("SourceFile ({0}:{1}:{2}:{3})", - Name, FullPathName, Index, SourceFileEntry); - } - } - - public class CompilationSourceFile : SourceFile, ICompileUnit - { - CompileUnitEntry comp_unit; - Dictionary include_files; - Dictionary conditionals; - NamespaceContainer ns_container; - - public CompilationSourceFile (string name, string fullPathName, int index) - : base (name, fullPathName, index) + public bool IsHiddenLocation (Location loc) { - } + if (hidden_lines == null) + return false; - CompileUnitEntry ICompileUnit.Entry { - get { return comp_unit; } - } - - public CompileUnitEntry CompileUnitEntry { - get { return comp_unit; } - } - - public NamespaceContainer NamespaceContainer { - get { - return ns_container; + int index = hidden_lines.BinarySearch (new LocationRegion (loc, loc)); + index = ~index; + if (index > 0) { + var found = hidden_lines[index - 1]; + if (loc.Row < found.End.Row) + return true; } - set { - ns_container = value; - } - } - - public void AddIncludeFile (SourceFile file) - { - if (file == this) - return; - - if (include_files == null) - include_files = new Dictionary (); - - if (!include_files.ContainsKey (file.FullPathName)) - include_files.Add (file.FullPathName, file); - } - - public void AddDefine (string value) - { - if (conditionals == null) - conditionals = new Dictionary (2); - conditionals [value] = true; + return false; } - public void AddUndefine (string value) + public void RegisterHiddenScope (Location start, Location end) { - if (conditionals == null) - conditionals = new Dictionary (2); + if (hidden_lines == null) + hidden_lines = new List (); - conditionals [value] = false; + hidden_lines.Add (new LocationRegion (start, end)); } - public override void DefineSymbolInfo (MonoSymbolWriter symwriter) - { - base.DefineSymbolInfo (symwriter); - - comp_unit = symwriter.DefineCompilationUnit (SourceFileEntry); - - if (include_files != null) { - foreach (SourceFile include in include_files.Values) { - include.DefineSymbolInfo (symwriter); - comp_unit.AddFile (include.SourceFileEntry); - } - } - } - - public bool IsConditionalDefined (CompilerContext ctx, string value) + public override string ToString () { - if (conditionals != null) { - bool res; - if (conditionals.TryGetValue (value, out res)) - return res; - - // When conditional was undefined - if (conditionals.ContainsKey (value)) - return false; - } - - return ctx.Settings.IsConditionalSymbolDefined (value); + return String.Format ("SourceFile ({0}:{1}:{2})", Name, FullPathName, Index); } } @@ -186,37 +152,33 @@ namespace Mono.CSharp { { struct Checkpoint { public readonly int LineOffset; - public readonly int CompilationUnit; public readonly int File; - public Checkpoint (int compile_unit, int file, int line) + public Checkpoint (int file, int line) { File = file; - CompilationUnit = compile_unit; LineOffset = line - (int) (line % (1 << line_delta_bits)); } } #if FULL_AST - long token; + readonly long token; const int column_bits = 24; const int line_delta_bits = 24; #else - int token; + readonly int token; const int column_bits = 8; const int line_delta_bits = 8; #endif const int checkpoint_bits = 16; - // -2 because the last one is used for hidden - const int max_column = (1 << column_bits) - 2; const int column_mask = (1 << column_bits) - 1; + const int max_column = column_mask; static List source_list; static int current_source; - static int current_compile_unit; static Checkpoint [] checkpoints; static int checkpoint_index; @@ -232,15 +194,12 @@ namespace Mono.CSharp { { source_list = new List (); current_source = 0; - current_compile_unit = 0; checkpoint_index = 0; } - public static SourceFile AddFile (string name, string fullName) + public static void AddFile (SourceFile file) { - var source = new SourceFile (name, fullName, source_list.Count + 1); - source_list.Add (source); - return source; + source_list.Add (file); } // @@ -249,7 +208,7 @@ namespace Mono.CSharp { // source file. We reserve some extra space for files we encounter via #line // directives while parsing. // - static public void Initialize (List files) + static public void Initialize (List files) { #if NET_4_0 source_list.AddRange (files); @@ -257,15 +216,14 @@ namespace Mono.CSharp { source_list.AddRange (files.ToArray ()); #endif - checkpoints = new Checkpoint [source_list.Count * 2]; + checkpoints = new Checkpoint [System.Math.Max (1, source_list.Count * 2)]; if (checkpoints.Length > 0) - checkpoints [0] = new Checkpoint (0, 0, 0); + checkpoints [0] = new Checkpoint (0, 0); } - static public void Push (CompilationSourceFile compile_unit, SourceFile file) + static public void Push (SourceFile file) { current_source = file != null ? file.Index : -1; - current_compile_unit = compile_unit != null ? compile_unit.Index : -1; // File is always pushed before being changed. } @@ -276,8 +234,6 @@ namespace Mono.CSharp { else { if (column > max_column) column = max_column; - else if (column < 0) - column = max_column + 1; long target = -1; long delta = 0; @@ -296,7 +252,7 @@ namespace Mono.CSharp { } } if (target == -1) { - AddCheckpoint (current_compile_unit, current_source, row); + AddCheckpoint (current_source, row); target = checkpoint_index; delta = row % (1 << line_delta_bits); } @@ -317,12 +273,12 @@ namespace Mono.CSharp { return new Location (loc.Row, loc.Column - columns); } - static void AddCheckpoint (int compile_unit, int file, int row) + static void AddCheckpoint (int file, int row) { if (checkpoints.Length == ++checkpoint_index) { Array.Resize (ref checkpoints, checkpoint_index * 2); } - checkpoints [checkpoint_index] = new Checkpoint (compile_unit, file, row); + checkpoints [checkpoint_index] = new Checkpoint (file, row); } string FormatLocation (string fileName) @@ -354,10 +310,9 @@ namespace Mono.CSharp { public string Name { get { int index = File; - if (token == 0 || index == 0) - return "Internal"; - if (source_list == null || index - 1 >= source_list.Count) - return "unknown_file"; + + if (token == 0 || index <= 0) + return null; SourceFile file = source_list [index - 1]; return file.Name; @@ -367,8 +322,8 @@ namespace Mono.CSharp { public string NameFullPath { get { int index = File; - if (token == 0 || index == 0) - return "Internal"; + if (token == 0 || index <= 0) + return null; return source_list[index - 1].FullPathName; } @@ -397,23 +352,7 @@ namespace Mono.CSharp { get { if (token == 0) return 1; - int col = (int) (token & column_mask); - return col > max_column ? 1 : col; - } - } - - public bool Hidden { - get { - return (int) (token & column_mask) == max_column + 1; - } - } - - public int CompilationUnitIndex { - get { - if (token == 0) - return 0; -if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("Should not happen. Token is {0:X04}, checkpoints are {1}, index is {2}", token, checkpoints.Length, CheckpointIndex)); - return checkpoints [CheckpointIndex].CompilationUnit; + return (int) (token & column_mask); } } @@ -443,16 +382,7 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" int index = File; if (index == 0) return null; - return (SourceFile) source_list [index - 1]; - } - } - - public CompilationSourceFile CompilationUnit { - get { - int index = CompilationUnitIndex; - if (index == 0) - return null; - return (CompilationSourceFile) source_list [index - 1]; + return source_list [index - 1]; } } diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs index cc42dc8c24..ffa46ec3c8 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs @@ -774,9 +774,6 @@ namespace Mono.CSharp { return conditions; } - public virtual void EmitExtraSymbolInfo (SourceMethod source) - { } - #endregion } @@ -784,17 +781,11 @@ namespace Mono.CSharp { public class SourceMethod : IMethodDef { MethodBase method; - SourceMethodBuilder builder; - protected SourceMethod (TypeDefinition parent, MethodBase method, ICompileUnit file) + SourceMethod (MethodBase method, ICompileUnit file) { this.method = method; - - TypeContainer ns = parent.Parent; - while (ns != null && !(ns is NamespaceContainer)) - ns = ns.Parent; - - builder = SymbolWriter.OpenMethod (file, ns == null ? -1 : ((NamespaceContainer) ns).SymbolFileID, this); + SymbolWriter.OpenMethod (file, this); } public string Name { @@ -822,28 +813,16 @@ namespace Mono.CSharp { SymbolWriter.CloseMethod (); } - public void SetRealMethodName (string name) - { - if (builder != null) - builder.SetRealMethodName (name); - } - - public static SourceMethod Create (TypeDefinition parent, MethodBase method, Block block) + public static SourceMethod Create (TypeDefinition parent, MethodBase method) { if (!SymbolWriter.HasSymbolWriter) return null; - if (block == null) - return null; - Location start_loc = block.StartLocation; - if (start_loc.IsNull) + var source_file = parent.GetCompilationSourceFile (); + if (source_file == null) return null; - ICompileUnit compile_unit = start_loc.CompilationUnit; - if (compile_unit == null) - return null; - - return new SourceMethod (parent, method, compile_unit); + return new SourceMethod (method, source_file.SymbolUnitEntry); } } @@ -1484,7 +1463,7 @@ namespace Mono.CSharp { ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself", caller_builder.GetSignatureForError ()); } - + return this; } @@ -1494,8 +1473,6 @@ namespace Mono.CSharp { if (base_ctor == null) return; - ec.Mark (loc); - var call = new CallEmitter (); call.InstanceExpression = new CompilerGeneratedThis (type, loc); call.EmitPredefined (ec, base_ctor, argument_list); @@ -1700,50 +1677,56 @@ namespace Mono.CSharp { base.Emit (); parameters.ApplyAttributes (this, ConstructorBuilder); - // - // If we use a "this (...)" constructor initializer, then - // do not emit field initializers, they are initialized in the other constructor - // - bool emit_field_initializers = ((ModFlags & Modifiers.STATIC) != 0) || - !(Initializer is ConstructorThisInitializer); BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void); bc.Set (ResolveContext.Options.ConstructorScope); - if (emit_field_initializers) + // + // If we use a "this (...)" constructor initializer, then + // do not emit field initializers, they are initialized in the other constructor + // + if (!(Initializer is ConstructorThisInitializer)) Parent.PartialContainer.ResolveFieldInitializers (bc); if (block != null) { - // If this is a non-static `struct' constructor and doesn't have any - // initializer, it must initialize all of the struct's fields. - if ((Parent.PartialContainer.Kind == MemberKind.Struct) && - ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null)) - block.AddThisVariable (bc); - - if ((ModFlags & Modifiers.STATIC) == 0){ - if (Parent.PartialContainer.Kind == MemberKind.Class && Initializer == null) - Initializer = new GeneratedBaseInitializer (Location); + if (!IsStatic) { + if (Initializer == null) { + if (Parent.PartialContainer.Kind == MemberKind.Struct) { + // + // If this is a non-static `struct' constructor and doesn't have any + // initializer, it must initialize all of the struct's fields. + // + block.AddThisVariable (bc); + } else if (Parent.PartialContainer.Kind == MemberKind.Class) { + Initializer = new GeneratedBaseInitializer (Location); + } + } if (Initializer != null) { - block.AddScopeStatement (new StatementExpression (Initializer)); + // + // Use location of the constructor to emit sequence point of initializers + // at beginning of constructor name + // + // TODO: Need to extend mdb to support line regions to allow set a breakpoint at + // initializer + // + block.AddScopeStatement (new StatementExpression (Initializer, Location)); } } - } - SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder, block); - - if (block != null) { if (block.Resolve (null, bc, this)) { EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType); ec.With (EmitContext.Options.ConstructorScope, true); + SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder); + block.Emit (ec); + + if (source != null) + source.CloseMethod (); } } - if (source != null) - source.CloseMethod (); - if (declarative_security != null) { foreach (var de in declarative_security) { #if STATIC @@ -1822,9 +1805,6 @@ namespace Mono.CSharp { return false; } - void IMethodData.EmitExtraSymbolInfo (SourceMethod source) - { } - #endregion } @@ -1845,7 +1825,6 @@ namespace Mono.CSharp { ToplevelBlock Block { get; set; } EmitContext CreateEmitContext (ILGenerator ig); - void EmitExtraSymbolInfo (SourceMethod source); } // @@ -2120,21 +2099,19 @@ namespace Mono.CSharp { method.ParameterInfo.ApplyAttributes (mc, MethodBuilder); - SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block); - ToplevelBlock block = method.Block; if (block != null) { BlockContext bc = new BlockContext (mc, block, method.ReturnType); if (block.Resolve (null, bc, method)) { EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator ()); + SourceMethod source = SourceMethod.Create (parent, MethodBuilder); + block.Emit (ec); - } - } - if (source != null) { - method.EmitExtraSymbolInfo (source); - source.CloseMethod (); + if (source != null) + source.CloseMethod (); + } } } } @@ -2411,9 +2388,6 @@ namespace Mono.CSharp { public override string DocCommentHeader { get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); } } - - void IMethodData.EmitExtraSymbolInfo (SourceMethod source) - { } } public class Operator : MethodOrOperator { diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs index 5369af6dbb..85d4ff42db 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs @@ -423,7 +423,7 @@ namespace Mono.CSharp } foreach (var tc in containers) { - tc.DefineConstants (); + tc.PrepareEmit (); } base.EmitContainer (); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs index f8d3f0b42f..572d30b701 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Mono.CompilerServices.SymbolWriter; namespace Mono.CSharp { @@ -597,23 +598,124 @@ namespace Mono.CSharp { } } + public class CompilationSourceFile : NamespaceContainer + { + readonly SourceFile file; + CompileUnitEntry comp_unit; + Dictionary include_files; + Dictionary conditionals; + + public CompilationSourceFile (ModuleContainer parent, SourceFile sourceFile) + : this (parent) + { + this.file = sourceFile; + } + + public CompilationSourceFile (ModuleContainer parent) + : base (parent) + { + } + + public CompileUnitEntry SymbolUnitEntry { + get { + return comp_unit; + } + } + + public string FileName { + get { + return file.Name; + } + } + + public SourceFile SourceFile { + get { + return file; + } + } + + public void AddIncludeFile (SourceFile file) + { + if (file == this.file) + return; + + if (include_files == null) + include_files = new Dictionary (); + + if (!include_files.ContainsKey (file.FullPathName)) + include_files.Add (file.FullPathName, file); + } + + public void AddDefine (string value) + { + if (conditionals == null) + conditionals = new Dictionary (2); + + conditionals[value] = true; + } + + public void AddUndefine (string value) + { + if (conditionals == null) + conditionals = new Dictionary (2); + + conditionals[value] = false; + } + + public override void PrepareEmit () + { + // Compiler.SymbolWriter + if (SymbolWriter.symwriter != null) { + CreateUnitSymbolInfo (SymbolWriter.symwriter); + } + + base.PrepareEmit (); + } + + // + // Creates symbol file index in debug symbol file + // + void CreateUnitSymbolInfo (MonoSymbolWriter symwriter) + { + var si = file.CreateSymbolInfo (symwriter); + comp_unit = symwriter.DefineCompilationUnit (si); + + if (include_files != null) { + foreach (SourceFile include in include_files.Values) { + si = include.CreateSymbolInfo (symwriter); + comp_unit.AddFile (si); + } + } + } + + public bool IsConditionalDefined (string value) + { + if (conditionals != null) { + bool res; + if (conditionals.TryGetValue (value, out res)) + return res; + + // When conditional was undefined + if (conditionals.ContainsKey (value)) + return false; + } + + return Compiler.Settings.IsConditionalSymbolDefined (value); + } + } + + // // Namespace block as created by the parser // public class NamespaceContainer : TypeContainer, IMemberContext { static readonly Namespace[] empty_namespaces = new Namespace[0]; - static readonly string[] empty_using_list = new string[0]; - - Namespace ns; - readonly ModuleContainer module; - readonly CompilationSourceFile file; + readonly Namespace ns; public new readonly NamespaceContainer Parent; - int symfile_id; - List clauses; // Used by parsed to check for parser errors @@ -622,25 +724,24 @@ namespace Mono.CSharp { Namespace[] namespace_using_table; Dictionary aliases; public readonly MemberName RealMemberName; - - public NamespaceContainer (MemberName name, ModuleContainer module, NamespaceContainer parent, CompilationSourceFile sourceFile) - : base ((TypeContainer) parent ?? module, name, null, MemberKind.Namespace) + + public NamespaceContainer (MemberName name, NamespaceContainer parent) + : base (parent, name, null, MemberKind.Namespace) { this.RealMemberName = name; - this.module = module; this.Parent = parent; - this.file = sourceFile; - - if (parent != null) - ns = parent.NS.AddNamespace (name); - else if (name != null) - ns = module.GlobalRootNamespace.AddNamespace (name); - else - ns = module.GlobalRootNamespace; + this.ns = parent.NS.AddNamespace (name); containers = new List (); } + protected NamespaceContainer (ModuleContainer parent) + : base (parent, null, null, MemberKind.Namespace) + { + ns = parent.GlobalRootNamespace; + containers = new List (2); + } + #region Properties public override AttributeTargets AttributeTargets { @@ -661,18 +762,6 @@ namespace Mono.CSharp { } } - public override ModuleContainer Module { - get { - return module; - } - } - - public CompilationSourceFile SourceFile { - get { - return file; - } - } - public List Usings { get { return clauses; @@ -765,7 +854,7 @@ namespace Mono.CSharp { var tdef = tc.PartialContainer; if (tdef != null) - ns.AddType (module, tdef.Definition); + ns.AddType (Module, tdef.Definition); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) @@ -1021,7 +1110,7 @@ namespace Mono.CSharp { } // It can be top level accessibility only - var better = Namespace.IsImportedTypeOverride (module, texpr_match.Type, texpr_fne.Type); + var better = Namespace.IsImportedTypeOverride (Module, texpr_match.Type, texpr_fne.Type); if (better == null) { if (mode == LookupMode.Normal) { Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type); @@ -1040,28 +1129,6 @@ namespace Mono.CSharp { return match; } - public int SymbolFileID { - get { - if (symfile_id == 0 && file.SourceFileEntry != null) { - int parent_id = Parent == null ? 0 : Parent.SymbolFileID; - - string [] using_list = empty_using_list; - if (clauses != null) { - // TODO: Why is it needed, what to do with aliases - var ul = new List (); - foreach (var c in clauses) { - ul.Add (c.ResolvedExpression.GetSignatureForError ()); - } - - using_list = ul.ToArray (); - } - - symfile_id = SymbolWriter.DefineNamespace (ns.Name, file.CompileUnitEntry, using_list, parent_id); - } - return symfile_id; - } - } - static void MsgtryRef (string s) { Console.WriteLine (" Try using -r:" + s); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs index fc6a69f511..64fc1bf01d 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs @@ -21,27 +21,15 @@ namespace Mono.CSharp { // public class Report { - /// - /// Whether warnings should be considered errors - /// - public bool WarningsAreErrors; - List warnings_as_error; - List warnings_only; - public const int RuntimeErrorId = 10000; - // - // Keeps track of the warnings that we are ignoring - // - HashSet warning_ignore_table; - Dictionary warning_regions_table; - int warning_level; - ReportPrinter printer; int reporting_disabled; + + readonly CompilerSettings settings; /// /// List of symbols related to reported error/warning. You have to fill it before error/warning is reported. @@ -72,13 +60,15 @@ namespace Mono.CSharp { static HashSet AllWarningsHashSet; - public Report (ReportPrinter printer) + public Report (CompilerContext context, ReportPrinter printer) { + if (context == null) + throw new ArgumentNullException ("settings"); if (printer == null) throw new ArgumentNullException ("printer"); + this.settings = context.Settings; this.printer = printer; - warning_level = 4; } public void DisableReporting () @@ -125,44 +115,6 @@ namespace Mono.CSharp { "Feature `{0}' is not supported in Mono mcs1 compiler. Consider using the `gmcs' compiler instead", feature); } - - bool IsWarningEnabled (int code, int level, Location loc) - { - if (WarningLevel < level) - return false; - - if (IsWarningDisabledGlobally (code)) - return false; - - if (warning_regions_table == null || loc.IsNull) - return true; - - WarningRegions regions; - if (!warning_regions_table.TryGetValue (loc.File, out regions)) - return true; - - return regions.IsWarningEnabled (code, loc.Row); - } - - public bool IsWarningDisabledGlobally (int code) - { - return warning_ignore_table != null && warning_ignore_table.Contains (code); - } - - bool IsWarningAsError (int code) - { - bool is_error = WarningsAreErrors; - - // Check specific list - if (warnings_as_error != null) - is_error |= warnings_as_error.Contains (code); - - // Ignore excluded warnings - if (warnings_only != null && warnings_only.Contains (code)) - is_error = false; - - return is_error; - } public void RuntimeMissingSupport (Location loc, string feature) { @@ -217,44 +169,6 @@ namespace Mono.CSharp { extra_information.Add (msg); } - public void AddWarningAsError (string warningId) - { - int id; - try { - id = int.Parse (warningId); - } catch { - CheckWarningCode (warningId, Location.Null); - return; - } - - if (!CheckWarningCode (id, Location.Null)) - return; - - if (warnings_as_error == null) - warnings_as_error = new List (); - - warnings_as_error.Add (id); - } - - public void RemoveWarningAsError (string warningId) - { - int id; - try { - id = int.Parse (warningId); - } catch { - CheckWarningCode (warningId, Location.Null); - return; - } - - if (!CheckWarningCode (id, Location.Null)) - return; - - if (warnings_only == null) - warnings_only = new List (); - - warnings_only.Add (id); - } - public bool CheckWarningCode (string code, Location loc) { Warning (1691, 1, loc, "`{0}' is not a valid warning number", code); @@ -300,11 +214,17 @@ namespace Mono.CSharp { if (reporting_disabled > 0) return; - if (!IsWarningEnabled (code, level, loc)) + if (!settings.IsWarningEnabled (code, level)) return; + if (warning_regions_table != null && !loc.IsNull) { + WarningRegions regions; + if (warning_regions_table.TryGetValue (loc.File, out regions) && !regions.IsWarningEnabled (code, loc.Row)) + return; + } + AbstractMessage msg; - if (IsWarningAsError (code)) { + if (settings.IsWarningAsError (code)) { message = "Warning as Error: " + message; msg = new ErrorMessage (code, loc, message, extra_information); } else { @@ -420,14 +340,6 @@ namespace Mono.CSharp { get { return printer; } } - public void SetIgnoreWarning (int code) - { - if (warning_ignore_table == null) - warning_ignore_table = new HashSet (); - - warning_ignore_table.Add (code); - } - public ReportPrinter SetPrinter (ReportPrinter printer) { ReportPrinter old = this.printer; @@ -435,15 +347,6 @@ namespace Mono.CSharp { return old; } - public int WarningLevel { - get { - return warning_level; - } - set { - warning_level = value; - } - } - [Conditional ("MCS_DEBUG")] static public void Debug (string message, params object[] args) { @@ -1200,13 +1103,13 @@ namespace Mono.CSharp { regions.Add (new EnableAll (line)); } - public void WarningEnable (Location location, int code, Report Report) + public void WarningEnable (Location location, int code, CompilerContext context) { - if (!Report.CheckWarningCode (code, location)) + if (!context.Report.CheckWarningCode (code, location)) return; - if (Report.IsWarningDisabledGlobally (code)) - Report.Warning (1635, 1, location, "Cannot restore warning `CS{0:0000}' because it was disabled globally", code); + if (context.Settings.IsWarningDisabledGlobally (code)) + context.Report.Warning (1635, 1, location, "Cannot restore warning `CS{0:0000}' because it was disabled globally", code); regions.Add (new Enable (location.Row, code)); } diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs index b49d2a3e47..3b44ac067d 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/settings.cs @@ -66,6 +66,11 @@ namespace Mono.CSharp { public string StrongNameKeyContainer; public bool StrongNameDelaySign; + public int TabSize; + + public bool WarningsAreErrors; + public int WarningLevel; + // // Assemblies references to be loaded // @@ -146,7 +151,11 @@ namespace Mono.CSharp { readonly List conditional_symbols; - readonly List source_files; + readonly List source_files; + + List warnings_as_error; + List warnings_only; + HashSet warning_ignore_table; public CompilerSettings () { @@ -156,10 +165,15 @@ namespace Mono.CSharp { Platform = Platform.AnyCPU; Version = LanguageVersion.Default; VerifyClsCompliance = true; - Optimize = true; Encoding = Encoding.UTF8; LoadDefaultReferences = true; StdLibRuntimeVersion = RuntimeVersion.v4; + WarningLevel = 4; + + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + TabSize = 4; + else + TabSize = 8; AssemblyReferences = new List (); AssemblyReferencesAliases = new List> (); @@ -172,12 +186,12 @@ namespace Mono.CSharp { // conditional_symbols.Add ("__MonoCS__"); - source_files = new List (); + source_files = new List (); } #region Properties - public CompilationSourceFile FirstSourceFile { + public SourceFile FirstSourceFile { get { return source_files.Count > 0 ? source_files [0] : null; } @@ -195,7 +209,7 @@ namespace Mono.CSharp { } } - public List SourceFiles { + public List SourceFiles { get { return source_files; } @@ -209,10 +223,62 @@ namespace Mono.CSharp { conditional_symbols.Add (symbol); } + public void AddWarningAsError (int id) + { + if (warnings_as_error == null) + warnings_as_error = new List (); + + warnings_as_error.Add (id); + } + + public void AddWarningOnly (int id) + { + if (warnings_only == null) + warnings_only = new List (); + + warnings_only.Add (id); + } + public bool IsConditionalSymbolDefined (string symbol) { return conditional_symbols.Contains (symbol); } + + public bool IsWarningAsError (int code) + { + bool is_error = WarningsAreErrors; + + // Check specific list + if (warnings_as_error != null) + is_error |= warnings_as_error.Contains (code); + + // Ignore excluded warnings + if (warnings_only != null && warnings_only.Contains (code)) + is_error = false; + + return is_error; + } + + public bool IsWarningEnabled (int code, int level) + { + if (WarningLevel < level) + return false; + + return !IsWarningDisabledGlobally (code); + } + + public bool IsWarningDisabledGlobally (int code) + { + return warning_ignore_table != null && warning_ignore_table.Contains (code); + } + + public void SetIgnoreWarning (int code) + { + if (warning_ignore_table == null) + warning_ignore_table = new HashSet (); + + warning_ignore_table.Add (code); + } } public class CommandLineParser @@ -228,22 +294,27 @@ namespace Mono.CSharp { static readonly char[] argument_value_separator = new char[] { ';', ',' }; static readonly char[] numeric_value_separator = new char[] { ';', ',', ' ' }; - readonly Report report; readonly TextWriter output; + readonly Report report; bool stop_argument; Dictionary source_file_index; public event Func UnknownOptionHandler; - public CommandLineParser (Report report) - : this (report, Console.Out) + CompilerSettings parser_settings; + + public CommandLineParser (TextWriter errorOutput) + : this (errorOutput, Console.Out) { } - public CommandLineParser (Report report, TextWriter messagesOutput) + public CommandLineParser (TextWriter errorOutput, TextWriter messagesOutput) { - this.report = report; + var rp = new StreamReportPrinter (errorOutput); + + parser_settings = new CompilerSettings (); + report = new Report (new CompilerContext (parser_settings, rp), rp); this.output = messagesOutput; } @@ -364,10 +435,13 @@ namespace Mono.CSharp { ProcessSourceFiles (arg, false, settings.SourceFiles); } + if (report.Errors > 0) + return null; + return settings; } - void ProcessSourceFiles (string spec, bool recurse, List sourceFiles) + void ProcessSourceFiles (string spec, bool recurse, List sourceFiles) { string path, pattern; @@ -461,7 +535,7 @@ namespace Mono.CSharp { settings.Resources.Add (res); } - void AddSourceFile (string fileName, List sourceFiles) + void AddSourceFile (string fileName, List sourceFiles) { string path = Path.GetFullPath (fileName); @@ -476,11 +550,43 @@ namespace Mono.CSharp { return; } - var unit = new CompilationSourceFile (fileName, path, sourceFiles.Count + 1); + var unit = new SourceFile (fileName, path, sourceFiles.Count + 1); sourceFiles.Add (unit); source_file_index.Add (path, unit.Index); } + void AddWarningAsError (string warningId, CompilerSettings settings) + { + int id; + try { + id = int.Parse (warningId); + } catch { + report.CheckWarningCode (warningId, Location.Null); + return; + } + + if (!report.CheckWarningCode (id, Location.Null)) + return; + + settings.AddWarningAsError (id); + } + + void RemoveWarningAsError (string warningId, CompilerSettings settings) + { + int id; + try { + id = int.Parse (warningId); + } catch { + report.CheckWarningCode (warningId, Location.Null); + return; + } + + if (!report.CheckWarningCode (id, Location.Null)) + return; + + settings.AddWarningOnly (id); + } + void Error_RequiresArgument (string option) { report.Error (2006, "Missing argument for `{0}' option", option); @@ -831,10 +937,18 @@ namespace Mono.CSharp { return ParseResult.Success; case "/debug": - if (value == "full" || value == "") + if (value == "full" || value == "pdbonly" || idx < 0) { settings.GenerateDebugInfo = true; + return ParseResult.Success; + } - return ParseResult.Success; + if (value.Length > 0) { + report.Error (1902, "Invalid debug option `{0}'. Valid options are `full' or `pdbonly'", value); + } else { + Error_RequiresArgument (option); + } + + return ParseResult.Error; case "/debug+": settings.GenerateDebugInfo = true; @@ -870,19 +984,20 @@ namespace Mono.CSharp { case "/warnaserror": case "/warnaserror+": if (value.Length == 0) { - report.WarningsAreErrors = true; + settings.WarningsAreErrors = true; + parser_settings.WarningsAreErrors = true; } else { foreach (string wid in value.Split (numeric_value_separator)) - report.AddWarningAsError (wid); + AddWarningAsError (wid, settings); } return ParseResult.Success; case "/warnaserror-": if (value.Length == 0) { - report.WarningsAreErrors = false; + settings.WarningsAreErrors = false; } else { foreach (string wid in value.Split (numeric_value_separator)) - report.RemoveWarningAsError (wid); + RemoveWarningAsError (wid, settings); } return ParseResult.Success; @@ -892,7 +1007,7 @@ namespace Mono.CSharp { return ParseResult.Error; } - SetWarningLevel (value); + SetWarningLevel (value, settings); return ParseResult.Success; case "/nowarn": @@ -911,7 +1026,7 @@ namespace Mono.CSharp { if (warn < 1) { throw new ArgumentOutOfRangeException ("warn"); } - report.SetIgnoreWarning (warn); + settings.SetIgnoreWarning (warn); } catch { report.Error (1904, "`{0}' is not a valid warning number", wc); return ParseResult.Error; @@ -1264,7 +1379,7 @@ namespace Mono.CSharp { Usage (); Environment.Exit (1); } - report.SetIgnoreWarning (warn); + settings.SetIgnoreWarning (warn); return ParseResult.Success; case "--wlevel": @@ -1274,7 +1389,7 @@ namespace Mono.CSharp { return ParseResult.Error; } - SetWarningLevel (args [++i]); + SetWarningLevel (args [++i], settings); return ParseResult.Success; case "--mcs-debug": @@ -1352,7 +1467,7 @@ namespace Mono.CSharp { } } - void SetWarningLevel (string s) + void SetWarningLevel (string s, CompilerSettings settings) { int level = -1; @@ -1364,7 +1479,7 @@ namespace Mono.CSharp { report.Error (1900, "Warning level must be in the range 0-4"); return; } - report.WarningLevel = level; + settings.WarningLevel = level; } // diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs index 4a9408ba1d..d38d269435 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs @@ -642,6 +642,12 @@ namespace Mono.CSharp { loc = expr.Location; } + public StatementExpression (ExpressionStatement expr, Location loc) + { + this.expr = expr; + this.loc = loc; + } + public ExpressionStatement Expr { get { return this.expr; @@ -925,14 +931,17 @@ namespace Mono.CSharp { return; } - if (unwind_protect) + if (unwind_protect || ec.EmitAccurateDebugInfo) ec.Emit (OpCodes.Stloc, ec.TemporaryReturn ()); } - if (unwind_protect) + if (unwind_protect) { ec.Emit (OpCodes.Leave, ec.CreateReturnLabel ()); - else + } else if (ec.EmitAccurateDebugInfo) { + ec.Emit (OpCodes.Br, ec.CreateReturnLabel ()); + } else { ec.Emit (OpCodes.Ret); + } } void Error_ReturnFromIterator (ResolveContext rc) @@ -1576,9 +1585,6 @@ namespace Mono.CSharp { protected override void DoEmit (EmitContext ec) { - if (li.IsConstant) - return; - li.CreateBuilder (ec); if (Initializer != null) @@ -1623,6 +1629,11 @@ namespace Mono.CSharp { { } + public override void Emit (EmitContext ec) + { + // Nothing to emit, not even sequence point + } + protected override Expression ResolveInitializer (BlockContext bc, LocalVariable li, Expression initializer) { initializer = initializer.Resolve (bc); @@ -2042,8 +2053,10 @@ namespace Mono.CSharp { #region Properties - public bool HasRet { - get { return (flags & Flags.HasRet) != 0; } + public bool HasUnreachableClosingBrace { + get { + return (flags & Flags.HasRet) != 0; + } } public Block Original { @@ -2296,7 +2309,6 @@ namespace Mono.CSharp { if (scope_initializers != null) EmitScopeInitializers (ec); - ec.Mark (StartLocation); DoEmit (ec); if (SymbolWriter.HasSymbolWriter) @@ -2305,14 +2317,8 @@ namespace Mono.CSharp { protected void EmitScopeInitializers (EmitContext ec) { - SymbolWriter.OpenCompilerGeneratedBlock (ec); - - using (ec.With (EmitContext.Options.OmitDebugInfo, true)) { - foreach (Statement s in scope_initializers) - s.Emit (ec); - } - - SymbolWriter.CloseCompilerGeneratedBlock (ec); + foreach (Statement s in scope_initializers) + s.Emit (ec); } protected virtual void EmitSymbolInfo (EmitContext ec) @@ -2444,14 +2450,28 @@ namespace Mono.CSharp { am_storey.EmitStoreyInstantiation (ec, this); } + if (scope_initializers != null) + EmitScopeInitializers (ec); + + if (ec.EmitAccurateDebugInfo && ec.Mark (StartLocation)) { + ec.Emit (OpCodes.Nop); + } + bool emit_debug_info = SymbolWriter.HasSymbolWriter && Parent != null && !(am_storey is IteratorStorey); if (emit_debug_info) ec.BeginScope (); - base.Emit (ec); + DoEmit (ec); + + if (SymbolWriter.HasSymbolWriter) + EmitSymbolInfo (ec); if (emit_debug_info) ec.EndScope (); + + if (ec.EmitAccurateDebugInfo && !HasUnreachableClosingBrace && ec.Mark (EndLocation)) { + ec.Emit (OpCodes.Nop); + } } void DefineAnonymousStorey (EmitContext ec) @@ -2980,6 +3000,7 @@ namespace Mono.CSharp { { this.compiler = ctx; top_block = this; + flags |= Flags.HasRet; ProcessParameters (); } @@ -2995,6 +3016,7 @@ namespace Mono.CSharp { { this.compiler = source.TopBlock.compiler; top_block = this; + flags |= Flags.HasRet; } public bool IsIterator { @@ -3029,18 +3051,18 @@ namespace Mono.CSharp { // for (int i = 0; i < existing_list.Count; ++i) { existing = existing_list[i]; - Block b = existing.Block; + Block b = existing.Block.Explicit; // Collision at same level - if (li.Block == b) { + if (li.Block.Explicit == b) { li.Block.Error_AlreadyDeclared (name, li); break; } // Collision with parent - b = li.Block; - while ((b = b.Parent) != null) { - if (existing.Block == b) { + Block parent = li.Block.Explicit; + while ((parent = parent.Parent) != null) { + if (parent == b) { li.Block.Error_AlreadyDeclared (name, li, "parent or current"); i = existing_list.Count; break; @@ -3049,9 +3071,8 @@ namespace Mono.CSharp { if (!ignoreChildrenBlocks) { // Collision with children - b = existing.Block; while ((b = b.Parent) != null) { - if (li.Block == b) { + if (li.Block.Explicit == b) { li.Block.Error_AlreadyDeclared (name, li, "child"); i = existing_list.Count; break; @@ -3272,36 +3293,37 @@ namespace Mono.CSharp { #if PRODUCTION try { #endif + if (IsCompilerGenerated) { + using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { + base.Emit (ec); + } + } else { + base.Emit (ec); + } - base.Emit (ec); + // + // If `HasReturnLabel' is set, then we already emitted a + // jump to the end of the method, so we must emit a `ret' + // there. + // + // Unfortunately, System.Reflection.Emit automatically emits + // a leave to the end of a finally block. This is a problem + // if no code is following the try/finally block since we may + // jump to a point after the end of the method. + // As a workaround, we're always creating a return label in + // this case. + // + if (ec.HasReturnLabel || !unreachable) { + if (ec.HasReturnLabel) + ec.MarkLabel (ec.ReturnLabel); - ec.Mark (EndLocation); + if (ec.ReturnType.Kind != MemberKind.Void) + ec.Emit (OpCodes.Ldloc, ec.TemporaryReturn ()); - if (ec.HasReturnLabel) - ec.MarkLabel (ec.ReturnLabel); + if (ec.EmitAccurateDebugInfo && !IsCompilerGenerated) + ec.Mark (EndLocation); - if (ec.return_value != null) { - ec.Emit (OpCodes.Ldloc, ec.return_value); ec.Emit (OpCodes.Ret); - } else { - // - // If `HasReturnLabel' is set, then we already emitted a - // jump to the end of the method, so we must emit a `ret' - // there. - // - // Unfortunately, System.Reflection.Emit automatically emits - // a leave to the end of a finally block. This is a problem - // if no code is following the try/finally block since we may - // jump to a point after the end of the method. - // As a workaround, we're always creating a return label in - // this case. - // - - if (ec.HasReturnLabel || !unreachable) { - if (ec.ReturnType.Kind != MemberKind.Void) - ec.Emit (OpCodes.Ldloc, ec.TemporaryReturn ()); - ec.Emit (OpCodes.Ret); - } } #if PRODUCTION diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/symbolwriter.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/symbolwriter.cs index ce19cfc492..933d69e085 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/symbolwriter.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/symbolwriter.cs @@ -92,11 +92,10 @@ namespace Mono.CSharp } } - public static SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id, - IMethodDef method) + public static SourceMethodBuilder OpenMethod (ICompileUnit file, IMethodDef method) { if (symwriter != null) - return symwriter.OpenMethod (file, ns_id, method); + return symwriter.OpenMethod (file, -1 /* Not used */, method); else return null; } @@ -125,15 +124,6 @@ namespace Mono.CSharp } } - public static int DefineNamespace (string name, CompileUnitEntry source, - string[] using_clauses, int parent) - { - if (symwriter != null) - return symwriter.DefineNamespace (name, source, using_clauses, parent); - else - return -1; - } - public static void DefineAnonymousScope (int id) { if (symwriter != null) @@ -232,8 +222,7 @@ namespace Mono.CSharp if (symwriter != null) { SourceFileEntry file = loc.SourceFile.SourceFileEntry; int offset = GetILOffset (ig); - symwriter.MarkSequencePoint ( - offset, file, loc.Row, loc.Column, loc.Hidden); + symwriter.MarkSequencePoint (offset, file, loc.Row, loc.Column, false); } }