2013-09-04 01:58:19 +08:00
|
|
|
//===-- ClangApplyReplacementsMain.cpp - Main file for the tool -----------===//
|
2013-08-22 21:07:14 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
///
|
|
|
|
/// \file
|
2013-09-04 01:58:19 +08:00
|
|
|
/// \brief This file provides the main function for the
|
|
|
|
/// clang-apply-replacements tool.
|
2013-08-22 21:07:14 +08:00
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-09-04 01:58:19 +08:00
|
|
|
#include "clang-apply-replacements/Tooling/ApplyReplacements.h"
|
2013-08-22 21:07:14 +08:00
|
|
|
#include "clang/Basic/Diagnostic.h"
|
|
|
|
#include "clang/Basic/DiagnosticOptions.h"
|
2013-08-22 21:40:32 +08:00
|
|
|
#include "clang/Basic/SourceManager.h"
|
2013-09-25 02:14:54 +08:00
|
|
|
#include "clang/Basic/Version.h"
|
2013-08-29 01:19:10 +08:00
|
|
|
#include "clang/Rewrite/Core/Rewriter.h"
|
2013-09-25 02:14:54 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/ADT/StringSet.h"
|
2013-08-22 21:07:14 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace clang;
|
|
|
|
using namespace clang::replace;
|
|
|
|
|
|
|
|
static cl::opt<std::string> Directory(cl::Positional, cl::Required,
|
|
|
|
cl::desc("<Search Root Directory>"));
|
|
|
|
|
2013-08-27 03:58:59 +08:00
|
|
|
static cl::opt<bool> RemoveTUReplacementFiles(
|
|
|
|
"remove-change-desc-files",
|
|
|
|
cl::desc("Remove the change description files regardless of successful\n"
|
|
|
|
"merging/replacing."),
|
|
|
|
cl::init(false));
|
|
|
|
|
2013-09-25 02:14:54 +08:00
|
|
|
// Update this list of options to show in -help as new options are added.
|
|
|
|
// Should add even those options marked as 'Hidden'. Any option not listed
|
|
|
|
// here will get marked 'ReallyHidden' so they don't appear in any -help text.
|
|
|
|
const char *OptionsToShow[] = { "help", "version", "remove-change-desc-files" };
|
|
|
|
|
2013-08-27 03:58:59 +08:00
|
|
|
// Helper object to remove the TUReplacement files (triggered by
|
|
|
|
// "remove-change-desc-files" command line option) when exiting current scope.
|
|
|
|
class ScopedFileRemover {
|
|
|
|
public:
|
|
|
|
ScopedFileRemover(const TUReplacementFiles &Files,
|
|
|
|
clang::DiagnosticsEngine &Diagnostics)
|
|
|
|
: TURFiles(Files), Diag(Diagnostics) {}
|
|
|
|
|
|
|
|
~ScopedFileRemover() {
|
|
|
|
deleteReplacementFiles(TURFiles, Diag);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const TUReplacementFiles &TURFiles;
|
|
|
|
clang::DiagnosticsEngine &Diag;
|
|
|
|
};
|
|
|
|
|
2013-09-25 02:14:54 +08:00
|
|
|
void printVersion() {
|
|
|
|
outs() << "clang-apply-replacements version " CLANG_VERSION_STRING << "\n";
|
|
|
|
}
|
|
|
|
|
2013-08-22 21:07:14 +08:00
|
|
|
int main(int argc, char **argv) {
|
2013-09-25 02:14:54 +08:00
|
|
|
// Only include our options in -help output.
|
|
|
|
StringMap<cl::Option*> OptMap;
|
|
|
|
cl::getRegisteredOptions(OptMap);
|
|
|
|
const char **EndOpts = OptionsToShow + array_lengthof(OptionsToShow);
|
|
|
|
for (StringMap<cl::Option *>::iterator I = OptMap.begin(), E = OptMap.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
if (std::find(OptionsToShow, EndOpts, I->getKey()) == EndOpts)
|
|
|
|
I->getValue()->setHiddenFlag(cl::ReallyHidden);
|
|
|
|
}
|
|
|
|
|
|
|
|
cl::SetVersionPrinter(&printVersion);
|
2013-08-22 21:07:14 +08:00
|
|
|
cl::ParseCommandLineOptions(argc, argv);
|
|
|
|
|
|
|
|
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
|
|
|
|
DiagnosticsEngine Diagnostics(
|
|
|
|
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
|
|
|
|
DiagOpts.getPtr());
|
|
|
|
|
|
|
|
TUReplacements TUs;
|
2013-08-27 03:58:59 +08:00
|
|
|
TUReplacementFiles TURFiles;
|
2013-08-22 21:07:14 +08:00
|
|
|
|
|
|
|
error_code ErrorCode =
|
2013-08-27 03:58:59 +08:00
|
|
|
collectReplacementsFromDirectory(Directory, TUs, TURFiles, Diagnostics);
|
2013-08-22 21:07:14 +08:00
|
|
|
|
|
|
|
if (ErrorCode) {
|
|
|
|
errs() << "Trouble iterating over directory '" << Directory
|
|
|
|
<< "': " << ErrorCode.message() << "\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-08-27 03:58:59 +08:00
|
|
|
// Remove the TUReplacementFiles (triggered by "remove-change-desc-files"
|
|
|
|
// command line option) when exiting main().
|
|
|
|
OwningPtr<ScopedFileRemover> Remover;
|
|
|
|
if (RemoveTUReplacementFiles)
|
|
|
|
Remover.reset(new ScopedFileRemover(TURFiles, Diagnostics));
|
|
|
|
|
2013-08-22 21:40:32 +08:00
|
|
|
FileManager Files((FileSystemOptions()));
|
|
|
|
SourceManager SM(Diagnostics, Files);
|
|
|
|
|
2013-08-22 21:07:14 +08:00
|
|
|
FileToReplacementsMap GroupedReplacements;
|
2013-08-22 21:40:32 +08:00
|
|
|
if (!mergeAndDeduplicate(TUs, GroupedReplacements, SM))
|
|
|
|
return 1;
|
|
|
|
|
2013-08-29 01:19:10 +08:00
|
|
|
Rewriter DestRewriter(SM, LangOptions());
|
|
|
|
if (!applyReplacements(GroupedReplacements, DestRewriter)) {
|
|
|
|
errs() << "Failed to apply all replacements. No changes made.\n";
|
2013-08-22 21:40:32 +08:00
|
|
|
return 1;
|
2013-08-29 01:19:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!writeFiles(DestRewriter))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
2013-08-22 21:07:14 +08:00
|
|
|
}
|