clang-tools  3.8.0
ClangRename.cpp
Go to the documentation of this file.
1 //===--- tools/extra/clang-rename/ClangRename.cpp - Clang rename tool -----===//
2 //
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
11 /// \brief This file implements a clang-rename tool that automatically finds and
12 /// renames symbols in C++ code.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "../USRFindingAction.h"
17 #include "../RenamingAction.h"
18 #include "clang/AST/ASTConsumer.h"
19 #include "clang/AST/ASTContext.h"
20 #include "clang/Basic/FileManager.h"
21 #include "clang/Basic/LangOptions.h"
22 #include "clang/Basic/TargetInfo.h"
23 #include "clang/Basic/TargetOptions.h"
24 #include "clang/Frontend/CommandLineSourceLoc.h"
25 #include "clang/Frontend/CompilerInstance.h"
26 #include "clang/Frontend/FrontendAction.h"
27 #include "clang/Frontend/TextDiagnosticPrinter.h"
28 #include "clang/Lex/Lexer.h"
29 #include "clang/Lex/Preprocessor.h"
30 #include "clang/Parse/ParseAST.h"
31 #include "clang/Parse/Parser.h"
32 #include "clang/Rewrite/Core/Rewriter.h"
33 #include "clang/Tooling/CommonOptionsParser.h"
34 #include "clang/Tooling/Refactoring.h"
35 #include "clang/Tooling/Tooling.h"
36 #include "llvm/ADT/IntrusiveRefCntPtr.h"
37 #include "llvm/Support/Host.h"
38 #include <ctype.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string>
42 #include <time.h>
43 #include <vector>
44 
45 using namespace llvm;
46 
47 cl::OptionCategory ClangRenameCategory("Clang-rename options");
48 
49 static cl::opt<std::string>
50 NewName(
51  "new-name",
52  cl::desc("The new name to change the symbol to."),
53  cl::cat(ClangRenameCategory));
54 static cl::opt<unsigned>
56  "offset",
57  cl::desc("Locates the symbol by offset as opposed to <line>:<column>."),
58  cl::cat(ClangRenameCategory));
59 static cl::opt<bool>
60 Inplace(
61  "i",
62  cl::desc("Overwrite edited <file>s."),
63  cl::cat(ClangRenameCategory));
64 static cl::opt<bool>
65 PrintName(
66  "pn",
67  cl::desc("Print the found symbol's name prior to renaming to stderr."),
68  cl::cat(ClangRenameCategory));
69 static cl::opt<bool>
71  "pl",
72  cl::desc("Print the locations affected by renaming to stderr."),
73  cl::cat(ClangRenameCategory));
74 
75 #define CLANG_RENAME_VERSION "0.0.1"
76 
77 static void PrintVersion() {
78  outs() << "clang-rename version " << CLANG_RENAME_VERSION << "\n";
79 }
80 
81 using namespace clang;
82 
83 const char RenameUsage[] = "A tool to rename symbols in C/C++ code.\n\
84 clang-rename renames every occurrence of a symbol found at <offset> in\n\
85 <source0>. If -i is specified, the edited files are overwritten to disk.\n\
86 Otherwise, the results are written to stdout.\n";
87 
88 int main(int argc, const char **argv) {
89  cl::SetVersionPrinter(PrintVersion);
90  tooling::CommonOptionsParser OP(argc, argv, ClangRenameCategory, RenameUsage);
91 
92  // Check the arguments for correctness.
93 
94  if (NewName.empty()) {
95  errs() << "clang-rename: no new name provided.\n\n";
96  cl::PrintHelpMessage();
97  exit(1);
98  }
99 
100  // Get the USRs.
101  auto Files = OP.getSourcePathList();
102  tooling::RefactoringTool Tool(OP.getCompilations(), Files);
104 
105  // Find the USRs.
106  Tool.run(tooling::newFrontendActionFactory(&USRAction).get());
107  const auto &USRs = USRAction.getUSRs();
108  const auto &PrevName = USRAction.getUSRSpelling();
109 
110  if (PrevName.empty())
111  // An error should have already been printed.
112  exit(1);
113 
114  if (PrintName)
115  errs() << "clang-rename: found name: " << PrevName;
116 
117  // Perform the renaming.
118  rename::RenamingAction RenameAction(NewName, PrevName, USRs,
119  Tool.getReplacements(), PrintLocations);
120  auto Factory = tooling::newFrontendActionFactory(&RenameAction);
121  int res;
122 
123  if (Inplace) {
124  res = Tool.runAndSave(Factory.get());
125  } else {
126  res = Tool.run(Factory.get());
127 
128  // Write every file to stdout. Right now we just barf the files without any
129  // indication of which files start where, other than that we print the files
130  // in the same order we see them.
131  LangOptions DefaultLangOptions;
132  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
133  new DiagnosticOptions();
134  TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
135  DiagnosticsEngine Diagnostics(
136  IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
137  &*DiagOpts, &DiagnosticPrinter, false);
138  auto &FileMgr = Tool.getFiles();
139  SourceManager Sources(Diagnostics, FileMgr);
140  Rewriter Rewrite(Sources, DefaultLangOptions);
141 
142  Tool.applyAllReplacements(Rewrite);
143  for (const auto &File : Files) {
144  const auto *Entry = FileMgr.getFile(File);
145  auto ID = Sources.translateFile(Entry);
146  Rewrite.getEditBuffer(ID).write(outs());
147  }
148  }
149 
150  exit(res);
151 }
static cl::opt< bool > PrintName("pn", cl::desc("Print the found symbol's name prior to renaming to stderr."), cl::cat(ClangRenameCategory))
HeaderHandle File
int main(int argc, const char **argv)
Definition: ClangRename.cpp:88
static cl::opt< bool > Inplace("i", cl::desc("Overwrite edited <file>s."), cl::cat(ClangRenameCategory))
Rewriter Rewrite
Definition: ClangTidy.cpp:173
static cl::opt< bool > PrintLocations("pl", cl::desc("Print the locations affected by renaming to stderr."), cl::cat(ClangRenameCategory))
#define CLANG_RENAME_VERSION
Definition: ClangRename.cpp:75
static cl::opt< std::string > NewName("new-name", cl::desc("The new name to change the symbol to."), cl::cat(ClangRenameCategory))
static cl::opt< unsigned > SymbolOffset("offset", cl::desc("Locates the symbol by offset as opposed to <line>:<column>."), cl::cat(ClangRenameCategory))
const char RenameUsage[]
Definition: ClangRename.cpp:83
static void PrintVersion()
Definition: ClangRename.cpp:77
IntrusiveRefCntPtr< DiagnosticOptions > DiagOpts
Definition: ClangTidy.cpp:169
FileManager Files
Definition: ClangTidy.cpp:167
cl::OptionCategory ClangRenameCategory("Clang-rename options")