X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Ftools%2Flinker%2FMono.Linker.Steps%2FSweepStep.cs;h=9bd2bad93444e1d258faa01310f7b4b7b0600571;hb=6352c16dd5306ccb8bedc742bf99505688695dc6;hp=a4fc201636888a0d7b8ce95e27a394325a1c69b9;hpb=2a4a45902114498c57108cab2515958ca3598cef;p=mono.git diff --git a/mcs/tools/linker/Mono.Linker.Steps/SweepStep.cs b/mcs/tools/linker/Mono.Linker.Steps/SweepStep.cs index a4fc2016368..9bd2bad9344 100644 --- a/mcs/tools/linker/Mono.Linker.Steps/SweepStep.cs +++ b/mcs/tools/linker/Mono.Linker.Steps/SweepStep.cs @@ -37,6 +37,7 @@ namespace Mono.Linker.Steps { public class SweepStep : BaseStep { AssemblyDefinition [] assemblies; + HashSet resolvedTypeReferences; protected override void Process () { @@ -93,6 +94,9 @@ namespace Mono.Linker.Steps { void SweepReferences (AssemblyDefinition assembly, AssemblyDefinition target) { + if (assembly == target) + return; + var references = assembly.MainModule.AssemblyReferences; for (int i = 0; i < references.Count; i++) { var reference = references [i]; @@ -102,21 +106,54 @@ namespace Mono.Linker.Steps { references.RemoveAt (i); // Removing the reference does not mean it will be saved back to disk! // That depends on the AssemblyAction set for the `assembly` - if (Annotations.GetAction (assembly) == AssemblyAction.Copy) { + switch (Annotations.GetAction (assembly)) { + case AssemblyAction.Copy: // Copy means even if "unlinked" we still want that assembly to be saved back // to disk (OutputStep) without the (removed) reference Annotations.SetAction (assembly, AssemblyAction.Save); - // note: we only enter here (Copy->Save once) so we nned to do the complete job - foreach (TypeReference tr in assembly.MainModule.GetTypeReferences ()) { - var td = tr.Resolve (); - // at this stage reference might include things that can't be resolved - tr.Scope = td == null ? null : assembly.MainModule.Import (td).Scope; - } + ResolveAllTypeReferences (assembly); + break; + + case AssemblyAction.Save: + case AssemblyAction.Link: + ResolveAllTypeReferences (assembly); + break; } return; } } + void ResolveAllTypeReferences (AssemblyDefinition assembly) + { + if (resolvedTypeReferences == null) + resolvedTypeReferences = new HashSet (); + if (resolvedTypeReferences.Contains (assembly)) + return; + resolvedTypeReferences.Add (assembly); + + var hash = new Dictionary (); + + foreach (TypeReference tr in assembly.MainModule.GetTypeReferences ()) { + if (hash.ContainsKey (tr)) + continue; + var td = tr.Resolve (); + IMetadataScope scope = tr.Scope; + // at this stage reference might include things that can't be resolved + // and if it is (resolved) it needs to be kept only if marked (#16213) + if ((td != null) && Annotations.IsMarked (td)) + scope = assembly.MainModule.Import (td).Scope; + hash.Add (tr, scope); + } + + // Resolve everything first before updating scopes. + // If we set the scope to null, then calling Resolve() on any of its + // nested types would crash. + + foreach (var e in hash) { + e.Key.Scope = e.Value; + } + } + void SweepType (TypeDefinition type) { if (type.HasFields)