[mtouch] Store a list of members for each native symbol.

There might be more than one member for each P/Invoke symbol, so make sure to
keep track of every one of them.
This commit is contained in:
Rolf Bjarne Kvinge 2017-01-18 09:29:46 +01:00
Родитель b4cc60572b
Коммит a09c1e8cc5
4 изменённых файлов: 44 добавлений и 13 удалений

Просмотреть файл

@ -7,13 +7,22 @@ namespace Xamarin.Tuner
{
public class DerivedLinkContext : LinkContext
{
Dictionary<string, MemberReference> required_symbols;
Dictionary<string, List<MemberReference>> required_symbols;
List<MethodDefinition> marshal_exception_pinvokes;
public Dictionary<string, MemberReference> RequiredSymbols {
public List<MemberReference> GetRequiredSymbolList (string symbol)
{
List<MemberReference> rv;
if (!RequiredSymbols.TryGetValue (symbol, out rv))
required_symbols [symbol] = rv = new List<MemberReference> ();
return rv;
}
public Dictionary<string, List<MemberReference>> RequiredSymbols {
get {
if (required_symbols == null)
required_symbols = new Dictionary<string, MemberReference> ();
required_symbols = new Dictionary<string, List<MemberReference>> ();
return required_symbols;
}
}

Просмотреть файл

@ -17,6 +17,12 @@ namespace MonoTouch.Tuner
PInvokeWrapperGenerator state;
bool skip_sdk_assemblies;
public DerivedLinkContext DerivedLinkContext {
get {
return (DerivedLinkContext) Context;
}
}
internal ListExportedSymbols (PInvokeWrapperGenerator state, bool skip_sdk_assemblies = false)
{
this.state = state;
@ -67,7 +73,7 @@ namespace MonoTouch.Tuner
if (method.IsPInvokeImpl && method.HasPInvokeInfo) {
var pinfo = method.PInvokeInfo;
if (pinfo.Module.Name == "__Internal")
((DerivedLinkContext) Context).RequiredSymbols [pinfo.EntryPoint] = method;
DerivedLinkContext.GetRequiredSymbolList (pinfo.EntryPoint).Add (method);
if (state != null) {
switch (pinfo.EntryPoint) {
@ -89,7 +95,7 @@ namespace MonoTouch.Tuner
object symbol;
// The Field attribute may have been linked away, but we've stored it in an annotation.
if (property != null && Context.Annotations.GetCustomAnnotations ("ExportedFields").TryGetValue (property, out symbol)) {
((DerivedLinkContext) Context).RequiredSymbols[(string) symbol] = property;
DerivedLinkContext.GetRequiredSymbolList ((string) symbol).Add (property);
}
}
}

Просмотреть файл

@ -1256,8 +1256,9 @@ namespace Xamarin.Bundler {
"Native linking failed, undefined Objective-C class: {0}. The symbol '{1}' could not be found in any of the libraries or frameworks linked with your application.",
symbol.Replace ("_OBJC_CLASS_$_", ""), symbol));
} else {
var member = target.GetMemberForSymbol (symbol.Substring (1));
if (member != null) {
var members = target.GetMembersForSymbol (symbol.Substring (1));
if (members != null && members.Count > 0) {
var member = members.First (); // Just report the first one.
// Neither P/Invokes nor fields have IL, so we can't find the source code location.
errors.Add (new MonoTouchException (5214, error,
"Native linking failed, undefined symbol: {0}. " +

Просмотреть файл

@ -167,8 +167,8 @@ namespace Xamarin.Bundler
Frameworks.Add ("CFNetwork"); // required by xamarin_start_wwan
}
Dictionary<string, MemberReference> entry_points;
public IDictionary<string, MemberReference> GetEntryPoints ()
Dictionary<string, List<MemberReference>> entry_points;
public IDictionary<string, List<MemberReference>> GetEntryPoints ()
{
if (entry_points == null)
GetRequiredSymbols ();
@ -182,7 +182,7 @@ namespace Xamarin.Bundler
var cache_location = Path.Combine (App.Cache.Location, "entry-points.txt");
if (cached_link || !any_assembly_updated) {
entry_points = new Dictionary<string, MemberReference> ();
entry_points = new Dictionary<string, List<MemberReference>> ();
foreach (var ep in File.ReadAllLines (cache_location))
entry_points.Add (ep, null);
} else {
@ -191,7 +191,7 @@ namespace Xamarin.Bundler
// This happens when using the simlauncher and the msbuild tasks asked for a list
// of symbols (--symbollist). In that case just produce an empty list, since the
// binary shouldn't end up stripped anyway.
entry_points = new Dictionary<string, MemberReference> ();
entry_points = new Dictionary<string, List<MemberReference>> ();
marshal_exception_pinvokes = new List<MethodDefinition> ();
} else {
entry_points = LinkContext.RequiredSymbols;
@ -214,9 +214,24 @@ namespace Xamarin.Bundler
return entry_points.Keys;
}
public MemberReference GetMemberForSymbol (string symbol)
public IEnumerable<string> GetRequiredSymbols (Assembly assembly, bool includeObjectiveCClasses)
{
MemberReference rv = null;
if (entry_points == null)
GetRequiredSymbols ();
foreach (var ep in entry_points) {
if (ep.Value == null)
continue;
foreach (var mr in ep.Value) {
if (mr.Module.Assembly == assembly.AssemblyDefinition)
yield return ep.Key;
}
}
}
public List<MemberReference> GetMembersForSymbol (string symbol)
{
List<MemberReference> rv = null;
entry_points?.TryGetValue (symbol, out rv);
return rv;
}