Example #1
0
        public static bool ImplementsInterface(ITypeDefinition tgt, ITypeDefinition queryItf)
        {
            if (queryItf == null || tgt == null)
            {
                return(false);
            }

            foreach (ITypeReference itf in tgt.Interfaces)
            {
                ITypeDefinition analItf = Stubber.GetTypeToAnalyze(itf.ResolvedType);
                if (analItf != null && tdc.Equals(queryItf, analItf.ResolvedType))
                {
                    return(true);
                }
            }
            foreach (ITypeReference itf in tgt.Interfaces)
            {
                ITypeReference analItf = Stubber.GetTypeToAnalyze(itf.ResolvedType);
                if (analItf != null && ImplementsInterface(analItf.ResolvedType, queryItf))
                {
                    return(true);
                }
            }
            foreach (ITypeReference bcl in tgt.BaseClasses)
            {
                ITypeReference analBcl = Stubber.GetTypeToAnalyze(bcl.ResolvedType);
                if (analBcl != null && ImplementsInterface(analBcl.ResolvedType, queryItf))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #2
0
        public static bool ExtendsClass(ITypeDefinition derivedCl, ITypeDefinition baseCl)
        {
            if (derivedCl == null || baseCl == null)
            {
                return(false);
            }
            ITypeDefinition analBaseCl = Stubber.GetTypeToAnalyze(baseCl);

            if (analBaseCl != null && tdc.Equals(derivedCl, analBaseCl))
            {
                return(true);
            }

            foreach (ITypeReference bcl in derivedCl.BaseClasses)
            {
                ITypeDefinition analBcl = Stubber.GetTypeToAnalyze(bcl.ResolvedType);
                if (analBcl != null && tdc.Equals(baseCl, analBcl))
                {
                    return(true);
                }
            }
            foreach (ITypeReference bcl in derivedCl.BaseClasses)
            {
                ITypeDefinition analBcl = Stubber.GetTypeToAnalyze(bcl.ResolvedType);
                if (ExtendsClass(analBcl, baseCl))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #3
0
        public void VisitLocals(MethodBody mBody)
        {
            ISet <IVariable> localVarSet = mBody.Variables;

            foreach (IVariable lclVar in localVarSet)
            {
                if (!lclVar.IsParameter && lclVar.Type.ResolvedType.IsStruct)
                {
                    Stubber.CheckAndAdd(lclVar.Type.ResolvedType);
                }
            }
            return;
        }
Example #4
0
        public static IMethodDefinition GetInstantiatedMeth(IMethodDefinition templateMeth, IMethodDefinition instMeth)
        {
            IGenericMethodInstance       genericM       = instMeth as IGenericMethodInstance;
            IEnumerable <ITypeReference> genericArgs    = genericM.GenericArguments;
            IList <ITypeReference>       stubbedArgList = new List <ITypeReference>();

            foreach (ITypeReference garg in genericArgs)
            {
                ITypeDefinition addedType = Stubber.CheckAndAdd(garg.ResolvedType);
                if (addedType != null)
                {
                    stubbedArgList.Add(addedType);
                }
                else
                {
                    stubbedArgList.Add(garg.ResolvedType);
                }
            }
            string argStr = GetGenericArgStr(stubbedArgList);
            IDictionary <string, IMethodDefinition> instMap;

            if (ClassAndMethodVisitor.genericMethodMap.ContainsKey(templateMeth))
            {
                instMap = ClassAndMethodVisitor.genericMethodMap[templateMeth];
            }
            else
            {
                instMap = new Dictionary <string, IMethodDefinition>();
                ClassAndMethodVisitor.genericMethodMap[templateMeth] = instMap;
            }
            if (instMap.ContainsKey(argStr))
            {
                return(instMap[argStr]);
            }
            else
            {
                GenericMethodInstanceReference newInstMethRef = new GenericMethodInstanceReference(templateMeth,
                                                                                                   genericArgs, internFactory);
                IMethodDefinition newInstMeth = newInstMethRef.ResolvedMethod;
                instMap[argStr] = newInstMeth;
                return(newInstMeth);
            }
        }
Example #5
0
        public static IMethodDefinition GetMethodSignMatchRecursive(ITypeDefinition ty, IMethodDefinition meth)
        {
            IMethodDefinition signMatchMeth = GetMethodSignMatch(ty, meth);

            if (signMatchMeth != null)
            {
                return(signMatchMeth);
            }

            foreach (ITypeReference bty in ty.BaseClasses)
            {
                ITypeDefinition analBty = Stubber.GetTypeToAnalyze(bty.ResolvedType);
                if (analBty != null && !Stubber.SuppressF(analBty))
                {
                    return(GetMethodSignMatchRecursive(analBty, meth));
                }
            }
            return(null);
        }
Example #6
0
 private void ProcessStaticConstructors(ITypeDefinition ty)
 {
     if (!rtaAnalyzer.clinitProcessedClasses.Contains(ty) && !Stubber.SuppressM(ty))
     {
         rtaAnalyzer.clinitProcessedClasses.Add(ty);
         IMethodDefinition clinitMeth = Utils.GetStaticConstructor(ty);
         if (clinitMeth != null)
         {
             Stubber.CheckAndAdd(clinitMeth);
         }
         if (ty.BaseClasses.Any())
         {
             ITypeDefinition baseTy = ty.BaseClasses.Single().ResolvedType;
             ProcessStaticConstructors(baseTy);
         }
         foreach (ITypeReference itf in ty.Interfaces)
         {
             ITypeDefinition itfD = itf.ResolvedType;
             ProcessStaticConstructors(itfD);
         }
     }
 }
Example #7
0
        public static bool TypeMatch(ITypeReference t1, ITypeReference t2)
        {
            ITypeDefinition tdef1 = t1.ResolvedType;
            ITypeDefinition tdef2 = t2.ResolvedType;

            if (tdc.Equals(tdef1, tdef2))
            {
                return(true);
            }

            if (Stubber.MatchesSuppressM(tdef1))
            {
                tdef1 = Stubs.GetStubType(tdef1);
            }
            if (Stubber.MatchesSuppressM(tdef2))
            {
                tdef2 = Stubs.GetStubType(tdef2);
            }
            // return (tdef1 != null && tdef2 != null && tdc.Equals(tdef1, tdef2));
            if (tdef1 != null && tdef2 != null)
            {
                if (tdef1 is IGenericTypeInstance)
                {
                    tdef1 = (tdef1 as IGenericTypeInstance).GenericType.ResolvedType;
                }
                if (tdef2 is IGenericTypeInstance)
                {
                    tdef2 = (tdef2 as IGenericTypeInstance).GenericType.ResolvedType;
                }
                return(tdc.Equals(tdef1, tdef2));
            }
            else
            {
                return(false);
            }
        }
Example #8
0
        static void DoRTA(IMetadataHost host, ClassAndMethodVisitor visitor, IModule rootModule, IModule stubsModule)
        {
            bool rootIsExe = false;

            if (rootModule.Kind == ModuleKind.ConsoleApplication)
            {
                rootIsExe = true;
            }
            StreamWriter rtaLogSW = new StreamWriter(Path.Combine(ConfigParams.LogDir, "rta_log.txt"));

            rtaAnalyzer = new RTAAnalyzer(rootIsExe, rtaLogSW, host);
            visitor.SetupRTAAnalyzer(rtaAnalyzer);
            Stubber.SetupRTAAnalyzer(rtaAnalyzer);
            Stubs.SetupInternFactory(host.InternFactory);
            GenericMethods.SetupInternFactory(host.InternFactory);
            Stubs.SetupStubs(stubsModule);

            bool diskLoadSuccessful = false;

            if (ConfigParams.LoadSavedScope)
            {
                diskLoadSuccessful = rtaAnalyzer.LoadSavedScope(host);
            }
            if (!diskLoadSuccessful)
            {
                Initialize(rtaAnalyzer.classes, rtaAnalyzer.entryPtClasses, rootModule, rootIsExe);
            }

            int  iterationCount = 0;
            bool changeInCount = true;
            int  startClassCnt, startMethCnt;

            while (changeInCount)
            {
                rtaLogSW.WriteLine();
                rtaLogSW.WriteLine("Starting RTA ITERATION:{0}", iterationCount);
                startClassCnt = rtaAnalyzer.classes.Count;
                startMethCnt  = rtaAnalyzer.methods.Count;
                rtaLogSW.WriteLine("Counts: classes:{0}   methods:{1}", startClassCnt, startMethCnt);
                rtaAnalyzer.classWorkList.Clear();
                rtaAnalyzer.visitedClasses.Clear();
                rtaAnalyzer.ignoredClasses.Clear();
                rtaAnalyzer.visitedMethods.Clear();
                rtaAnalyzer.ignoredMethods.Clear();
                CopyAll(rtaAnalyzer.classes, rtaAnalyzer.classWorkList);
                while (rtaAnalyzer.classWorkList.Count > 0)
                {
                    ITypeDefinition ty = rtaAnalyzer.classWorkList.First <ITypeDefinition>();
                    rtaAnalyzer.classWorkList.RemoveAt(0);
                    visitor.Traverse(ty);
                }
                if (rtaAnalyzer.classes.Count == startClassCnt && rtaAnalyzer.methods.Count == startMethCnt)
                {
                    changeInCount = false;
                }
                iterationCount++;
            }
            Copy(rtaAnalyzer.allocClasses, rtaAnalyzer.classes);
            rtaLogSW.WriteLine();
            rtaLogSW.WriteLine();
            foreach (IMethodDefinition m in rtaAnalyzer.methods)
            {
                rtaLogSW.WriteLine(m.FullName());
            }
            rtaLogSW.WriteLine();
            rtaLogSW.WriteLine();
            foreach (IMethodDefinition m in rtaAnalyzer.entryPtMethods)
            {
                rtaLogSW.WriteLine(m.FullName());
            }
            rtaLogSW.WriteLine();
            rtaLogSW.WriteLine();
            foreach (ITypeDefinition cl in rtaAnalyzer.classes)
            {
                rtaLogSW.WriteLine(cl.FullName());
            }

            rtaLogSW.WriteLine();
            rtaLogSW.WriteLine("ALLOC CLASSES");
            foreach (ITypeDefinition cl in rtaAnalyzer.allocClasses)
            {
                rtaLogSW.WriteLine(cl.FullName());
            }
            rtaLogSW.WriteLine("+++++++++++++++ RTA DONE ++++++++++++++++++");

            if (!diskLoadSuccessful)
            {
                rtaAnalyzer.SaveScope(host);
            }
            rtaLogSW.Close();
        }
Example #9
0
        public MethodCfgAndTac AnalyzeIntraProcedural(IMethodDefinition methodDefinition)
        {
            // System.Console.WriteLine("Traversing: {0}", methodDefinition.GetName());
            if (Stubber.SuppressM(methodDefinition))
            {
                return(null);
            }
            if (methodDefinition.IsExternal)
            {
                return(null);
            }
            if (methodDefinition.IsAbstract)
            {
                return(null);
            }

            ITypeDefinition         containingDefn         = methodDefinition.ContainingTypeDefinition;
            ISourceLocationProvider sourceLocationProvider = null;

            if (containingDefn != null)
            {
                IModule mod = TypeHelper.GetDefiningUnit(containingDefn) as IModule;
                if (moduleToPdbMap.ContainsKey(mod))
                {
                    sourceLocationProvider = moduleToPdbMap[mod];
                }
                else
                {
                    if (!(mod == null || mod == Dummy.Module || mod == Dummy.Assembly))
                    {
                        sourceLocationProvider = GetPdbReader(mod.Location);
                        moduleToPdbMap[mod]    = sourceLocationProvider;
                    }
                }
            }
            var disassembler = new Disassembler(host, methodDefinition, sourceLocationProvider);
            var methodBody   = disassembler.Execute();

            var cfAnalysis = new ControlFlowAnalysis(methodBody);
            // var cfg = cfAnalysis.GenerateNormalControlFlow();
            var cfg = cfAnalysis.GenerateExceptionalControlFlow();

            var domAnalysis = new DominanceAnalysis(cfg);

            domAnalysis.Analyze();
            domAnalysis.GenerateDominanceTree();

            var loopAnalysis = new NaturalLoopAnalysis(cfg);

            loopAnalysis.Analyze();

            var domFrontierAnalysis = new DominanceFrontierAnalysis(cfg);

            domFrontierAnalysis.Analyze();

            var splitter = new WebAnalysis(cfg, methodDefinition);

            splitter.Analyze();
            splitter.Transform();

            methodBody.UpdateVariables();

            var typeAnalysis = new TypeInferenceAnalysis(cfg, methodDefinition.Type);

            typeAnalysis.Analyze();

            var forwardCopyAnalysis = new ForwardCopyPropagationAnalysis(cfg);

            forwardCopyAnalysis.Analyze();
            forwardCopyAnalysis.Transform(methodBody);

            // backwardCopyAnalysis is buggy - it says so in the source file - see notes in src/test
            // var backwardCopyAnalysis = new BackwardCopyPropagationAnalysis(cfg);
            // backwardCopyAnalysis.Analyze();
            // backwardCopyAnalysis.Transform(methodBody);

            var liveVariables = new LiveVariablesAnalysis(cfg);

            liveVariables.Analyze();

            var ssa = new StaticSingleAssignment(methodBody, cfg);

            ssa.Transform();
            ssa.Prune(liveVariables);

            methodBody.UpdateVariables();

            MethodCfgAndTac mct = new MethodCfgAndTac(cfg, methodBody);

            foreach (IExceptionHandlerBlock ehInfo in disassembler.GetExceptionHandlers())
            {
                if (ehInfo is CatchExceptionHandler)
                {
                    mct.ehInfoList.Add(ehInfo as CatchExceptionHandler);
                }
            }
            return(mct);
        }
Example #10
0
        public void Traverse(IMethodDefinition methodDefinition)
        {
            ControlFlowGraph cfg;
            MethodBody       methodBody;
            IList <CatchExceptionHandler> ehInfoList;

            if (methodToCfgAndTacMap.ContainsKey(methodDefinition))
            {
                MethodCfgAndTac mct = methodToCfgAndTacMap[methodDefinition];
                if (mct == null)
                {
                    return;
                }
                cfg        = mct.cfg;
                methodBody = mct.methodBody;
                ehInfoList = mct.ehInfoList;
            }
            else
            {
                MethodCfgAndTac mct = AnalyzeIntraProcedural(methodDefinition);
                methodToCfgAndTacMap[methodDefinition] = mct;
                if (mct == null)
                {
                    return;
                }
                cfg        = mct.cfg;
                methodBody = mct.methodBody;
                ehInfoList = mct.ehInfoList;
            }

            if (rtaAnalyzer != null)
            {
                if (rtaAnalyzer.entryPtClasses.Contains(methodDefinition.ContainingTypeDefinition))
                {
                    if (rtaAnalyzer.rootIsExe)
                    {
                        // Add only the Main method as entry point
                        if (Utils.IsMainMethod(methodDefinition))
                        {
                            rtaAnalyzer.rtaLogSW.WriteLine("Adding main method: {0}", methodDefinition.FullName());
                            IMethodDefinition addedMeth = Stubber.CheckAndAdd(methodDefinition);
                            // The assumption is that addedMeth is not a template method. Here it is safe because it holds for the main method.
                            if (addedMeth != null)
                            {
                                rtaAnalyzer.entryPtMethods.Add(addedMeth);
                            }
                        }
                    }
                    else
                    {
                        if (methodDefinition.Visibility == TypeMemberVisibility.Public ||
                            methodDefinition.Visibility == TypeMemberVisibility.Family)
                        {
                            // Otherwise, add all public methods as entry points
                            IMethodDefinition addedMeth = Stubber.CheckAndAdd(methodDefinition);
                            rtaAnalyzer.rtaLogSW.WriteLine("Adding method: {0}", methodDefinition.FullName());
                            // The assumption here is that addedMeth is not a template method.
                            // TODO: It may be the case that this assumption does not hold in some cases.
                            if (addedMeth != null)
                            {
                                rtaAnalyzer.entryPtMethods.Add(addedMeth);
                            }
                        }
                    }
                }
                if (rtaAnalyzer.methods.Contains(methodDefinition) && !rtaAnalyzer.visitedMethods.Contains(methodDefinition))
                {
                    rtaAnalyzer.visitedMethods.Add(methodDefinition);
                    // rtaAnalyzer.rtaLogSW.WriteLine("SRK_DBG: Visiting method: {0}", methodDefinition.GetName());
                    rtaAnalyzer.VisitMethod(methodBody, cfg);
                }
                else
                {
                    rtaAnalyzer.ignoredMethods.Add(methodDefinition);
                }
            }
            else if (factGen != null)
            {
                if (factGen.methods.Contains(methodDefinition))
                {
                    factGen.GenerateFacts(methodBody, cfg, ehInfoList);
                }
            }
        }
Example #11
0
        public void VisitMethod(MethodBody mBody, ControlFlowGraph cfg)
        {
            VisitLocals(mBody);

            // Going through the instructions via cfg nodes instead of directly iterating over the instructions
            // of the methodBody becuase Phi instructions may not have been inserted in the insts of the methodBody.
            foreach (var node in cfg.Nodes)
            {
                foreach (var instruction in node.Instructions)
                {
                    // System.Console.WriteLine("{0}", instruction.ToString());
                    // System.Console.WriteLine("{0}", instruction.GetType().FullName());
                    // System.Console.WriteLine();

                    if (instruction is LoadInstruction)
                    {
                        LoadInstruction lInst      = instruction as LoadInstruction;
                        IValue          rhsOperand = lInst.Operand;
                        if (rhsOperand is StaticFieldAccess)
                        {
                            StaticFieldAccess rhsAcc  = rhsOperand as StaticFieldAccess;
                            IFieldReference   fld     = rhsAcc.Field;
                            ITypeDefinition   fldType = fld.ContainingType.ResolvedType;
                            Stubber.CheckAndAdd(fldType);
                        }
                        // Note: calls to static methods and instance methods appear as a StaticMethodReference
                        else if (rhsOperand is StaticMethodReference)
                        {
                            StaticMethodReference sMethAddr    = rhsOperand as StaticMethodReference;
                            IMethodDefinition     tgtMeth      = sMethAddr.Method.ResolvedMethod;
                            ITypeDefinition       containingTy = tgtMeth.ContainingTypeDefinition;
                            Stubber.CheckAndAdd(containingTy);
                            IMethodDefinition addedMeth = Stubber.CheckAndAdd(tgtMeth);
                            // addrTakenMethods do not contain templates.
                            if (addedMeth != null)
                            {
                                addrTakenMethods.Add(addedMeth);
                            }
                        }
                        //Note: calls to virtual, abstract or interface methods appear as VirtualMethodReference
                        else if (rhsOperand is VirtualMethodReference)
                        {
                            VirtualMethodReference sMethAddr    = rhsOperand as VirtualMethodReference;
                            IMethodDefinition      tgtMeth      = sMethAddr.Method.ResolvedMethod;
                            ITypeDefinition        containingTy = tgtMeth.ContainingTypeDefinition;
                            ITypeDefinition        addedTy      = Stubber.CheckAndAdd(containingTy);
                            IMethodDefinition      addedMeth    = Stubber.CheckAndAdd(tgtMeth);
                            if (addedTy != null && addedMeth != null)
                            {
                                // addrTakenMethods do not contain templates.
                                addrTakenMethods.Add(addedMeth);
                                ProcessVirtualInvoke(addedMeth, addedTy, true);
                            }
                        }
                        else if (rhsOperand is Reference)
                        {
                            Reference      rhsRef = rhsOperand as Reference;
                            IReferenceable refOf  = rhsRef.Value;
                            if (refOf is StaticFieldAccess)
                            {
                                StaticFieldAccess refAcc  = refOf as StaticFieldAccess;
                                IFieldDefinition  fld     = refAcc.Field.ResolvedField;
                                ITypeDefinition   fldType = fld.ContainingType.ResolvedType;
                                Stubber.CheckAndAdd(fldType);
                                addrTakenStatFlds.Add(fld);
                            }
                            else if (refOf is IVariable)
                            {
                                IVariable refVar = refOf as IVariable;
                                if (!refVar.Type.IsValueType || refVar.Type.ResolvedType.IsStruct)
                                {
                                    addrTakenLocals.Add(refVar);
                                }
                            }
                            else if (refOf is InstanceFieldAccess)
                            {
                                InstanceFieldAccess refAcc = refOf as InstanceFieldAccess;
                                IFieldDefinition    fld    = refAcc.Field.ResolvedField;
                                addrTakenInstFlds.Add(fld);
                            }
                            else if (refOf is ArrayElementAccess)
                            {
                                // All arrays will be added into domX as potential address taken.
                            }
                        }
                    }
                    else if (instruction is StoreInstruction)
                    {
                        StoreInstruction sInst = instruction as StoreInstruction;
                        IAssignableValue lhs   = sInst.Result;
                        if (lhs is StaticFieldAccess)
                        {
                            StaticFieldAccess lhsAcc  = lhs as StaticFieldAccess;
                            IFieldReference   fld     = lhsAcc.Field;
                            ITypeDefinition   fldType = fld.ContainingType.ResolvedType;
                            Stubber.CheckAndAdd(fldType);
                        }
                    }
                    else if (instruction is CreateObjectInstruction)
                    {
                        CreateObjectInstruction newObjInst = instruction as CreateObjectInstruction;
                        ITypeReference          objType    = newObjInst.AllocationType;
                        ITypeDefinition         objTypeDef = objType.ResolvedType;
                        if (objTypeDef is IGenericTypeInstance)
                        {
                            objTypeDef = objTypeDef.ResolvedType;
                        }
                        ITypeDefinition addedTy = Stubber.CheckAndAdd(objTypeDef);
                        if (addedTy != null && !allocClasses.Contains(addedTy))
                        {
                            allocClasses.Add(addedTy);
                        }
                    }
                    else if (instruction is CreateArrayInstruction)
                    {
                        CreateArrayInstruction newArrInst  = instruction as CreateArrayInstruction;
                        ITypeReference         elemType    = newArrInst.ElementType;
                        ITypeDefinition        elemTypeDef = elemType.ResolvedType;
                        ITypeDefinition        addedTy     = Stubber.CheckAndAdd(elemTypeDef);
                        if (addedTy != null && !allocClasses.Contains(addedTy))
                        {
                            allocClasses.Add(addedTy);
                        }
                    }
                    else if (instruction is MethodCallInstruction)
                    {
                        MethodCallInstruction invkInst       = instruction as MethodCallInstruction;
                        IMethodReference      callTgt        = invkInst.Method;
                        ITypeReference        containingType = callTgt.ContainingType;
                        ITypeDefinition       declType       = containingType.ResolvedType;
                        IMethodDefinition     callTgtDef     = callTgt.ResolvedMethod;
                        ITypeDefinition       addedType      = Stubber.CheckAndAdd(declType);
                        IMethodDefinition     addedMeth      = Stubber.CheckAndAdd(callTgtDef);
                        MethodCallOperation   callType       = invkInst.Operation;
                        if (callType == MethodCallOperation.Virtual && addedType != null && addedMeth != null)
                        {
                            ProcessVirtualInvoke(addedMeth, addedType, false);
                        }
                    }
                    else
                    {
                        // System.Console.WriteLine("{0}", instruction.ToString());
                        // System.Console.WriteLine("Not currently handled: {0}", instruction.GetType().ToString());
                        // System.Console.WriteLine();
                    }
                }
            }
        }
Example #12
0
        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);
                        }
                    }
                }
            }
        }