Skip to content

Instantly share code, notes, and snippets.

@itzurabhi
Last active June 22, 2020 08:43
Show Gist options
  • Select an option

  • Save itzurabhi/1c6e9dfdfefa78fc2f86cd768a9de2fa to your computer and use it in GitHub Desktop.

Select an option

Save itzurabhi/1c6e9dfdfefa78fc2f86cd768a9de2fa to your computer and use it in GitHub Desktop.

Revisions

  1. itzurabhi revised this gist Jun 22, 2020. 1 changed file with 19 additions and 0 deletions.
    19 changes: 19 additions & 0 deletions CMakeLists.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    set(LLVM_LINK_COMPONENTS
    Option
    Support
    )

    add_clang_tool(clang-ast-rewrite
    ClangASTRename.cpp
    )

    clang_target_link_libraries(clang-ast-rewrite
    PRIVATE
    clangBasic
    clangFrontend
    clangRewrite
    clangSerialization
    clangTooling
    clangToolingCore
    clangToolingRefactoring
    )
  2. itzurabhi created this gist Jun 22, 2020.
    123 changes: 123 additions & 0 deletions clang-ast-rewrite.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,123 @@
    #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 <string>
    #include <system_error>
    #include <memory>

    using namespace llvm;
    using namespace clang;

    static cl::OptionCategory
    ClangASTRenameOptions("clang-ast-rewrite common options");

    static cl::opt<std::string> Input("input", cl::desc("Input .ast file"),
    cl::Required, cl::cat(ClangASTRenameOptions));

    static cl::opt<std::string> Output("output", cl::desc("Output .ast file"),
    cl::Required,
    cl::cat(ClangASTRenameOptions));

    static cl::opt<std::string>
    FindPath("find", cl::desc("The path to be replaced with `replace` value"),
    cl::Required, cl::cat(ClangASTRenameOptions));

    static cl::opt<std::string>
    ReplacePath("replace", cl::desc("The path which will replace `find` value"),
    cl::Required, cl::cat(ClangASTRenameOptions));

    static cl::opt<bool> 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<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
    TextDiagnosticPrinter *DiagClient =
    new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
    ci.createDiagnostics(DiagClient,false);
    IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
    new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));

    auto to = std::make_shared<clang::TargetOptions>();
    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;
    }