public MemoryVisitor(CodeContractAwareHostEnvironment host, PdbReader pdbReader, ContractProvider contractProvider, MemoryContractsInformation memoryContractsInformation, PointsToInformation pointsToInformation)
 {
     _host = host;
     _pdbReader = pdbReader;
     _contractProvider = contractProvider;
     _memoryContractsInformation = memoryContractsInformation;
     _errorReportItems = new List<ErrorReportItem>();
     _pointsToInformation = pointsToInformation;
 }
示例#2
0
 /// <summary>
 /// Wraps a call to GetTypeContractFor inside of a try-catch statement.
 /// </summary>
 public static bool TryGetTypeContract(CodeContractAwareHostEnvironment host, ITypeReference type, out ITypeContract typeContract, DocTracker docTracker) {
   Contract.Requires(host != null);
   Contract.Requires(type != null);
   Contract.Ensures(!Contract.Result<bool>() || Contract.ValueAtReturn(out typeContract) != null);
   try {
     var unit = TypeHelper.GetDefiningUnit(type.ResolvedType);
     if (unit == null) {
       typeContract = null;
     } else {
       IContractProvider lcp = host.GetContractExtractor(unit.UnitIdentity);
       if (lcp == null) {
         typeContract = null;
       } else {
         typeContract = lcp.GetTypeContractFor(type);
       }
     }
   } catch (NullReferenceException) {
     docTracker.WriteLine("ERROR: NullReferenceException was thrown in CCI!");
     typeContract = null;
   }
   return typeContract != null;
 }
示例#3
0
 /// <summary>
 /// Wraps a call to GetMethodContractFor inside of a try-catch statement.
 /// </summary>
 public static bool TryGetMethodContract(CodeContractAwareHostEnvironment host, IMethodReference method, out IMethodContract methodContract, DocTracker docTracker) {
   Contract.Requires(host != null);
   Contract.Requires(method != null);
   Contract.Ensures(!Contract.Result<bool>() || Contract.ValueAtReturn(out methodContract) != null);
   try {
     methodContract = ContractHelper.GetMethodContractFor(host, method.ResolvedMethod);
   } catch (NullReferenceException) {
     docTracker.WriteLine("ERROR: NullReferenceException was thrown in CCI!");
     methodContract = null;
   }
   //} catch (Exception e) {
   //  docTracker.WriteLine("ERROR: Exception of type '{0}' was thrown in CCI!", e.GetType().Name);
   //  docTracker.WriteLine("\t'{0}'", e.Message);
   //  methodContract = null;
   //}
   return methodContract != null;
 }
示例#4
0
 /// <summary>
 /// Creates a new contract packager.
 /// </summary>
 public ContractPackager(CodeContractAwareHostEnvironment host, DocTracker docTracker) {
   Contract.Requires(host != null);
   Contract.Requires(docTracker != null);
   this.host = host;
   this.docTracker = docTracker;
 }
示例#5
0
    /// <summary>
    /// Creates a ContractTraverser
    /// </summary>
    /// <param name="contracts">The dictionary of contracts. This gets filled with contracts during the traversal.</param>
    /// <param name="options">The options.</param>
    /// <param name="host">The host environment of the traverser used to load any required assemblies.</param>
    /// <param name="docTracker">The DocTracker used to provide metrics and to be written into during the traversal.</param>
    public ContractVisitor(CodeContractAwareHostEnvironment host, IDictionary<string, XContract[]> contracts, Options options, DocTracker docTracker) {
      Contract.Requires(host != null);
      Contract.Requires(contracts != null);
      //Contract.Requires(options != null);
      Contract.Requires(docTracker != null);

      this.contracts = contracts;
      //this.options = options;
      this.docTracker = docTracker;
      this.host = host;
    }
        private static MemoryContractsInformation ExtractMemoryContractsFromModule(CodeContractAwareHostEnvironment host, IModule module)
        {
            var memoryContractsInformation = new MemoryContractsInformation();

            if (_visitedModules.Contains(module))
            {
                return memoryContractsInformation;
            }

            _visitedModules.Add(module);

            if (module != null && module != Dummy.Module && module != Dummy.Assembly)
            {
                PdbReader pdbReader = null;
                string pdbFile = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile))
                    {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader);

                var extractor = new MemoryContractsExtractor();

                extractor.Visit(module);

                memoryContractsInformation.MethodsTmpTypes = extractor.MethodsTmpTypes;
                memoryContractsInformation.MethodsTmpContracts = extractor.MethodsTmpContracts;
                memoryContractsInformation.MethodsTmpContractsWithConds = extractor.MethodsTmpContractsWithConds;
                memoryContractsInformation.MethodsRsdTypes = extractor.MethodsRsdTypes;
                memoryContractsInformation.MethodsRsdContracts = extractor.MethodsRsdContracts;
                memoryContractsInformation.MethodsRsdContractsWithConds = extractor.MethodsRsdContractsWithConds;
                memoryContractsInformation.MethodsRsdExprs = extractor.MethodsRsdExprs;

                //merge the contracts of the referenced assemblies
                foreach (var assemblyReference in module.AssemblyReferences)
                {
                    //skip assemblies that we know don't have memory contracts
                    if (!new List<string>() { "mscorlib", "Contracts", "System", "Microsoft" }.Exists(s => assemblyReference.Name.Value.StartsWith(s)))
                    {
                        var referencedAssembly = host.LoadAssembly(assemblyReference.AssemblyIdentity);

                        var referencedModuleMemoryContractsInformation = ExtractMemoryContractsFromModule(host, referencedAssembly);

                        if (referencedModuleMemoryContractsInformation.MethodsTmpTypes != null)
                        {
                            foreach (var methodName in referencedModuleMemoryContractsInformation.MethodsTmpTypes.Keys)
                            {
                                memoryContractsInformation.MethodsTmpTypes[methodName] = referencedModuleMemoryContractsInformation.MethodsTmpTypes[methodName];
                            }
                        }

                        if (referencedModuleMemoryContractsInformation.MethodsRsdTypes != null)
                        {
                            foreach (var methodName in referencedModuleMemoryContractsInformation.MethodsRsdTypes.Keys)
                            {
                                memoryContractsInformation.MethodsRsdTypes[methodName] = referencedModuleMemoryContractsInformation.MethodsRsdTypes[methodName];
                            }
                        }
                    }
                }
            }

            return memoryContractsInformation;
        }
        private static MemoryContractsInformation ExtractMemoryContracts(CodeContractAwareHostEnvironment host, string assemblyFullPath)
        {
            var module = host.LoadUnitFrom(assemblyFullPath) as IModule;

            return ExtractMemoryContractsFromModule(host, module);
        }
        private static List<ErrorReportItem> RewriteAssembly(CodeContractAwareHostEnvironment host, string assemblyFullPath, MemoryContractsInformation memoryContractsInformation, PointsToInformation pointsToInformation)
        {
            var module = host.LoadUnitFrom(assemblyFullPath) as IModule;

            PdbReader pdbReader = null;
            string pdbFile = Path.ChangeExtension(module.Location, "pdb");
            if (File.Exists(pdbFile))
            {
                using (var pdbStream = File.OpenRead(pdbFile))
                {
                    pdbReader = new PdbReader(pdbStream, host);
                }
            }

            if (module != null && module != Dummy.Module && module != Dummy.Assembly)
            {
                var mutableModule = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader);

                using (pdbReader)
                {
                    var contractProvider = Microsoft.Cci.MutableContracts.ContractHelper.ExtractContracts(host, mutableModule, pdbReader, pdbReader);

                    var mutator = new MemoryVisitor(host, pdbReader, contractProvider, memoryContractsInformation, pointsToInformation);

                    mutator.Visit(mutableModule);

                    Microsoft.Cci.MutableContracts.ContractHelper.InjectContractCalls(host, mutableModule, contractProvider, pdbReader);

                    Stream peStream = File.Create(Path.ChangeExtension(mutableModule.Location, ".mod.dll"));

                    if (pdbReader == null)
                    {
                        PeWriter.WritePeToStream(mutableModule, host, peStream);
                    }
                    else
                    {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(pdbFile, ".mod.pdb"), pdbReader))
                        {
                            PeWriter.WritePeToStream(mutableModule, host, peStream, pdbReader, pdbReader, pdbWriter);
                        }
                    }

                    peStream.Close();

                    return mutator.ErrorReportItems;
                }
            }

            return null;
        }
        static int Main(string[] args)
        {
            //for debugging
            //args = new string[] { @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_with_contracts\Example\obj\Debug\Decl\Example.dll", @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\Contracts.Contract.Memory\;C:\Program Files (x86)\Microsoft\Contracts\PublicAssemblies\v3.5\;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\;C:\Windows\Microsoft.NET\Framework\v2.0.50727\;C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\Contracts.Contract.Memory\CodeContracts;C:\Program Files (x86)\Microsoft\Contracts\PublicAssemblies\v3.5\CodeContracts;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\CodeContracts;C:\Windows\Microsoft.NET\Framework\v2.0.50727\CodeContracts;C:\Program Files (x86)\Microsoft\Contracts\Contracts\v3.5" };
            //args = new string[] { @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_with_contracts_Person\PersonExample\obj\Debug\Decl\PersonExample.dll" };
            //args = new string[] { @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\experiments\experiments\obj\Debug\Decl\experiments.dll" };
            //args = new string[] { @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_cross_assembly\Assembly1\obj\Debug\Decl\Assembly1.dll", @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_cross_assembly\Assembly2\bin\Debug\;C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\Contracts.Contract.Memory\;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\;C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_cross_assembly\Assembly2\bin\Debug\CodeContracts;C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\Contracts.Contract.Memory\CodeContracts;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\CodeContracts;C:\Program Files (x86)\Microsoft\Contracts\Contracts\.NETFramework\v4.0" };
            //args = new string[] { @"C:\TESIS\tesis\cci_rewriter\example_with_contracts_Person\PersonExample\obj\Debug\Decl\PersonExample.dll", @"C:\TESIS\tesis\cci_rewriter\Contracts.Contract.Memory\;C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\;C:\TESIS\tesis\cci_rewriter\Contracts.Contract.Memory\CodeContracts;C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\CodeContracts;C:\Program Files\Microsoft\Contracts\Contracts\.NETFramework\v4.0" };

            if (args.Length < 1)
            {
                Console.WriteLine("Usage: memory_contracts_rewriter.exe [assembly_full_path] [lib_paths]");
                return 1;
            }

            var assemblyFullPath = args[0];
            var libPaths = new string[0];
            if (args.Length > 1)
            {
                libPaths = args[1].Split(Path.PathSeparator);
            }

            try
            {
                var host = new CodeContractAwareHostEnvironment(libPaths, true, true);

                var hasMemoryContracts = false;
                var module = host.LoadUnitFrom(assemblyFullPath) as IModule;
                foreach (var assemblyReference in module.AssemblyReferences)
                {
                    if (assemblyReference.Name.Value == "Contracts")
                    {
                        hasMemoryContracts = true;
                        break;
                    }
                }

                if (hasMemoryContracts)
                {
                    var memoryContractsInformation = ExtractMemoryContracts(host, assemblyFullPath);

                    var pointsToInformation = new PointsToInformation(assemblyFullPath);

                    List<ErrorReportItem> errorReportItems = RewriteAssembly(host, assemblyFullPath, memoryContractsInformation, pointsToInformation);

                    if (errorReportItems != null)
                    {
                        foreach (var errorReportItem in errorReportItems)
                        {
                            Console.WriteLine("OutputError,{0},,,false,False,False,error,{1}", errorReportItem.Message, errorReportItem.Location);
                        }
                    }
                }
                else
                {
                    return 2;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return 1;
            }

            return 0;
        }
示例#10
0
    /// <summary>
    /// Traverse the given assembly (located in options.Assembly) for contracts and return the contracts.
    /// </summary>
    /// <remarks>
    /// We use dictionary mapping special string ids that are unique to each member in an XML file to 
    /// the contracts that that member has.
    /// </remarks>
    static IDictionary<string, XContract[]> GetContracts(Options options, DocTracker docTracker) {
      Contract.Requires(options != null);
      Contract.Requires(docTracker != null);
      Contract.Ensures(Contract.Result<IDictionary<string,XContract[]>>() != null);
      
      #region Establish host and load assembly

      Contract.Assume(options.resolvedPaths != null);

      var host = new CodeContractAwareHostEnvironment(options.libpaths);
      foreach (var p in options.resolvedPaths) {
        host.AddResolvedPath(p);
      }
      IModule module = host.LoadUnitFrom(options.assembly) as IModule;
      if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
        Console.WriteLine("'{0}' is not a PE file containing a CLR module or assembly.", options.assembly);
        Environment.Exit(1);
      }
      #endregion
      #region Create the contracts dictionary
      Dictionary<string, XContract[]> contracts = new Dictionary<string, XContract[]>(StringComparer.Ordinal);  //Use Ordinal compare for faster string comparison.
      #endregion
      #region Traverse module and extract contracts
      var contractsVisitor = new ContractVisitor(host, contracts, options, docTracker);
      var traverser = new ContractTraverser(host);
      traverser.PreorderVisitor = contractsVisitor;
      traverser.Traverse(module);
      #endregion
      return contracts;
    }
示例#11
0
    public static Bpl.Program/*?*/ TranslateAssembly(List<string> assemblyNames, HeapFactory heapFactory, Options options, List<Regex> exemptionList, bool whiteList) {
      Contract.Requires(assemblyNames != null);
      Contract.Requires(heapFactory != null);

      var libPaths = options.libpaths;
      var wholeProgram = options.wholeProgram;
      var/*?*/ stubAssemblies = options.stub;
      var phoneControlsConfigFile = options.phoneControls;
      var doPhoneNav = options.phoneNavigationCode;
      var doPhoneFeedback = options.phoneFeedbackCode;

      var host = new CodeContractAwareHostEnvironment(libPaths != null ? libPaths : Enumerable<string>.Empty, true, true);
      Host = host;

      Bpl.CommandLineOptions.Install(new Bpl.CommandLineOptions());

      #region Assemlies to translate (via cmd line)
      modules = new List<IModule>();
      var contractExtractors = new Dictionary<IUnit, IContractProvider>();
      var pdbReaders = new Dictionary<IUnit, PdbReader>();
      #region Load *all* of the assemblies before doing anything else so that they can all vote on unification matters
      foreach (var a in assemblyNames) {
        var module = host.LoadUnitFrom(a) as IModule;
        if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
          Console.WriteLine(a + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
          Console.WriteLine("Skipping it, continuing with other input assemblies");
          continue;
        }
        modules.Add(module);
      }
      #endregion
      #region Decompile all of the assemblies
      var decompiledModules = new List<IModule>();
      foreach (var m in modules) {
        PdbReader/*?*/ pdbReader = null;
        string pdbFile = Path.ChangeExtension(m.Location, "pdb");
        if (File.Exists(pdbFile)) {
          Stream pdbStream = File.OpenRead(pdbFile);
          pdbReader = new PdbReader(pdbStream, host);
        }
        var m2 = Decompiler.GetCodeModelFromMetadataModel(host, m, pdbReader, DecompilerOptions.Unstack) as IModule;
        // The decompiler does not turn calls to Assert/Assume into Code Model nodes
        m2 = new Microsoft.Cci.MutableContracts.ContractExtractor.AssertAssumeExtractor(host, pdbReader).Rewrite(m2);
        decompiledModules.Add(m2);
        host.RegisterAsLatest(m2);
        contractExtractors.Add(m2, host.GetContractExtractor(m2.UnitIdentity));
        pdbReaders.Add(m2, pdbReader);
      }
      modules = decompiledModules;
      #endregion
      #endregion

      #region Assemblies to translate (stubs)
      if (stubAssemblies != null) {
        foreach (var s in stubAssemblies) {
          var module = host.LoadUnitFrom(s) as IModule;
          if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
            Console.WriteLine(s + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
            Console.WriteLine("Skipping it, continuing with other input assemblies");
          }
          PdbReader/*?*/ pdbReader = null;
          string pdbFile = Path.ChangeExtension(module.Location, "pdb");
          if (File.Exists(pdbFile)) {
            Stream pdbStream = File.OpenRead(pdbFile);
            pdbReader = new PdbReader(pdbStream, host);
          }
          module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader, DecompilerOptions.Unstack) as IModule;

          var copier = new CodeDeepCopier(host);
          var mutableModule = copier.Copy(module);

          var mscorlib = TypeHelper.GetDefiningUnit(host.PlatformType.SystemObject.ResolvedType);

          //var mutator = new ReparentModule(host, mscorlib, mutableModule);
          //module = mutator.Rewrite(mutableModule);
          //modules.Add(Tuple.Create(module, pdbReader));

          RewriteUnitReferences renamer = new RewriteUnitReferences(host, mutableModule);
          var mscorlibAssembly = (IAssembly)mscorlib;
          renamer.targetAssembly = mscorlibAssembly;
          renamer.originalAssemblyIdentity = mscorlibAssembly.AssemblyIdentity;
          renamer.RewriteChildren(mutableModule);
          modules.Add((IModule)mutableModule);
          contractExtractors.Add(module, host.GetContractExtractor(module.UnitIdentity));
          pdbReaders.Add(module, pdbReader);
        }
      }
      #endregion

      if (modules.Count == 0) {
        throw new TranslationException("No input assemblies to translate.");
      }

      var primaryModule = modules[0];
      Sink sink= new Sink(host, heapFactory, options, exemptionList, whiteList);
      TranslationHelper.tmpVarCounter = 0;

      // TODO move away, get all plugin and translators from a config file or alike
      #region Plugged translators
      List<Translator> translatorsPlugged = new List<Translator>();
      ITranslationPlugin bctPlugin= new BytecodeTranslatorPlugin(wholeProgram);
      Translator bcTranslator = bctPlugin.getTranslator(sink, contractExtractors, pdbReaders);
      translatorsPlugged.Add(bcTranslator);

      if (phoneControlsConfigFile != null && phoneControlsConfigFile != "") {
        // TODO this should be part of the translator initialziation
        PhoneCodeHelper.initialize(host);
        PhoneCodeHelper.instance().PhonePlugin = new PhoneControlsPlugin(phoneControlsConfigFile);

        if (doPhoneNav) {
          // TODO this should be part of the translator initialziation
          PhoneCodeHelper.instance().PhoneNavigationToggled = true;

          ITranslationPlugin phoneInitPlugin = new PhoneInitializationPlugin();
          ITranslationPlugin phoneNavPlugin = new PhoneNavigationPlugin();
          Translator phInitTranslator = phoneInitPlugin.getTranslator(sink, contractExtractors, pdbReaders);
          Translator phNavTranslator = phoneNavPlugin.getTranslator(sink, contractExtractors, pdbReaders);
          translatorsPlugged.Add(phInitTranslator);
          translatorsPlugged.Add(phNavTranslator);
        }

        if (doPhoneFeedback) {
          // TODO this should be part of the translator initialziation
          PhoneCodeHelper.instance().PhoneFeedbackToggled = true;

          ITranslationPlugin phoneFeedbackPlugin = new PhoneFeedbackPlugin();
          Translator phFeedbackTranslator = phoneFeedbackPlugin.getTranslator(sink, contractExtractors, pdbReaders);
          translatorsPlugged.Add(phFeedbackTranslator);
        }
      }
      #endregion
      sink.TranslationPlugins = translatorsPlugged;

      /*
      if (phoneControlsConfigFile != null && phoneControlsConfigFile != "") {
        // TODO send this all way to initialization of phone plugin translator
        PhoneCodeHelper.initialize(host);
        PhoneCodeHelper.instance().PhonePlugin = new PhoneControlsPlugin(phoneControlsConfigFile);
        
        // TODO these parameters will eventually form part of plugin configuration
        if (doPhoneNav) {
          PhoneCodeHelper.instance().PhoneNavigationToggled = true;
          PhoneInitializationMetadataTraverser initTr = new PhoneInitializationMetadataTraverser(host);
          initTr.InjectPhoneCodeAssemblies(modules);
          PhoneNavigationMetadataTraverser navTr = new PhoneNavigationMetadataTraverser(host);
          navTr.InjectPhoneCodeAssemblies(modules);
        }

        if (doPhoneFeedback) {
          PhoneCodeHelper.instance().PhoneFeedbackToggled = true;
          PhoneControlFeedbackMetadataTraverser fbMetaDataTraverser= new PhoneControlFeedbackMetadataTraverser(host);
          fbMetaDataTraverser.Visit(modules);
        }
      }
      */

      // TODO replace the whole translation by a translator initialization and an orchestrator calling back for each element
      // TODO for the current BC translator it will possibly just implement onMetadataElement(IModule)
      // TODO refactor this away, handle priorities between plugged translators
      IOrderedEnumerable<Translator> prioritizedTranslators = translatorsPlugged.OrderBy(t => t.getPriority());
      foreach (Translator t in prioritizedTranslators) {
        t.initialize();
        if (t.isOneShot())
          t.TranslateAssemblies(modules);
      }

      foreach (var pair in sink.delegateTypeToDelegates.Values) {
        CreateDispatchMethod(sink, pair.Item1, pair.Item2);
        CreateDelegateCreateMethod(sink, pair.Item1, pair.Item2);
        CreateDelegateAddMethod(sink, pair.Item1, pair.Item2);
        CreateDelegateRemoveMethod(sink, pair.Item1, pair.Item2);
      }

      // Subtyping for extern types
      if(sink.Options.typeInfo > 0) sink.DeclareExternTypeSubtyping();

      string outputFileName = primaryModule.Name + ".bpl";
      callPostTranslationTraversers(modules, sink, phoneControlsConfigFile, outputFileName);
      if (PhoneCodeHelper.instance().PhoneNavigationToggled) {
        finalizeNavigationAnalysisAndBoogieCode(phoneControlsConfigFile, sink, outputFileName);
      }

      //sink.CreateIdentifierCorrespondenceTable(primaryModule.Name.Value);

      //var rc = new Bpl.ResolutionContext((Bpl.IErrorSink)null);
      //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
      //  decl.Register(rc);
      //}
      //sink.TranslatedProgram.Resolve(rc);
      //var goodDecls = new List<Bpl.Declaration>();
      //var tc = new Bpl.TypecheckingContext(null);
      //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
      //  var impl = decl as Bpl.Implementation;
      //  if (impl == null) {
      //    goodDecls.Add(decl);
      //    continue;
      //  }
      //  try {
      //    //var tc = new Bpl.TypecheckingContext(null);
      //    impl.Typecheck(tc);
      //    goodDecls.Add(impl);
      //  } catch {
      //    Console.WriteLine("Deleting implementation for: " + impl.Name);
      //    // nothing to do, just continue
      //  }
      //}
      //sink.TranslatedProgram.TopLevelDeclarations = goodDecls;
      return sink.TranslatedProgram;
    }