summaryrefslogtreecommitdiffstats
path: root/clang/tools
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-07-21 12:49:28 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-07-21 12:49:28 +0000
commita75b2cac718500b6b0d2bc59abc7ccbb1eeb0663 (patch)
tree467caac864825052c987965ddadba416031a5a40 /clang/tools
parent024e319489daa7fe28e0d639502f2f141fb5a146 (diff)
downloadbcm5719-llvm-a75b2cac718500b6b0d2bc59abc7ccbb1eeb0663.tar.gz
bcm5719-llvm-a75b2cac718500b6b0d2bc59abc7ccbb1eeb0663.zip
[clang-diff] Add initial implementation
This is the first commit for the "Clang-based C/C++ diff tool" GSoC project. ASTDiff is a new library that computes a structural AST diff between two ASTs using the gumtree algorithm. Clang-diff is a new Clang tool that will show the structural code changes between different ASTs. Patch by Johannes Altmanninger! Differential Revision: https://reviews.llvm.org/D34329 llvm-svn: 308731
Diffstat (limited to 'clang/tools')
-rw-r--r--clang/tools/CMakeLists.txt1
-rw-r--r--clang/tools/clang-diff/CMakeLists.txt13
-rw-r--r--clang/tools/clang-diff/ClangDiff.cpp110
3 files changed, 124 insertions, 0 deletions
diff --git a/clang/tools/CMakeLists.txt b/clang/tools/CMakeLists.txt
index 4976332b7db..17ad9f4a1a1 100644
--- a/clang/tools/CMakeLists.txt
+++ b/clang/tools/CMakeLists.txt
@@ -2,6 +2,7 @@ create_subdirectory_options(CLANG TOOL)
add_clang_subdirectory(diagtool)
add_clang_subdirectory(driver)
+add_clang_subdirectory(clang-diff)
add_clang_subdirectory(clang-format)
add_clang_subdirectory(clang-format-vs)
add_clang_subdirectory(clang-fuzzer)
diff --git a/clang/tools/clang-diff/CMakeLists.txt b/clang/tools/clang-diff/CMakeLists.txt
new file mode 100644
index 00000000000..cc696efb31a
--- /dev/null
+++ b/clang/tools/clang-diff/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(LLVM_LINK_COMPONENTS
+ Support
+ )
+
+add_clang_executable(clang-diff
+ ClangDiff.cpp
+ )
+
+target_link_libraries(clang-diff
+ clangFrontend
+ clangTooling
+ clangToolingASTDiff
+ )
diff --git a/clang/tools/clang-diff/ClangDiff.cpp b/clang/tools/clang-diff/ClangDiff.cpp
new file mode 100644
index 00000000000..0386de598aa
--- /dev/null
+++ b/clang/tools/clang-diff/ClangDiff.cpp
@@ -0,0 +1,110 @@
+//===- ClangDiff.cpp - compare source files by AST nodes ------*- C++ -*- -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a tool for syntax tree based comparison using
+// Tooling/ASTDiff.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/ASTDiff/ASTDiff.h"
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+using namespace clang;
+using namespace clang::tooling;
+
+static cl::OptionCategory ClangDiffCategory("clang-diff options");
+
+static cl::opt<bool>
+ DumpAST("ast-dump",
+ cl::desc("Print the internal representation of the AST as JSON."),
+ cl::init(false), cl::cat(ClangDiffCategory));
+
+static cl::opt<bool> NoCompilationDatabase(
+ "no-compilation-database",
+ cl::desc(
+ "Do not attempt to load build settings from a compilation database"),
+ cl::init(false), cl::cat(ClangDiffCategory));
+
+static cl::opt<std::string> SourcePath(cl::Positional, cl::desc("<source>"),
+ cl::Required,
+ cl::cat(ClangDiffCategory));
+
+static cl::opt<std::string> DestinationPath(cl::Positional,
+ cl::desc("<destination>"),
+ cl::Optional,
+ cl::cat(ClangDiffCategory));
+
+static std::unique_ptr<ASTUnit> getAST(const StringRef Filename) {
+ std::string ErrorMessage;
+ std::unique_ptr<CompilationDatabase> Compilations;
+ if (!NoCompilationDatabase)
+ Compilations =
+ CompilationDatabase::autoDetectFromSource(Filename, ErrorMessage);
+ if (!Compilations) {
+ if (!NoCompilationDatabase)
+ llvm::errs()
+ << "Error while trying to load a compilation database, running "
+ "without flags.\n"
+ << ErrorMessage;
+ Compilations = llvm::make_unique<clang::tooling::FixedCompilationDatabase>(
+ ".", std::vector<std::string>());
+ }
+ std::array<std::string, 1> Files = {{Filename}};
+ ClangTool Tool(*Compilations, Files);
+ std::vector<std::unique_ptr<ASTUnit>> ASTs;
+ Tool.buildASTs(ASTs);
+ if (ASTs.size() != Files.size())
+ return nullptr;
+ return std::move(ASTs[0]);
+}
+
+int main(int argc, const char **argv) {
+ cl::HideUnrelatedOptions(ClangDiffCategory);
+ if (!cl::ParseCommandLineOptions(argc, argv)) {
+ cl::PrintOptionValues();
+ return 1;
+ }
+
+ if (DumpAST) {
+ if (!DestinationPath.empty()) {
+ llvm::errs() << "Error: Please specify exactly one filename.\n";
+ return 1;
+ }
+ std::unique_ptr<ASTUnit> AST = getAST(SourcePath);
+ if (!AST)
+ return 1;
+ diff::SyntaxTree Tree(AST->getASTContext());
+ Tree.printAsJson(llvm::outs());
+ return 0;
+ }
+
+ if (DestinationPath.empty()) {
+ llvm::errs() << "Error: Exactly two paths are required.\n";
+ return 1;
+ }
+
+ std::unique_ptr<ASTUnit> Src = getAST(SourcePath);
+ std::unique_ptr<ASTUnit> Dst = getAST(DestinationPath);
+ if (!Src || !Dst)
+ return 1;
+
+ diff::ComparisonOptions Options;
+ diff::SyntaxTree SrcTree(Src->getASTContext());
+ diff::SyntaxTree DstTree(Dst->getASTContext());
+ diff::ASTDiff DiffTool(SrcTree, DstTree, Options);
+ for (const auto &Match : DiffTool.getMatches())
+ DiffTool.printMatch(llvm::outs(), Match);
+ for (const auto &Change : DiffTool.getChanges())
+ DiffTool.printChange(llvm::outs(), Change);
+
+ return 0;
+}
OpenPOWER on IntegriCloud