[clang-diff] Add commandline arguments.

Summary:
Support command line options for build path and extra arguments
This emulates the options accepted by clang tools that use CommonOptionsParser.

Add a flag for controlling the maximum size parameter for bottom up matching.

Reviewers: arphaman

Subscribers: klimek

Differential Revision: https://reviews.llvm.org/D36177

llvm-svn: 311173
This commit is contained in:
Johannes Altmanninger 2017-08-18 16:34:22 +00:00
parent fa524d7b24
commit 849f20e4a2
3 changed files with 65 additions and 22 deletions

View File

@ -0,0 +1,8 @@
RUN: echo a > %t.cpp
CHECK: unknown type name 'X'
check adding compiler cflags
RUN: clang-diff -ast-dump -extra-arg=-Da=X %t.cpp -- 2>&1 | FileCheck %s
RUN: clang-diff -ast-dump -extra-arg-before=-Da=X %t.cpp -- 2>&1 | FileCheck %s
RUN: clang-diff -ast-dump %t.cpp -- 2>&1 -Da=X | FileCheck %s

View File

@ -1,7 +1,6 @@
// RUN: mkdir -p %t
// RUN: %clang_cc1 -E %s > %t/src.cpp
// RUN: %clang_cc1 -E %s > %t/dst.cpp -DDEST
// RUN: clang-diff -no-compilation-database %t/src.cpp %t/dst.cpp | FileCheck %s
// RUN: %clang_cc1 -E %s > %t.src.cpp
// RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST
// RUN: clang-diff %t.src.cpp %t.dst.cpp -- | FileCheck %s
#ifndef DEST
namespace src {

View File

@ -28,12 +28,6 @@ static cl::opt<bool>
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));
@ -43,23 +37,56 @@ static cl::opt<std::string> DestinationPath(cl::Positional,
cl::Optional,
cl::cat(ClangDiffCategory));
static std::unique_ptr<ASTUnit> getAST(const StringRef Filename) {
static cl::opt<int> MaxSize("s", cl::desc("<maxsize>"), cl::Optional,
cl::init(-1), cl::cat(ClangDiffCategory));
static cl::opt<std::string> BuildPath("p", cl::desc("Build path"), cl::init(""),
cl::Optional, cl::cat(ClangDiffCategory));
static cl::list<std::string> ArgsAfter(
"extra-arg",
cl::desc("Additional argument to append to the compiler command line"),
cl::cat(ClangDiffCategory));
static cl::list<std::string> ArgsBefore(
"extra-arg-before",
cl::desc("Additional argument to prepend to the compiler command line"),
cl::cat(ClangDiffCategory));
static void addExtraArgs(std::unique_ptr<CompilationDatabase> &Compilations) {
if (!Compilations)
return;
auto AdjustingCompilations =
llvm::make_unique<ArgumentsAdjustingCompilations>(
std::move(Compilations));
AdjustingCompilations->appendArgumentsAdjuster(
getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN));
AdjustingCompilations->appendArgumentsAdjuster(
getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END));
Compilations = std::move(AdjustingCompilations);
}
static std::unique_ptr<ASTUnit>
getAST(const std::unique_ptr<CompilationDatabase> &CommonCompilations,
const StringRef Filename) {
std::string ErrorMessage;
std::unique_ptr<CompilationDatabase> Compilations;
if (!NoCompilationDatabase)
Compilations =
CompilationDatabase::autoDetectFromSource(Filename, ErrorMessage);
if (!Compilations) {
if (!NoCompilationDatabase)
if (!CommonCompilations) {
Compilations = CompilationDatabase::autoDetectFromSource(
BuildPath.empty() ? Filename : BuildPath, ErrorMessage);
if (!Compilations) {
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>());
Compilations =
llvm::make_unique<clang::tooling::FixedCompilationDatabase>(
".", std::vector<std::string>());
}
}
addExtraArgs(Compilations);
std::array<std::string, 1> Files = {{Filename}};
ClangTool Tool(*Compilations, Files);
ClangTool Tool(Compilations ? *Compilations : *CommonCompilations, Files);
std::vector<std::unique_ptr<ASTUnit>> ASTs;
Tool.buildASTs(ASTs);
if (ASTs.size() != Files.size())
@ -68,18 +95,25 @@ static std::unique_ptr<ASTUnit> getAST(const StringRef Filename) {
}
int main(int argc, const char **argv) {
std::string ErrorMessage;
std::unique_ptr<CompilationDatabase> CommonCompilations =
FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage);
if (!CommonCompilations && !ErrorMessage.empty())
llvm::errs() << ErrorMessage;
cl::HideUnrelatedOptions(ClangDiffCategory);
if (!cl::ParseCommandLineOptions(argc, argv)) {
cl::PrintOptionValues();
return 1;
}
addExtraArgs(CommonCompilations);
if (ASTDump) {
if (!DestinationPath.empty()) {
llvm::errs() << "Error: Please specify exactly one filename.\n";
return 1;
}
std::unique_ptr<ASTUnit> AST = getAST(SourcePath);
std::unique_ptr<ASTUnit> AST = getAST(CommonCompilations, SourcePath);
if (!AST)
return 1;
diff::SyntaxTree Tree(AST->getASTContext());
@ -92,12 +126,14 @@ int main(int argc, const char **argv) {
return 1;
}
std::unique_ptr<ASTUnit> Src = getAST(SourcePath);
std::unique_ptr<ASTUnit> Dst = getAST(DestinationPath);
std::unique_ptr<ASTUnit> Src = getAST(CommonCompilations, SourcePath);
std::unique_ptr<ASTUnit> Dst = getAST(CommonCompilations, DestinationPath);
if (!Src || !Dst)
return 1;
diff::ComparisonOptions Options;
if (MaxSize != -1)
Options.MaxSize = MaxSize;
diff::SyntaxTree SrcTree(Src->getASTContext());
diff::SyntaxTree DstTree(Dst->getASTContext());
diff::ASTDiff DiffTool(SrcTree, DstTree, Options);