#include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TokenKinds.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Rewrite/Core/Rewriter.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Refactoring/Rename/RenamingAction.h" #include "clang/Tooling/Refactoring/Rename/USRFindingAction.h" #include "clang/Tooling/ReplacementsYaml.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/Process.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" #include #include #include using namespace llvm; using namespace clang; static cl::OptionCategory ClangASTRenameOptions("clang-ast-rewrite common options"); static cl::opt Input("input", cl::desc("Input .ast file"), cl::Required, cl::cat(ClangASTRenameOptions)); static cl::opt Output("output", cl::desc("Output .ast file"), cl::Required, cl::cat(ClangASTRenameOptions)); static cl::opt FindPath("find", cl::desc("The path to be replaced with `replace` value"), cl::Required, cl::cat(ClangASTRenameOptions)); static cl::opt ReplacePath("replace", cl::desc("The path which will replace `find` value"), cl::Required, cl::cat(ClangASTRenameOptions)); static cl::opt Help("h", cl::desc("Alias for -help"), cl::Hidden); int main(int argc, const char **argv) { llvm::InitLLVM X(argc, argv); cl::HideUnrelatedOptions(ClangASTRenameOptions); cl::ParseCommandLineOptions( argc, argv, "A tool to modify the absolute path(s) inside a .ast file"); if (Help) { cl::PrintHelpMessage(); return 0; } // remove leading and trailing spaces StringRef refInput(Input); refInput = refInput.ltrim().rtrim(); StringRef refOutput(Output); refOutput = refOutput.ltrim().rtrim(); StringRef refFindPath(FindPath); refFindPath = refFindPath.ltrim().rtrim(); StringRef refReplacePath(ReplacePath); refReplacePath = refReplacePath.ltrim().rtrim(); // check the sanity of arguments if (refInput.empty()) { errs() << "clang-ast-rename: valid --input must be specified.\n\n"; return 1; } if (refOutput.empty()) { errs() << "clang-ast-rename: valid --output must be specified.\n\n"; return 1; } if (refFindPath.empty()) { errs() << "clang-ast-rename: valid --find must be specified.\n\n"; return 1; } if (refReplacePath.empty()) { errs() << "clang-ast-rename: valid --replace must be specified.\n\n"; return 1; } CompilerInstance ci; IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); ci.createDiagnostics(DiagClient,false); IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); IntrusiveRefCntPtr Diags( new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient)); auto to = std::make_shared(); to->Triple = llvm::sys::getDefaultTargetTriple(); TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to); ci.setTarget(pti); auto FileMan = ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(TranslationUnitKind::TU_Complete); auto AU = ASTUnit::LoadFromASTFile( std::string(refInput.str()), ci.getPCHContainerOperations()->getRawReader(), ASTUnit::LoadEverything, Diags, ci.getFileSystemOpts()); return 0; }