/**** * Four cases: * 1. Ordinary method (not stubbed and not generic) * 2. Stubbed but not generic * 3. Not stubbed but generic * 4. Stubbed and generic * Note that there are two sub-cases for "is stubbed": "stub present" or "stub absent". * So that makes it a total of 6 cases. ****/ public static IMethodDefinition CheckAndAdd(IMethodDefinition m) { IMethodDefinition lookFor = m; if (m is IGenericMethodInstance) { lookFor = GenericMethods.GetTemplate(m); } ITypeDefinition containingType = m.ContainingTypeDefinition; if (containingType.InternedKey == 0) { return(m); // Ignore methods from Cci's Dummy typeref. } bool matches = MatchesSuppressM(m); if (matches) { containingType = Stubs.GetStubType(containingType); if (containingType == null) { return(null); // This entire containingType is to be ignored. } lookFor = Utils.GetMethodSignMatch(containingType, lookFor); if (lookFor == null) { return(null); // containingType itself is stubbed, but the stub does not define a method equivalent to m. } } IMethodDefinition methToAdd; if (m is IGenericMethodInstance) { // Here, lookFor is a template method methToAdd = GenericMethods.RecordInfo(lookFor, m, matches); } else { methToAdd = lookFor; } if (!rtaAnalyzer.visitedMethods.Contains(methToAdd) && !rtaAnalyzer.methods.Contains(methToAdd)) { rtaAnalyzer.rtaLogSW.WriteLine("SRK_DBG: Adding method: {0}", methToAdd.FullName()); rtaAnalyzer.methods.Add(methToAdd); } return(methToAdd); }
public void ProcessVirtualInvoke(IMethodDefinition mCallee, ITypeDefinition calleeClass, bool isAddrTaken) { // mCallee is an ordinary method - never a template method. // calleeClass and mCallee are either both stubbed or, both unstubbed - i.e. they are consistent. bool isInterface = calleeClass.IsInterface; IMethodDefinition calleeTemplate = null; if (mCallee is IGenericMethodInstance) { calleeTemplate = (mCallee as IGenericMethodInstance).GenericMethod.ResolvedMethod; } foreach (ITypeDefinition cl in allocClasses) { if (cl is IArrayTypeReference) { continue; } if (!Stubber.SuppressM(cl)) { bool process = false; if (isInterface && Utils.ImplementsInterface(cl, calleeClass)) { process = true; } if (Utils.ExtendsClass(cl, calleeClass)) { process = true; } if (!process) { continue; } IMethodDefinition calleeArg; if (mCallee is IGenericMethodInstance) { calleeArg = calleeTemplate; } else { calleeArg = mCallee; } IMethodDefinition meth = Utils.GetMethodSignMatchRecursive(cl, calleeArg); if (meth == null) { continue; } if (meth.IsGeneric && calleeTemplate != null) { IMethodDefinition instMeth = GenericMethods.RecordInfo(meth, mCallee, /* createIfReqd = */ true); IMethodDefinition addedMeth = Stubber.CheckAndAdd(instMeth); if (addedMeth != null && isAddrTaken) { addrTakenMethods.Add(addedMeth); } } else if (meth.IsGeneric && calleeTemplate == null) { continue; } else if (!meth.IsGeneric && calleeTemplate != null) { continue; } else // meth is not generic and calleeTemplate is null { IMethodDefinition addedMeth = Stubber.CheckAndAdd(meth); if (addedMeth != null && isAddrTaken) { addrTakenMethods.Add(addedMeth); } } } } }