diff options
author | Marek Safar <marek.safar@gmail.com> | 2016-11-04 18:03:52 +0300 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2016-11-04 18:05:07 +0300 |
commit | 933d252afc5c4f2e5ca5df41564c940157a2e691 (patch) | |
tree | 73cc618dfd29fc9f2daf3fe50450c2a22b4bf15e /mcs/class/Mono.CompilerServices.SymbolWriter | |
parent | 627eaebf94e6218891656fbda6ed722226cc2f59 (diff) |
[mcs] More work on debug scopes declared out of order. Fixes #45774
Diffstat (limited to 'mcs/class/Mono.CompilerServices.SymbolWriter')
-rw-r--r-- | mcs/class/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/mcs/class/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs b/mcs/class/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs index 89763f52ec9..306570627a5 100644 --- a/mcs/class/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs +++ b/mcs/class/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs @@ -187,13 +187,54 @@ namespace Mono.CompilerServices.SymbolWriter public void DefineMethod (MonoSymbolFile file, int token) { var blocks = Blocks; + if (blocks.Length > 0) { + // + // When index is provided by user it can be inserted in + // any order but mdb format does not store its value. It + // uses stored order as the index instead. + // + var sorted = new List<CodeBlockEntry> (blocks.Length); + int max_index = 0; + for (int i = 0; i < blocks.Length; ++i) { + max_index = System.Math.Max (max_index, blocks [i].Index); + } + + for (int i = 0; i < max_index; ++i) { + var scope_index = i + 1; + + // + // Common fast path + // + if (i < blocks.Length && blocks [i].Index == scope_index) { + sorted.Add (blocks [i]); + continue; + } + + bool found = false; + for (int ii = 0; ii < blocks.Length; ++ii) { + if (blocks [ii].Index == scope_index) { + sorted.Add (blocks [ii]); + found = true; + break; + } + } + + if (found) + continue; - // - // When index is provided by user it can be inserted in - // any order but mdb format does not store its value. It - // uses store order instead as the index. - // - Array.Sort (blocks, (x, y) => x.Index.CompareTo (y.Index)); + // + // Ideally this should never happen but with current design we can + // generate scope index for unreachable code before reachable code + // + sorted.Add (new CodeBlockEntry (scope_index, -1, CodeBlockEntry.Type.CompilerGenerated, 0)); + } + + blocks = sorted.ToArray (); + for (int i = 0; i < blocks.Length; ++i) { + if (blocks [i].Index - 1 != i) + throw new ArgumentException ("CodeBlocks cannot be converted to mdb format"); + } + } var entry = new MethodEntry ( file, _comp_unit.Entry, token, ScopeVariables, |