Пример #1
0
 void makeCurrent(const Transform& transform)
 {
     currentIterator =
         std::find(absolute.begin(), absolute.end(), transform);
     if (currentIterator == absolute.end())
         currentIterator = absolute.insert(absolute.end(), transform);
 }
Пример #2
0
 void makeCurrentTransform(const Transform& transform)
 {
     Transforms::iterator oldPosition =
         std::find(absoluteTransforms.begin(), absoluteTransforms.end(), transform);
     if (oldPosition == absoluteTransforms.end())
         absoluteTransforms.push_back(transform);
     else
         absoluteTransforms.splice(absoluteTransforms.end(), absoluteTransforms, oldPosition);
 }
int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  Transforms TransformManager;
  ReplacementHandling ReplacementHandler;

  TransformManager.registerTransforms();

  // Hide all options we don't define ourselves. Move pre-defined 'help',
  // 'help-list', and 'version' to our general category.
  llvm::StringMap<cl::Option*> Options;
  cl::getRegisteredOptions(Options);
  const cl::OptionCategory **CategoryEnd =
      VisibleCategories + llvm::array_lengthof(VisibleCategories);
  for (llvm::StringMap<cl::Option *>::iterator I = Options.begin(),
                                               E = Options.end();
       I != E; ++I) {
    if (I->first() == "help" || I->first() == "version" ||
        I->first() == "help-list")
      I->second->setCategory(GeneralCategory);
    else if (std::find(VisibleCategories, CategoryEnd, I->second->Category) ==
             CategoryEnd)
      I->second->setHiddenFlag(cl::ReallyHidden);
  }
  cl::SetVersionPrinter(&printVersion);

  // Parse options and generate compilations.
  std::unique_ptr<CompilationDatabase> Compilations(
      FixedCompilationDatabase::loadFromCommandLine(argc, argv));
  cl::ParseCommandLineOptions(argc, argv);

  // Populate the ModifiableFiles structure.
  GlobalOptions.ModifiableFiles.readListFromString(IncludePaths, ExcludePaths);
  GlobalOptions.ModifiableFiles.readListFromFile(IncludeFromFile,
                                                 ExcludeFromFile);

  if (!Compilations) {
    std::string ErrorMessage;
    Compilations.reset(autoDetectCompilations(ErrorMessage));
    if (!Compilations) {
      llvm::errs() << llvm::sys::path::filename(argv[0]) << ": " << ErrorMessage
                   << "\n";
      return 1;
    }
  }

  // Populate source files.
  std::vector<std::string> Sources;
  if (!SourcePaths.empty()) {
    // Use only files that are not explicitly excluded.
    std::remove_copy_if(SourcePaths.begin(), SourcePaths.end(),
                        std::back_inserter(Sources),
                        isFileExplicitlyExcludedPredicate);
  } else {
    if (GlobalOptions.ModifiableFiles.isIncludeListEmpty()) {
      llvm::errs() << llvm::sys::path::filename(argv[0])
                   << ": Use -include to indicate which files of "
                   << "the compilatiion database to transform.\n";
      return 1;
    }
    // Use source paths from the compilation database.
    // We only transform files that are explicitly included.
    Sources = Compilations->getAllFiles();
    std::vector<std::string>::iterator E = std::remove_if(
        Sources.begin(), Sources.end(), isFileNotIncludedPredicate);
    Sources.erase(E, Sources.end());
  }

  // check if line ranges are just applyed to single files
  if ( !LineRanges.empty() && Sources.size() > 1 ){
     llvm::errs() << "error: -line can only be used for single file.\n";
     return 1;
  }

  // add the line ranges to the sources 
  if ( !LineRanges.empty() ){
  }

  if (Sources.empty()) {
    llvm::errs() << llvm::sys::path::filename(argv[0])
                 << ": Could not determine sources to transform.\n";
    return 1;
  }

  // Enable timming.
  GlobalOptions.EnableTiming = TimingDirectoryName.getNumOccurrences() > 0;

  bool CmdSwitchError = false;
  CompilerVersions RequiredVersions =
      handleSupportedCompilers(argv[0], CmdSwitchError);
  if (CmdSwitchError)
    return 1;

  TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions);

  if (TransformManager.begin() == TransformManager.end()) {
    if (SupportedCompilers.empty())
      llvm::errs() << llvm::sys::path::filename(argv[0])
                   << ": no selected transforms\n";
    else
      llvm::errs() << llvm::sys::path::filename(argv[0])
                   << ": no transforms available for specified compilers\n";
    return 1;
  }

  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
      new DiagnosticOptions());
  DiagnosticsEngine Diagnostics(
      llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
      DiagOpts.getPtr());

  // FIXME: Make this DiagnosticsEngine available to all Transforms probably via
  // GlobalOptions.

  // If SerializeReplacements is requested, then code reformatting must be
  // turned off and only one transform should be requested.
  if (SerializeOnly &&
      (std::distance(TransformManager.begin(), TransformManager.end()) > 1 ||
       DoFormat)) {
    llvm::errs() << "Serialization of replacements requested for multiple "
                    "transforms.\nChanges from only one transform can be "
                    "serialized.\n";
    return 1;
  }

  // If we're asked to apply changes to files on disk, need to locate
  // clang-apply-replacements.
  if (!SerializeOnly) {
    if (!ReplacementHandler.findClangApplyReplacements(argv[0])) {
      llvm::errs() << "Could not find clang-apply-replacements\n";
      return 1;
    }

    if (DoFormat)
      ReplacementHandler.enableFormatting(FormatStyleOpt, FormatStyleConfig);
  }

  StringRef TempDestinationDir;
  if (SerializeLocation.getNumOccurrences() > 0)
    ReplacementHandler.setDestinationDir(SerializeLocation);
  else
    TempDestinationDir = ReplacementHandler.useTempDestinationDir();

  SourcePerfData PerfData;

  for (Transforms::const_iterator I = TransformManager.begin(),
                                  E = TransformManager.end();
       I != E; ++I) {
    Transform *T = *I;

    if (T->apply(*Compilations, Sources,LineRanges) != 0) {
      // FIXME: Improve ClangTool to not abort if just one file fails.
      return 1;
    }

    if (GlobalOptions.EnableTiming)
      collectSourcePerfData(*T, PerfData);

    if (SummaryMode) {
      llvm::outs() << "Transform: " << T->getName()
                   << " - Accepted: " << T->getAcceptedChanges();
      if (T->getChangesNotMade()) {
        llvm::outs() << " - Rejected: " << T->getRejectedChanges()
                     << " - Deferred: " << T->getDeferredChanges();
      }
      llvm::outs() << "\n";
    }

    if (!ReplacementHandler.serializeReplacements(T->getAllReplacements()))
      return 1;

    if (!SerializeOnly)
      if (!ReplacementHandler.applyReplacements())
        return 1;
  }

  // Let the user know which temporary directory the replacements got written
  // to.
  if (SerializeOnly && !TempDestinationDir.empty())
    llvm::errs() << "Replacements serialized to: " << TempDestinationDir << "\n";

  if (FinalSyntaxCheck) {
    ClangTool SyntaxTool(*Compilations, SourcePaths);
    if (SyntaxTool.run(newFrontendActionFactory<SyntaxOnlyAction>().get()) != 0)
      return 1;
  }

  // Report execution times.
  if (GlobalOptions.EnableTiming && !PerfData.empty()) {
    std::string DirectoryName = TimingDirectoryName;
    // Use default directory name.
    if (DirectoryName.empty())
      DirectoryName = "./migrate_perf";
    writePerfDataJSON(DirectoryName, PerfData);
  }

  return 0;
}