blob: c714b221c62e20bcc3624fbfbc50549beca0689f [file] [log] [blame]
Edwin Vaneb225be22013-09-03 17:58:19 +00001//===-- ClangApplyReplacementsMain.cpp - Main file for the tool -----------===//
Edwin Vane3bf14ce2013-08-22 13:07:14 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
Edwin Vaneb225be22013-09-03 17:58:19 +000011/// \brief This file provides the main function for the
12/// clang-apply-replacements tool.
Edwin Vane3bf14ce2013-08-22 13:07:14 +000013///
14//===----------------------------------------------------------------------===//
15
Edwin Vaneb225be22013-09-03 17:58:19 +000016#include "clang-apply-replacements/Tooling/ApplyReplacements.h"
Edwin Vane3bf14ce2013-08-22 13:07:14 +000017#include "clang/Basic/Diagnostic.h"
18#include "clang/Basic/DiagnosticOptions.h"
Edwin Vane1106ef22013-08-22 13:40:32 +000019#include "clang/Basic/SourceManager.h"
Edwin Vane6d5350c2013-09-24 18:14:54 +000020#include "clang/Basic/Version.h"
Edwin Vanef18633c2013-08-28 17:19:10 +000021#include "clang/Rewrite/Core/Rewriter.h"
Edwin Vane6d5350c2013-09-24 18:14:54 +000022#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/StringSet.h"
Edwin Vane3bf14ce2013-08-22 13:07:14 +000024#include "llvm/Support/CommandLine.h"
25
26using namespace llvm;
27using namespace clang;
28using namespace clang::replace;
29
30static cl::opt<std::string> Directory(cl::Positional, cl::Required,
31 cl::desc("<Search Root Directory>"));
32
Tareq A. Siraj11755522013-08-26 19:58:59 +000033static cl::opt<bool> RemoveTUReplacementFiles(
34 "remove-change-desc-files",
35 cl::desc("Remove the change description files regardless of successful\n"
36 "merging/replacing."),
37 cl::init(false));
38
Edwin Vane6d5350c2013-09-24 18:14:54 +000039// Update this list of options to show in -help as new options are added.
40// Should add even those options marked as 'Hidden'. Any option not listed
41// here will get marked 'ReallyHidden' so they don't appear in any -help text.
42const char *OptionsToShow[] = { "help", "version", "remove-change-desc-files" };
43
Tareq A. Siraj11755522013-08-26 19:58:59 +000044// Helper object to remove the TUReplacement files (triggered by
45// "remove-change-desc-files" command line option) when exiting current scope.
46class ScopedFileRemover {
47public:
48 ScopedFileRemover(const TUReplacementFiles &Files,
49 clang::DiagnosticsEngine &Diagnostics)
50 : TURFiles(Files), Diag(Diagnostics) {}
51
52 ~ScopedFileRemover() {
53 deleteReplacementFiles(TURFiles, Diag);
54 }
55
56private:
57 const TUReplacementFiles &TURFiles;
58 clang::DiagnosticsEngine &Diag;
59};
60
Edwin Vane6d5350c2013-09-24 18:14:54 +000061void printVersion() {
62 outs() << "clang-apply-replacements version " CLANG_VERSION_STRING << "\n";
63}
64
Edwin Vane3bf14ce2013-08-22 13:07:14 +000065int main(int argc, char **argv) {
Edwin Vane6d5350c2013-09-24 18:14:54 +000066 // Only include our options in -help output.
67 StringMap<cl::Option*> OptMap;
68 cl::getRegisteredOptions(OptMap);
69 const char **EndOpts = OptionsToShow + array_lengthof(OptionsToShow);
70 for (StringMap<cl::Option *>::iterator I = OptMap.begin(), E = OptMap.end();
71 I != E; ++I) {
72 if (std::find(OptionsToShow, EndOpts, I->getKey()) == EndOpts)
73 I->getValue()->setHiddenFlag(cl::ReallyHidden);
74 }
75
76 cl::SetVersionPrinter(&printVersion);
Edwin Vane3bf14ce2013-08-22 13:07:14 +000077 cl::ParseCommandLineOptions(argc, argv);
78
79 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
80 DiagnosticsEngine Diagnostics(
81 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
82 DiagOpts.getPtr());
83
84 TUReplacements TUs;
Tareq A. Siraj11755522013-08-26 19:58:59 +000085 TUReplacementFiles TURFiles;
Edwin Vane3bf14ce2013-08-22 13:07:14 +000086
87 error_code ErrorCode =
Tareq A. Siraj11755522013-08-26 19:58:59 +000088 collectReplacementsFromDirectory(Directory, TUs, TURFiles, Diagnostics);
Edwin Vane3bf14ce2013-08-22 13:07:14 +000089
90 if (ErrorCode) {
91 errs() << "Trouble iterating over directory '" << Directory
92 << "': " << ErrorCode.message() << "\n";
93 return false;
94 }
95
Tareq A. Siraj11755522013-08-26 19:58:59 +000096 // Remove the TUReplacementFiles (triggered by "remove-change-desc-files"
97 // command line option) when exiting main().
98 OwningPtr<ScopedFileRemover> Remover;
99 if (RemoveTUReplacementFiles)
100 Remover.reset(new ScopedFileRemover(TURFiles, Diagnostics));
101
Edwin Vane1106ef22013-08-22 13:40:32 +0000102 FileManager Files((FileSystemOptions()));
103 SourceManager SM(Diagnostics, Files);
104
Edwin Vane3bf14ce2013-08-22 13:07:14 +0000105 FileToReplacementsMap GroupedReplacements;
Edwin Vane1106ef22013-08-22 13:40:32 +0000106 if (!mergeAndDeduplicate(TUs, GroupedReplacements, SM))
107 return 1;
108
Edwin Vanef18633c2013-08-28 17:19:10 +0000109 Rewriter DestRewriter(SM, LangOptions());
110 if (!applyReplacements(GroupedReplacements, DestRewriter)) {
111 errs() << "Failed to apply all replacements. No changes made.\n";
Edwin Vane1106ef22013-08-22 13:40:32 +0000112 return 1;
Edwin Vanef18633c2013-08-28 17:19:10 +0000113 }
114
115 if (!writeFiles(DestRewriter))
116 return 1;
117
118 return 0;
Edwin Vane3bf14ce2013-08-22 13:07:14 +0000119}